Java集合框架ArrayList的创建原理

来源:互联网 发布:家用投影仪知乎 编辑:程序博客网 时间:2024/05/16 04:28

以ArrayList为例,分析它的创建过程,分析JVM怎么分配它的内存,从而分析Arraylist里面的数组对象判断是否相等的原理。

分析ArrayList创建过程(代码在后面)

  • 创建ArrayList对象,对象名称为userList,因为ArrayLIst类是泛型类,传入的对象参数为User。
  • 查看ArrayList代码可知,里面有一个空的静态数组对象 实例变量。
    /**     * Default initial capacity.     */    private static final int DEFAULT_CAPACITY = 10;    /**     * Shared empty array instance used for empty instances.     */    private static final Object[] EMPTY_ELEMENTDATA = {};    /**     * Shared empty array instance used for default sized empty instances. We     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when     * first element is added.     */    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};    /**     * The array buffer into which the elements of the ArrayList are stored.     * The capacity of the ArrayList is the length of this array buffer. Any     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA     * will be expanded to DEFAULT_CAPACITY when the first element is added.     */    transient Object[] elementData; // non-private to simplify nested class access
  • 当执行List userList = new ArrayList<>(); 方法时,userList作为对象的引用变量存储在虚拟机栈 中,在堆中建立一个空的数组
  • User user1 = new User(“cjm”, “1”),userList.add(user1);执行代码,首先创建user1对象,对象的实例数据的内存堆中,user1作为实例引用存储在虚拟机栈中,而userList.add(user1),执行的操作是,user1作为虚拟机栈地址存储在数组的静态内存空间中 ,有连续的内存和下标。这个时候数组的长度为10。user1存储的位置为第一个。
  • 同理再一次添加一个对象。userList.add(new User(“qj”,”2”)); 保存对象的引用地址在数组的第二个位置。
  • .新建第二个userList1对象。注意,其中user1对象是同一个对象。但是在userList和userList1中,user1存储在数组中的地址是不一样的。
  • . 现在在执行removeAll方法,分析源码知,在Arraylist中判断数组存储的对象是否相等,使用的是equal。举例user1,比较就是创建user1这个对象时,存储在内存堆的数据。所以user1是相等的。
    public int indexOf(Object o) {        if (o == null) {            for (int i = 0; i < size; i++)                if (elementData[i]==null)                    return i;        } else {            for (int i = 0; i < size; i++)                if (o.equals(elementData[i]))                    return i;        }        return -1;    }

结论:
  在执行ArrayList的removeAll方法,判断它的成员变量是否相等,判断的是成员变量对象在内存堆中的值是否相等。
  ArrayList中静态数组存储的都是实例变量对象的引用地址。

示例代码

public class User {    private String name;    private String orgId;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getOrgId() {        return orgId;    }    public void setOrgId(String orgId) {        this.orgId = orgId;    }    public User(String name, String orgId) {        this.name = name;        this.orgId = orgId;    }}
public class CollectionTest {    public static void main(String[] args) {        List<User> userList = new ArrayList<>();        userList.add(new User("qj","2"));        User user1 = new User("cjm", "1");        userList.add(user1);        userList.add(new User("zlz","3"));        List<User> userList1 = new ArrayList<>();        userList1.add(new User("zzq","4"));        userList1.add(user1);        boolean a = userList.removeAll(userList1);        System.out.println(a);        print(userList);    }    private static void print(List<User> userList){        for (User user : userList){            System.out.println(user.getName());        }    }}
原创粉丝点击