集合3、集合_Collection接口_List接口

List接口的使用

存储有序的可重复的数据 ---> “动态”数组,替换原有的数组

三种实现类:

  • ArrayList:作为List接口的主要实现类:线程不安全的,效率高;底层使用Object[] elementData存储
  • LinkedList:对于频繁的插入和删除操作,使用此类效率比ArrayList高;底层使用双向链表存储
  • Vector:作为List接口的古老实现类:线程安全的,效率低;底层使用Object[] elementData存储

三种实现类的异同

相同点:

三个类都是实现了List接口,存储数据的特点相同(存储有序的、可重复的数据)

不同点:如上

一、ArrayList源码分析

JDK 7中:

ArrayList list = new ArrayList();	//底层创建了长度为10的Object[] 数组 elementData
list.add(1);	//elementData[0] = new Integer(1);
...
list.add(11);	//如果此次的添加导致底层elementData数组容量不够,则扩容。默认情况下,扩容为原来的1.5倍,同时需要将原数组中的数据复制到新数组中。

结论:建议开发中使用带参的构造器:

ArrayList list = new ArrayList(int capacity)

JDK 8中:

ArrayList list = new ArrayList();	//底层Object[] elementData初始化为{},并没有创建长度为10的数组
list.add(1);	//第一次调用add()时,底层才创建了长度为10的数组,并将数据1添加到elementData中
...
//后续的添加与扩容操作与JDK7中相同

小结

jdk7中的ArrayList的对象的创建类似于单例模式的饿汉式;而jdk8中的ArrayList的对象的创建类似于单例模式的懒汉式,延迟了数组的创建,节省内存。

二、LinkedList源码分析

LinkedList list = new LinkedList();		//内部声明了Node类型的first和last属性,默认值为null
list.add(123);	//将123封装到Node中,创建了Node对象

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

三、Vector源码分析

没必要看了,反正也不用了~😄

和ArrayList区别不大,扩容有区别(Vector默认扩容是扩两倍,ArrayList默认扩容是1.5倍)

四、List接口中的常用方法

void add(int index, Object ele);//    在index位置插入ele元素
boolean addAll(int index, Collection eles);//     从index位置开始将eles中的所有元素添加进来
Object get(int index);//      获取指定index位置的元素
int indexOf(Object obj);//       返回obj在集合中首次出现的位置
int lastIndexOf(Object obj);//    返回obj在当前集合中末次出现的位置
Object remove(int index);//   移除指定index位置的元素,并返回此元素
Object set(int index, Object ele);//      设置指定index位置的元素为ele
List subList(int fromIndex, int toIndex);//       返回从fromIndex到toIndex位置的子集合

add(int index, Object ele)

//void add(int index, Object ele):    在index位置插入ele元素
System.out.println("---add()");

ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new String("ABC"));
list.add(456);

System.out.println(list);	//[123, 456, AA, ABC, 456]

list.add(1,"BB");

System.out.println(list);	//[123, BB, 456, AA, ABC, 456]

addAll(int index, Collection eles)

//boolean addAll(int index, Collection eles):     从index位置开始将eles中的所有元素添加进来
System.out.println("---addAll()");

List list1 = Arrays.asList(1, 2, 3);

list.addAll(2, list1);
System.out.println(list);	//[123, BB, 1, 2, 3, 456, AA, ABC, 456]

//若为 addAll(Collection c) 则自动将c集合的所有元素插入末尾

get(int index)

//Object get(int index):      获取指定index位置的元素
System.out.println("---get()");

System.out.println(list.get(1));	//BB

indexOf(Object obj)

//int indexOf(Object obj):       返回obj在集合中首次出现的位置。如果不存在,返回-1
System.out.println("---indexOf()");

ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new String("ABC"));
list.add(456);

int index = list.indexOf(456);
System.out.println(index);		//1

lastIndexOf(Object obj)

//int lastIndexOf(Object obj):    返回obj在当前集合中末次出现的位置
System.out.println("lastIndexOf()");

System.out.println(list.lastIndexOf(456));	//4

remove(int index)

//Object remove(int index):   移除指定index位置的元素,并返回此元素
System.out.println("---remove(int index)");

Object obj = list.remove(0);        //返回所删除的元素
System.out.println(obj);	//123
System.out.println(list);	//[456, AA, ABC, 456]

set(int index, Object ele)

//Object set(int index, Object ele):      设置指定index位置的元素为ele
System.out.println("---set()");

list.set(1, "CC");
System.out.println(list);	//[456, CC, ABC, 456]

subList(int fromIndex, int toIndex)

//List subList(int fromIndex, int toIndex):       返回从fromIndex到toIndex位置的子集合(左闭右开)
System.out.println("---subList()");

List list1 = list.subList(2, 4);
System.out.println(list1);	//[ABC, 456]

五、List方法总结以及List的遍历

List的遍历

ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new String("ABC"));
list.add(456);

//方式一:Iterator
Iterator iterator = list.iterator();
while (iterator.hasNext()){
    System.out.println(iterator.next());
}

System.out.println("**************************");

//方式二:foreach
for (Object o : list) {
    System.out.println(o);
}

System.out.println("**************************");

//方式三:普通循环
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

常用方法

  • 增:add(Object obj)
  • 删:remove(int index)/remove(Object obj)
  • 查:get(int index)
  • 改:set(int index, Object ele)
  • 插:add(int index, Object ele)
  • 长度:size()
  • 遍历:①Iterator迭代器 ②增强for循环(foreach) ③普通的循环
posted @ 2021-11-19 23:45  叁玖贰拾柒  阅读(60)  评论(0)    收藏  举报