Collection-ArrayList-Transient及序列化

现在开始补课,补Java基础知识(这些应该是早就会的,现在才开始系统的学,但也没关系吧,争取6个月能够深入了解)。

首先看集合,引一个图

java collection


先从ArrayList看起,类定义开始是

private transient Object[] elementData;

transient不懂。看了一下是短期存在內存的不能持久化的变量,序列化的时候会跳过transient的变量。如密码等。上例的elementData为什么声明为transient?是由于elementData有预留,不是整个数组都有数,通过writeObject将有数的部分持久化,elementData不进行持久化。


transient的使用说明:

1.一旦变量被transient修饰,变量将不再是持久化的一部分,该变量在序列化后无法显示(如上描述)。

2.静态变量不管是否被transient修饰,都不被序列化。


序列化:如果需要序列化只需要实现Serializable接口。然后可以用ObjectOutputStream将该对象保存或发送给其他主机。所有的non-transient和non-static字段都将被序列化,并且由反序列化构造出一模一样的对象。readObject和writeObject是自定义序列化方法,如果用户定义了自己的readObject和writeObject,虚拟机会使用自定的持久化方法,如果没有就调用ObjectOutputStream里的defaultWriteObjectObjectInputStream里的defaultReadObject

ArrayList的readObject和writeObject实现:

    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in array length and allocate array
        int arrayLength = s.readInt();
        Object[] a = elementData = new Object[arrayLength];

        // Read in all elements in the proper order.
        for (int i=0; i<size; i++)
            a[i] = s.readObject();
    }


private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException{
    // Write out element count, and any hidden stuff
    int expectedModCount = modCount;
    s.defaultWriteObject();

    // Write out array length
    s.writeInt(elementData.length);

    // Write out all elements in the proper order.
    for (int i=0; i<size; i++)
        s.writeObject(elementData[i]);

    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }

}

调用方法
List<Integer> list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
try {
    ObjectOutputStream os = new ObjectOutputStream(
            new FileOutputStream("C:/a.txt"));
    os.writeObject(list); // 将User对象写进文件
    os.flush();
    os.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

try {
    ObjectInputStream is = new ObjectInputStream(new FileInputStream(
            "C:/a.txt"));
    List<Integer> ls = (ArrayList) is.readObject(); // 从流中读取User的数据
    is.close();

    System.out.println("\nread after Serializable: ");
    System.out.println("1: " + ls.get(0));
    System.out.println("2: " + ls.get(1));
    System.out.println("3: " + ls.get(2));


} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}


todo:  后续了解kryo序列化实现



ArrayList允许插入空,也允许重复。

所以在很多操作的时候要注意可能为null,如remove操作,先对null做判断,否则调用null的equals报空指针异常:

public boolean remove(Object o) {
    if (o == null) {
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                fastRemove(index);
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值