java语言基础--集合学习,arraylist和linkedlist

记录点点滴滴      2022-04-16     494

关键词:

Collection<E>接口

  这个接口是集合框架最顶级的接口,该接口扩展了Iterable接口,这意味着所有的集合类fore-each风格进行遍历。

ArrayList 与 Linkedlist

区别:

  ArrayList是实现了基于动态数组,LinkedList基于链表。对于随机访问get和set,ArrayList性能要优于LinkedList,因为LinkedList要移动指针。对于删除和新增LinkedList性能要优于ArrayList,因为ArrayList要移动数据。 

ArrayList的扩容方式,扩容时机

  当集合中的元素超出容量,便会进行扩容操作。扩容操作也是ArrayList 的一个性能消耗比较大的地方,所以若我们可以提前预知数据的规模,应该通过public ArrayList(int initialCapacity) {}构造方法,指定集合的大小,去构建ArrayList实例,以减少扩容次数,提高效率

ArrayList的成员属性

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
    private static final long serialVersionUID = 8683452581122892189L;
    //默认初始容量
    private static final int DEFAULT_CAPACITY = 10;
    //默认构造函数的空数组
    private static final Object[] EMPTY_ELEMENTDATA = {};
    //瞬态(在采用Java默认的序列化机制的时候,被该关键字修饰的属性不会被序列化)的数组,真正存放元素的数组
    transient Object[] elementData; // non-private to simplify nested class access
    //elementData存放元素的数量,这里和容量不一样
    private int size;
}

 ArrayList的构造方法

    public ArrayList(int initialCapacity) {
        super();//即父类protected AbstractList() {}
        if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
        this.elementData = new Object[initialCapacity];//创建一个容量为initialCapacity的空的(但是size==0)对象数组
    }

    public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;//将空数组赋值给elementData
    }

    public ArrayList(Collection<? extends E> c) {
        //调用Collection.toArray()方法得到一个对象数组,并赋值给elementData
        elementData = c.toArray();
        //设置size的值
        size = elementData.length;
        //c.toArray()如果没有返回Object[]时,利用Arrays.copyOf 来复制集合c中的元素到elementData数组中
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    }

add方法

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;//将数组元素追加到末尾,并修改size
        return true;
    }
    
    private void ensureCapacityInternal(int minCapacity) {
        //根据EMPTY_ELEMENTDATA  判断数组是否是用默认构造函数初始化的,(这里不考虑ArrayList(Collection<? extends E> c)这种情况是因为,minCapacity是肯定大于c的size的)
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }
    
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;///如果确定要扩容,会修改modCount 
        
        // 如果传入的数大于数组原容量 则开始扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    
    private void grow(int minCapacity) {
        //
        int oldCapacity = elementData.length;
        //扩容为原来的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //取1.5倍的容量和传入的扩容系数的最大值
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)//这里的 MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    //最大返回 Integer.MAX_VALUE
    private static int hugeCapacity(int minCapacity) {
        // overflow
        if (minCapacity < 0) throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
    }

指定位置插入add(int index, E element)

    public void add(int index, E element) {
        rangeCheckForAdd(index);//范围检查

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //将index开始的数据 向后移动一位
        System.arraycopy(elementData, index, elementData, index + 1,size - index);
        elementData[index] = element;
        size++;
    }
    
    private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

addAl方法

    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        //扩容准备
        ensureCapacityInternal(size + numNew);  
        // 复制数组 ,并载入数据
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }

查询

    public E get(int index) {
        rangeCheck(index);//范围检查

        return elementData(index);//下标获取数据
    }    

    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }

 Linkedlist

    transient int size = 0;//集合元素数量

    transient Node<E> first; //头部节点

    transient Node<E> last;//尾部节点

构造方法

   public LinkedList() {}

    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);//将集合c所有元素插入链表中
    }

