Java集合框架ArrayList的创建原理

以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());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值