浅析Java中的List接口和实现类

168 阅读3分钟

文章目录


1. List接口

List属于单列集合,常用来替换数组使用。集合类中元素有序且可重复,每个元素都有其对应的顺序索引,可以根据指定的索引在集合中存取元素。List接口常用的实现类有:

  • ArrayList
  • LinkedList
  • Vector

2. ArrayList

Class ArrayList<E>中E表示泛型,泛型指的是集合中的所有元素的类型,而且泛型只能是引用类型,不能是基本类型。

有关泛型的定义和使用可阅读 :java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

ArrayList是一个其容量能够动态增长的动态数组,但又和数组不一样,它继承了AbstractList,实现了List、RandomAccess, Cloneable, java.io.Serializable。

  • K1.7:饿汉式,直接创建一个初始容量为10的数组
  • JDK1.8:懒汉式,一开始创建个长度为0的数组,当添加第一个元素时再创建一个初始容量为10的数组

常用方法:

  • boolean add(E e):向集合中添加元素,参数类型和泛型一致
  • boolean addAll(int index, Collection eles):从index开始的位置将eles中所有的元素加入到集合中
  • E get(int index):从集合中获取元素,参数是索引编号,返回值就是对应位置元素
  • E remove(int index):从集合中删除元素,参数是索引编号,返回值就是要被删掉的元素
  • int size():获取集合的尺寸长度,返回值是集合中包含的元素个数
  • void clear():移除list中的所有元素
  • boolean isEmpty():判断list是否为空
  • boolean contains():判断元素是否存在
  • object [] toArray():将集合转换为数组形式
  • void sort(Comparator<? super E> c):按执行的规则进行排列
  • int indexOf(Object obj):obj在集合中首次出现的索引位置
  • int lastIndexOf(Object obj):obj在集合中最后出现的索引位置
  • List subList(int fromIndex, int toIndex):返回指定区间的子集合

测试代码:

public class ListDemo {

    @Test
    public void test() {
        List<Integer> list = new ArrayList<>();

        list.add(31);
        list.add(2);
        Collections.addAll(list, 23, 23);
        list.add(0, 10);
        System.out.println(list);
        System.out.println(Arrays.toString(list.toArray()));
        System.out.println("-------------");

        System.out.println(list.isEmpty());
        System.out.println(list.size());
        System.out.println("-------------");

        System.out.println(list.indexOf(23));
        System.out.println(list.lastIndexOf(23));
        System.out.println("-------------");

        System.out.println(list.subList(0, 2));
        System.out.println("-------------");

        System.out.println(list.contains(5));
        System.out.println(list.contains(10));
        System.out.println("-------------");

        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        System.out.println(list);
    }
}

输出为:

 [10, 31, 2, 23, 23]
 [10, 31, 2, 23, 23]
 -------------
 false
 5
 -------------
 3
 4
 -------------
 [10, 31]
 -------------
 false
 true
 -------------
 [2, 10, 23, 23, 31]

3. LinkedList

ArrayList集合中元素允许重复,且元素之间是无序的。如果希望集合中的元素按照插入的顺序排列,以及对于频繁的插入或删除元素 的操作,LinkedList更为适合。

LinkedList的实现形式为双向链表,它的内部实现采用的是内部类Node,将其作为存储数据的基本数据结构,而不是数组。Node类不仅可以保存数据本身,而且还定义了next和prev来指向下一个元素和上一个元素。

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;
        }
    }

LinkedList除了和ArrayList具有相同的方法外,依赖于链表的实现方式,还有如下的方法:

  • addFirst(Object obj)
  • addLast(Object obj)
  • getFirst()
  • getLast()
  • removeFirst()
  • removeLast()

测试代码:

public class LinkedListMain {

    @Test
    public void test() {
        LinkedList<Integer> list = new LinkedList<>();

        // 添加元素
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list); 
        System.out.println("----------");

        list.addFirst(10);
        list.addLast(24);
        System.out.println(list); 
        System.out.println("----------");

        list.push(11);
        System.out.println(list); 
        System.out.println("----------");

        // 获取元素
        System.out.println(list.getFirst());
        System.out.println(list.getLast()); 
        System.out.println("----------");

        // 移除元素
        System.out.println(list.removeFirst()); 
        System.out.println(list.removeLast()); 
        System.out.println(list); 
        System.out.println("----------");

        list.pop();
        System.out.println(list); 
        System.out.println("----------");

        // 判空
        System.out.println(list.isEmpty()); 
    }
}

输出为:

[1, 2, 3]
----------
[10, 1, 2, 3, 24]
----------
[11, 10, 1, 2, 3, 24]
----------
11
24
----------
11
24
[10, 1, 2, 3]
----------
[1, 2, 3]
----------
false

4. Vector

Vector是List接口一个古老的实现类,它基本上和ArrayList是相同的。唯一区别在于Vector是强同步类,因此开销相比于ArrayList要大一些,访问速度较慢。但在正常的使用中更推荐使用的是ArrayList。