Java进阶之List知识详解(上)
List接口介绍
List接口是属java.util包下的,继承于Collection接口。那么我们将实现了List接口的对象称为List集合。
在List集合中允许出现重复的元素,所有的元素是以一种现行方式进行存储,在程序中可以通过索引来访问集合中的指定元素。
List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。
List接口的特点
- 它是一个元素存取有序的集合。
- 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
- 集合中可以有重复的元素(它的特性,就是这么规定的),通过元素的equals方法,来比较是否为重复的元素。
- 可以插入多个null元素
关于List特点的一些问题
“有序 ”是什么意思?
是否有序指的是集合中的元素是否会按照插入的先后顺序来存储,而不是指集合中的元素本身是否有序
那么在List集合中,有序是存取顺序一致。
比如:存入的顺序是“123”“abc”,那么取出的顺序也是“123”“abc”。
为什么List集合带有索引?
list是有序的,是以数组的存储方式进行存储,与数组相类似。但集合没有固定大小,这与数组是不一样的(数组大小固定)。
因此List中包含了一些带索引的方法。
为什么可以插入多个null值?
List中存储的每个元素本质上是一个地址指针指向一个对象的存储位置。当List中添加null的时候,相当于在List中添加了一个没有指向任何一个有效对象的引用,就是先占了一个位置,之后可以将这个位置的引用换成一个有效的引用。
List接口中带索引的方法
- public void add(int index, E element)
将指定的元素插入此列表中的指定位置。- public E get(int index)
返回此列表中指定位置的元素。- public E remove(int index)
删除该列表中指定位置的元素,返回的是被移除的元素。- public E set(int index, E element)
用指定的元素替换此列表中指定位置的元素,返回值是更新前的元素。
注意:操作索引的时候,一定要防止索引越界异常(以下是三种索引越界异常)
public class demo01List {
public static void main(String[] args) {
//创建一个List集合对象,可以使用多态
List<String> list = new ArrayList<>();
//添加元素
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
//打印集合
System.out.println(list);
//public void add(int index, E element) :将指定的元素添加到该集合中的指定位置上
//在c和d之间添加一个xxx
list.add(3,"xxx");
System.out.println(list);
//public E remove(int index):一处列表中指定位置的元素,返回的是被移除的元素
//移除元素
String removeE = list.remove(2);
System.out.println("被移除的元素:" + removeE);
System.out.println(list);
//public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素
//把最后一个a替换为A
String setE = list.set(4, "A");
System.out.println("被替换的元素:" + setE);
System.out.println(list);
//public E get(int index):返回集合中指定位置的元素
//遍历数组(for循环)
for (int i=0;i <list.size();i++){
String s = list.get(i);
System.out.println(s);
}
}
}
List下的常用实现类
ArrayList
ArrayList接口是属java.util包下的,继承于List接口。
此集合数据存储的结构是数组结构。元素增删慢,查找快。由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList底层采用动态数组的存储方式,便利效率非常高,但是ArrayList是线程不安全的。
ArrayList的优缺点
优点:
- 根据下标遍历和访问元素的效率高(查找快)
- 可以自动扩容
缺点:
- 插入和删除会带来元素的移动(增删慢)
- 根据内容查找元素的效率低
LinkedList
LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。
LinkedList是一个双向链表(头和尾很好找,里边有大量操作首尾元素的方法)。查询慢,增删快。
LinkedList常用方法
- public void addFirst(E e) 在该列表开头插入指定的元素。
- public void push(E e) 将元素推送到由此列表表示的堆栈上,此方法等效于addFirst(E)。
- public void addLast(E e) 将指定的元素追加到此列表的末尾,此方法等效于add()。
private static void show01() {
//创建LinkedList集合对象
LinkedList<String> linked = new LinkedList<>();
//使用add方法添加元素
linked.add("a");
linked.add("b");
linked.add("c");
System.out.println(linked);
//public void addFirst(E e):将指定的元素插入此列表的开头
linked.addFirst("www");
System.out.println(linked);
//public void push(E e):将元素推送到由此列表所表示的堆栈上,此方法等效于addFirst(E)
//public void addLast(E e):将指定的元素追加到此列表的末尾,此方法等效于add()
linked.addLast("com");
System.out.println(linked);
}
- public boolean isEmpty() 如果列表不包含元素,则返回true
private static void show02() {
//创建LinkedList集合对象
LinkedList<String> linked = new LinkedList<>();
//使用add方法添加元素
linked.add("a");
linked.add("b");
linked.add("c");
System.out.println(linked);
linked.clear();//清空集合中的元素 再获取集合中的元素会抛出异常
//public boolean isEmpty():如果列表不包含元素,则返回true
//增加判断
if (linked.isEmpty()){
String first = linked.getFirst();
System.out.println(first);
String last = linked.getLast();
System.out.println(last);
}
}
- public E removeFirst() 从此列表中删除并返回第一个元素。
- public E removeLast() 从此列表中删除并返回最后一个元素。
private static void show03() {
//创建LinkedList集合对象
LinkedList<String> linked = new LinkedList<>();
//使用add方法添加元素
linked.add("a");
linked.add("b");
linked.add("c");
System.out.println(linked);
String first = linked.removeFirst();
System.out.println("被移除的第一个元素:" + first);
String last = linked.removeLast();
System.out.println("被移除的最后一个元素:" + last);
System.out.println(linked);
}
LinkedList的优缺点
优点:
- 插入和删除比较快,因为不会带来元素的移动(增删快)
缺点:
- 检索速度慢(查找慢)
ArrayList与LinkedList区别
- 数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。
- 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其他数据的下标。
- ArrayList与LinkedList都是不同步的,也就是线程是不安全的。