java collections framework -----List对象的实现

本文详细对比了Java中ArrayList与LinkedList两种数据结构的特点及适用场景。分析了它们在存取、增删操作上的性能差异,帮助开发者根据具体需求选择合适的数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在jdk中对于List对象提供了ArrayList以及LinkedList实现类。

ArrayList对象采用的是数组方式存储数据。LinkedList采用的是链表的存储方式。

在sun官方提供的文档中说明:用户如果不需要频繁的存移(存放,移除)数据,可以采用ArrayList实现,如果频繁的存移(存放,移除)数据,采用LinkedList是一个比较好的选择。原文如下:

 

 There are two general-purpose List implementations in the Collections Framework:
ArrayList and LinkedList. Which of the two List implementations you use depends on
your specific needs. If you need to support random access, without inserting or removing
elements from any place other than the end, then ArrayList offers the optimal collection.
If, however, you need to frequently add and remove elements from the middle of the list and
only access the list elements sequentially, then LinkedList offers the better
implementation.

 

    实际也很好理解,因为采用ArrayList方式的时候,数据采用数据对象存放,我们都明白数组对象的存取都非常快速,但有一个非常大的弱点就是需要在申明数组的时候确定数组的长度,分配过大浪费空间,如果申明长度太小,又会出现“溢出”。ArrayList为了解决这个问题,就在添加数组长度的时候判断数组是否还有空间存放数据,如果数组已满,无法再存放数据时,将会重新申明一个新的数组,将旧的数组数据添加进新的数组,并销毁旧数组。同样的道理,在移除数据时,又需要将后当前数据后面的数据前移。

 

    如果用户需要频繁的,那么将花费大量的性能在存放数据是开辟新的数组空间,在移除数据是,又需要将后面的数据向前移动位置。

 

    所以需要频繁存放,移除数据时,不宜采用ArrayList方式实现,而应该采用LinkedList方式实现,当然LinkedList方式也并不完美。LinkedList虽然在存放,移除数据时具有先天的优势,但是在查询时相对ArrayList对象较慢。

 

    因为通过LinkedList方式查询数据是,是通过链表一步一步的遍历到节点而获取数据。假如一个集合数据A的长度为10,需要查询其第5个数据,采用ArrayList方式,只需要去获取数组下标为4的数据就行,而采用LinkedList方式,就需要找到头节点,获取头节点的后继,再获取后继的后继.......直到获取到查询的数据。一目了然,ArrayList与LinkedList在查询中的差异。

 

在jdk中,初始化对象是,实际上是申请了一个长度为10的数组对象。这是ArrayList对象的默认长度。

    public ArrayList(int initialCapacity) {
    super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
    this.elementData = new Object[initialCapacity];
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
    this(10);        //在我们调用List list= new ArrayList()时,ArrayList在elementData数组长度分配10个空间存储数据。
    }

当插入数据时,ArrayList会优先检查一下是否还有存储空间,如果没有就需要申明新的数组空间。相应的代码如下。

    public boolean add(E e) {
    ensureCapacity(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
    }

    public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
            if (newCapacity < minCapacity)
        newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);//将旧的数组数据存放到新数组中。
    }
    }

   移除数据时,ArrayList对象将当前数组后的数据覆盖到当前数下标中,以此类推,直到最后一个数组下标,将其设置为null,size长度减一。

     而采用Linked方式存放数据时,只需要初始化一个新的节点,将当前节点的后继执行新的节点,新的节点的前驱执行当前节点,并且将新的节点指定为当前节点,size长度加1就行。移除同理。

 

     当然LinkedList作为链表,插入数据是可以在头节点插入,也可以在尾节点插入,删除数据的时候也提供了删除头节点和删除尾节点的方法。

   LinkedList link = new LinkedList();

   list.addFirst(0);

   list.addLast(0);

   list.removeFirst();

   list.removeLast();

合理的运行LinkedList提供的方法,可以将它变形为栈和队列的链式存储结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值