内部类 Node

  //双向链表
  private static class Node<E> {
        E item;//元素值
        Node<E> next;//前节点引用
        Node<E> prev; //后节点引用

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

add方法

    //尾部插入新节点
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    
    void linkLast(E e) {
        final Node<E> l = last;//记录原来的尾部节点
        final Node<E> newNode = new Node<>(l, e, null);//以原尾部节点为前节点生成新节点
        last = newNode;//将当期节点设置为尾部节点
        if (l == null)//如果原尾部节点为null  则将当前节点设置为链表的首节点
            first = newNode;
        else//否则将当前节点设置为原尾部节点的后节点
            l.next = newNode;
        size++;
        modCount++;
    }

其他例子就不看了,总得来说 LinkedList  修改数据时,只需要设置新节点和关联前后节点关系即可,不向ArrayList那样,增加一个数据。后面的数据都要后移。因此LinkedList 对数据操作效率高。

 

java集合系列:arraylist详细介绍(源码解析)和使用示例

...Collection的具体实现类进行讲解;首先,讲解List,而List中ArrayList又最为常用。因此,本章我们讲解ArrayList。先对ArrayList有个整体认识,再学习它的源码,最后再通过例子来学习如何使用它。第1部分ArrayList介绍ArrayList简介ArrayList... 查看详情

java集合系列03之arraylist详细介绍(源码解析)和使用示例

...Collection的具体实现类进行讲解;首先,讲解List,而List中ArrayList又最为常用。因此,本章我们讲解ArrayList。先对ArrayList有个整体认识,再学习它的源码,最后再通过例子来学习如何使用它。内容包括:第1部分ArrayList简介第2部分A... 查看详情

java小白集合源码的学习系列:arraylist

目录ArrayList源码学习ArrayList的继承体系ArrayList核心源码ArrayList扩容机制最后的总结ArrayList源码学习本文基于JDK1.8版本,对集合中的巨头ArrayList做一定的源码学习,将会参考大量资料,在文章后面都将会给出参考文章链接,本文用... 查看详情

java小白集合源码的学习系列:arraylist

目录ArrayList源码学习ArrayList的继承体系ArrayList核心源码ArrayList扩容机制最后的总结ArrayList源码学习本文基于JDK1.8版本,对集合中的巨头ArrayList做一定的源码学习,将会参考大量资料,在文章后面都将会给出参考文章链接,本文用... 查看详情

我的c/c++语言学习进阶之旅jni开发之java传递实体bean到c++层,实体bean包含intfloat等基本类型和数组arraylist集合等

一、需求描述最近有个需求,Java上层包装一系列的数据到一个实体bean,实体Bean包含int、float等基本类型和数组array、List集合等,然后通过JNI传递给C++层来进行数据处理,这边折腾了一番终于搞定,这里... 查看详情

java基础知识之什么是集合框架(代码片段)

...了很多接口,比如Set、List、Queue、Deque、…,实现类的有ArrayList、Vector、LinkedList、PriorityQueue、HashSet、LinkedHashSet、TreeSet、…,这些实现类都是数据架构和算法的应用,比如链表、红黑树、二叉树等等,集合框架的类可以在java.uti... 查看详情

2019-05-25java学习日记之list集合

去除ArrayList中重复字符串元素方式:需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)去除ArrayList中重复自定义对象元素:需求:ArrayList去除自定义对象元素的重复值(对象的成员变量值相同)注意事项:重写equals... 查看详情

java集合学习笔记:arraylist(代码片段)

Java集合学习笔记:ArrayList简介UML常用方法增删改查迭代内部类静态内部类自动扩容逻辑Java7Java8扩容-核心代码移除-核心代码使用建议参考资料简介ArrayList是List接口的大小可变数组的实现。实现了所有可选列表操作,并允... 查看详情

java集合学习笔记:arraylist(代码片段)

Java集合学习笔记:ArrayList简介UML常用方法增删改查迭代内部类静态内部类自动扩容逻辑Java7Java8扩容-核心代码移除-核心代码使用建议参考资料简介ArrayList是List接口的大小可变数组的实现。实现了所有可选列表操作,并允... 查看详情

java集合---arraylist源码

...供本人学习参考使用,如有侵权立即删除。 一、 ArrayList概述:  ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。  &nbs 查看详情

java学习笔记--类arraylist和linkedlist的实现

...集合Collection下的List中有两个实现使用的很频繁,一个是ArrayList,另一个是LinkedList,在学习中肯定都会有这样的疑问:什么时候适合使用ArrayList,什么时候用LinkedList?这时,我们就需要了解ArrayList和LinkedList的底层的实现,下面,为... 查看详情

我的c/c++语言学习进阶之旅jni开发之java传递实体bean到c++层,实体bean包含intfloat等基本类型和数组arraylist集合等(代码片段)

一、需求描述最近有个需求,Java上层包装一系列的数据到一个实体bean,实体Bean包含int、float等基本类型和数组array、List集合等,然后通过JNI传递给C++层来进行数据处理,这边折腾了一番终于搞定,这里... 查看详情

java基础——集合——arraylist

ArrayList集合ArrayList的一些方法(JDK1.8):将指定的元素附加到列表的末尾,true:添加成功,false:添加失败:publicboolean add(Ee)  在指定的位置插入指定的元素列表。改变当前位置的元素(如果有的话)右边的所有元素往... 查看详情

java集合collection体系集合详解(arraylist,linkedlist,hashset,treeset...)(代码片段)

...集合的体系结构4.Collection父接口5.List子接口6.List实现类6.1ArrayList类6.2Vector类6.3LinkedList类6.4ArrayList和LinkedList的区别7.Set子接口8.Set实现类8.1HashSet类8.2TreeSet类9.Collections工具类Java编程基础教程系列1.概念集合是对象的容器,定义... 查看详情

java集合之arraylist链表基础

ArrayList可变数组:arrayList继承AbstractList抽象类,实现list接口,底层基于数组实现。可存放null,除了非同步的之外,大致等同Vector。适用快速访问,复制、序列化。构造函数:ArrayList()默认初始容量为10ArrayList(intinitialCapacity)指定... 查看详情

java集合:arraylist

集合是Java中非常重要而且基础的内容,因为任何数据必不可少的就是该数据是如何存储的,集合的作用就是以一定的方式组织、存储数据。这里写的集合,一部分是比较常见的、一部分是不常用但是我个人平时见到过的,一些... 查看详情

80道最新java基础部分面试题

...需要更多资料的可以私信我哦,大家一起学习进步!59、ArrayList和Vector的区别答:这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动... 查看详情

java集合系列05之linkedlist详细介绍(源码解析)和使用示例

概要 前面,我们已经学习了ArrayList,并了解了fail-fast机制。这一章我们接着学习List的实现类——LinkedList。和学习ArrayList一样,接下来呢,我们先对LinkedList有个整体认识,然后再学习它的源码;最后再通过实例来学会... 查看详情