Java学习笔记-Day23 Java List集合
- 一、List集合
- 1、ArrayList集合
- 1.1、构造方法
- 1.2、常见方法
- 2、LinkedList集合
- 2.1、构造方法
- 2.2、常见方法
- 3、Vector集合
- 3.1、构造方法
- 3.2、常见方法
- 二、List集合为空和null
- 三、为什么使用集合
- 四、迭代器Iterator
- 1、创建Iterator对象
- 2、Iterator的方法
- 五、迭代器ListIterator
- 六、泛型
- 1、泛型常见字母
- 2、泛型集合
一、List集合
List(java.util.List)是一个有序、重复、有索引的集合,是一个继承了Collection接口的接口,List集合长度可变,提供了很多灵活操作方法,可以精确控制集合中每个元素的插入位置,可以通过整数索引(集合中的位置)访问元素,可以搜索集合中的元素。通常List集合中允许重复的元素。
List接口提供了可以有效地插入和删除列表中任意一点的多个元素的方法。
添加一个对象到集合中,集合中存放的是对象的引用(内存地址值)。
1、ArrayList集合
ArrayList是一个有序、有索引、可重复、长度可变的集合。ArrayList是一个用数组实现的列表,相当于一个可调整大小的数组。
ArrayList 实现了 List 接口,实现所有List接口操作, 还提供了一些方法来操纵内部使用的存储列表的数组的大小。ArrayList允许任何符合规则的元素插入,包括null。
ArrayList的底层数据结构就是一个数组,数组元素的类型为Object类型,对ArrayList的所有操作底层都是基于数组。ArrayList底层以数组实现,是一种随机访问模式,再加上它实现了RandomAccess接口,因此查找元素的时候非常快。ArrayList顺序添加一个元素也非常方便,只是往数组里面添加了一个元素而已。根据下标遍历元素,效率高。
每个ArrayList实例都有一个容量 ,默认的初始容量为10。 容量是用于存储列表中的元素的数组的大小,它总是至少与列表的大小一样大。 当元素添加到ArrayList时,其容量会自动增长。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作(构建一个新的更大的数组并将之前的内容拷贝到新数组中),ArrayList的默认扩容后数组大小变为原数组长度的1.5倍。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间和效率。
ArrayList是一个线程不安全、不同步的集合。
1.1、构造方法
ArrayList()
:构造一个初始容量为10的空列表。ArrayList(int initialCapacity)
:构造具有指定初始容量的空列表。
1.2、常见方法
boolean add(E e)
:将指定的元素追加到此列表的末尾。void add(int index, E element)
:在此列表中的指定位置插入指定的元素。E get(int index)
:返回此列表中指定位置的元素。E remove(int index)
:删除该列表中指定位置的元素。boolean remove(Object o)
:从列表中删除指定元素的第一个出现(如果存在)。int size()
:返回此列表中的元素数。
2、LinkedList集合
LinkedList是一个有序、有索引、可重复、长度可变的集合,实现了List接口,实现所有List接口的操作。LinkedList允许任何符合规则的元素插入,包括null。所有的操作都能像ArrayList一样,通过索引来访问。
LinkedList的底层是双向链表。当数据量很大或者操作很频繁的情况下,添加和删除元素时具有比ArrayList更好的性能,但在元素的查询和修改方面要弱于ArrayList。
LinkedList存储元素的数据结构是双向链表结构,由存储元素的结点连接而成,每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可。
LinkedList是一个线程不安全、不同步的集合。
2.1、构造方法
LinkedList()
:构造一个空列表。
2.2、常见方法
boolean add(E e)
:将指定的元素追加到此列表的末尾。void add(int index, E element)
:在此列表中的指定位置插入指定的元素。void addFirst(E e)
:在该列表开头插入指定的元素。void addLast(E e)
:将指定的元素追加到此列表的末尾。E get(int index)
:返回此列表中指定位置的元素。E getFirst()
:返回此列表中的第一个元素。E getLast()
:返回此列表中的最后一个元素。
3、Vector集合
Vector是一个有序、有索引、可重复、长度可变、线程安全的集合。底层是数组,默认的初始容量为10,Vector在进行默认规则扩容时,扩容后的数组长度变为原来的2倍。Vector允许任何符合规则的元素插入,包括null。
Vector是一个线程安全、同步的集合,Vector类中的很多方法上增加了synchronized关键字,表示线程同步。
3.1、构造方法
Vector()
:构造一个空向量,使其内部数据数组的大小为 10 ,标准容量增量为零。Vector(int initialCapacity)
:构造具有指定初始容量并且其容量增量等于零的空向量。Vector(int initialCapacity, int capacityIncrement)
:构造具有指定的初始容量和容量增量的空向量。
3.2、常见方法
int capacity()
:返回此向量的当前容量。int size()
:返回此向量中的元素的个数。
二、List集合为空和null
List集合为空:list.isEmpty()
相当于 list.size()==0
, isEmpty() 判断有没有元素,而 size() 返回元素的个数,使用 isEmpty() 方法判断一个集合有无元素,判断这个集合是否为一个空集合。
List集合为null:list == null
判断list是否有为list分配地址,如果 list 为 null 表示没有对该 list 集合分配内存空间,即这个容器不存在。
三、为什么使用集合
(1)数组的长度是固定的,集合的长度是可变的。
(2)数组进行操作时,需要自己去实现算法。集合以类的形式存在,其内部的方法能够实现各种复杂的操作。
四、迭代器Iterator
迭代器Iterator是一个接口。迭代器Iterator对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素。
1、创建Iterator对象
在集合中有一个iterator()
方法,用来返回集合中的元素的迭代器。
Iterator<E> iterator()
:以正确的顺序返回集合中的元素的迭代器。
Iterator it = list.iterator();
2、Iterator的方法
boolean hasNext()
:没有指针下移操作,只是判断是否存在下一个元素。如果存在返回true。如果不存在,返回false。E next()
:指针下移,返回该指针所指向的元素。 返回值是集合的元素,而集合元素的类型可以是任意类型的,有不确定性,而为了达到代码的通用性,指定返回的类型的是Object类型。如果泛型有定义引用类型,则返回的类型为指定的引用类型。
while(it.hasNext()) {
System.out.println(it.next());
}
while(it.hasNext()) {
//集合中的元素是Book类型
Book b = (Book)it.next();
System.out.println(b.getName());
}
default void remove()
:从底层集合中删除此迭代器返回的最后一个元素(可选操作)。
while(it.hasNext()) {
System.out.println(it.next());
it.remove();
}
五、迭代器ListIterator
List接口提供了一个特殊的迭代器,称为ListIterator。其允许元件插入和更换,并且提供正常操作的双向访问。 ListIterator迭代器继承了Iterator迭代器,可以直接使用 hasNext() 和 next()方法,ListIterator迭代器还有以下方法:
Object previous()
:获取上一个元素。boolean hasPrevious()
:判断有没有上一个元素。
ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
ListIterator it = list.listIterator();
while(it.hasNext()) {
System.out.println(it.next());
}
while(it.hasPrevious()) {
System.out.println(it.previous());
}
注意:ListIterator迭代器可以逆向遍历List集合,但是前提是先正向遍历,才能逆向遍历,一般情况下不使用。
ListIterator迭代器还提供了一种方法来获取从列表中的指定位置开始的列表迭代器。
ListIterator<E> listIterator(int index)
:从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。
六、泛型
1、泛型常见字母
(1)T:Type,表示类型。
(2)E:Element,表示元素。
(3)K V:key与value,表示键与值。
(4)?:表示不确定类型。
2、泛型集合
泛型集合:支持泛型的集合,<E>
中的E
为引用类型。当E指定引用类型后,在集合中只能存放指定引用类型的对象。编译时,会对添加的数据进行类型的检查,如果添加的对象不属于指定的引用类型,则编译会不通过。
语法:
当<E>
作为方法的返回值类型时,如果在定义集合对象时泛型指定了引用类型,则返回的类型是指定的引用类型。但是如果没有指定引用类型,则默认返回的类型是Object类型,因为返回值是集合的元素,而集合元素的类型可以是任意类型的,有不确定性,为了达到代码的通用性,默认返回的类型是Object类型。
//语法①:类/接口<E> 引用名 = new 类/实现类<E>();
ArrayList<Book> set1 = new ArrayList<Book>();
//语法②:类/接口<E> 引用名 = new 类/实现类();
ArrayList<Book> set2 = new ArrayList();