五. List集合
5.1 List接口介绍
java.util.List
接口继承自Collection
接口,是单列集合的一个重要分支,习惯性地会将实现了List
接口的对象称为List集合。
特点:
- 它是一个元素存取有序的集合。
- 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
- 集合中元素可以重复,通过元素的equals方法,来比较是否为重复的元素。
常用方法
List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法。
public void add(int index, Object o); // 在index位置插入对象o。
public boolean addAll(int index, Collection c); // 将一个集合中的元素添加到此集合中的index位置。
public Object get(int index); // 返回集合中指定位置的元素。
public E set(int index, E element); // 用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
public E remove(int index)`;// 移除列表中指定位置的元素, 返回的是被移除的元素。
public List subList(int fromIndex, int toIndex); // 返回fromIndex和toIndex之间的集合元素。
5.2 ListIterator *
ListIterator 与 Iterator 的方法
Iterator迭代器包含的方法有:
- hasNext():如果迭代器指向位置后面还有元素,则返回 true,否则返回false
- next():返回集合中Iterator指向位置后面的元素
- remove():删除集合中Iterator指向位置后面的元素
ListIterator迭代器包含的方法有:
-
add(E e): 将指定的元素插入列表,插入位置为迭代器当前位置之前
-
hasNext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false
-
hasPrevious() : 如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false
-
next():返回列表中ListIterator指向位置后面的元素
-
nextIndex() :返回列表中ListIterator所需位置后面元素的索引
-
previous() : 返回列表中ListIterator指向位置前面的元素
-
previousIndex():返回列表中ListIterator所需位置前面元素的索引
-
remove() : 从列表中删除next()或previous()返回的最后一个元素(有点拗口,意思就是对迭代器使用 hasNext()方法时,删除ListIterator指向位置后面的元素;当对迭代器使用hasPrevious()方法时,删除ListIterator指向位置前面的元素)
-
set(E e):从列表中将next()或previous()返回的最后一个元素返回的最后一个元素更改为指定元素e
ListIterator 与 Iterator 异同
相同点
都是迭代器,当需要对集合中元素进行遍历不需要干涉其遍历过程时,这两种迭代器都可以使用。
不同点
- 使用范围不同,Iterator可以应用于所有的集合,Set、List和Map和这些集合的子类型。而ListIterator只能用于List及其子类型。
- ListIterator有add方法,可以向List中添加对象,而Iterator不能。
- ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以。
- ListIterator可以定位当前索引的位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
- 都可实现删除操作,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。
【例】ListIterator 正向遍历 和 反向遍历
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class IteratorDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();// 创建列表
for (int i = 0; i < 10; i++) {
// 向列表中增加10个元素
list.add(i);
}
// ======== 用Iterator正向遍历,打印ArrayList中元素 ========
Iterator it = list.iterator();
System.out.print("ArrayList集合中的元素为:");
while(it.hasNext()){
System.out.print(it.next()+" ");
}
System.out.println();
// ======== 用ListIterator正向遍历,打印ArrayList中元素 ========
System.out.println("正向遍历:");
ListIterator<Integer> li1 = list.listIterator();// 获得ListIterator对象
while(li.hasNext()){
System.out.print(li1.next()+" ");
}
System.out.println();
// ======== 用ListIterator反向遍历,打印ArrayList中元素 ========
System.out.println("反向遍历:");
ListIterator<Integer> li2 = list.listIterator();// 获得ListIterator对象
for (li2 = list.listIterator(); li2.hasNext();) {
// *将游标定位到列表结尾
li2.next();
}
for (; li2.hasPrevious();) {
// 逆序输出列表中的元素
System.out.print(li2.previous() + " ");
}
}
}
5.3 List的子类
-
ArrayList:*
- 数组结构实现,查询快、增删慢。
- JDK1.2版本,运行效率快、线程不安全。
-
Vector:
- 数组结构实现,查询快、增删慢。
- JDK1.0版本,运行效率慢、线程安全。
-
LinkedList:*
- 双向链表结构实现,增删快、查询慢。
5.4 ArrayList *
java.util.ArrayList
集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList
是最常用的集合。
5.5 LinkedList *
java.util.LinkedList
集合数据存储的结构是链表结构。方便元素添加、删除的集合。
LinkedList是一个双向链表,具体结构如下
实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。
public void addFirst(E e)
:将指定元素插入此列表的开头。public void addLast(E e)
:将指定元素添加到此列表的结尾。public E getFirst()
:返回此列表的第一个元素。public E getLast()
:返回此列表的最后一个元素。public E removeFirst()
:移除并返回此列表的第一个元素。public E removeLast()
:移除并返回此列表的最后一个元素。public E pop()
:从此列表所表示的堆栈处弹出一个元素。public void push(E e)
:将元素推入此列表所表示的堆栈。public boolean isEmpty()
:如果列表不包含元素,则返回true。
LinkedList是List的子类,List中的方法LinkedList都是可以使用,这里只介绍LinkedList的特有方法。在开发时,LinkedList集合也可以作为堆栈,队列的结构使用。(了解即可)
【例】
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<String>();
//添加元素
link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
System.out.println(link);
// 获取元素
System.out.println(link.getFirst());
System.out.println(link.getLast());
// 删除元素
System.out.println(link.removeFirst());
System.out.println(link.removeLast());
while (!link.isEmpty()) {
//判断集合是否为空
System.out.println(link.pop()); //弹出集合中的栈顶元素
}
System.out.println(link);
}
}
六. Set集合
6.1 Set接口介绍
java.util.Set
接口和java.util.List
接口一样,同样继承自Collection
接口,它与Collection
接口中的方法基本一致,并没有对Collection
接口进行功能上的扩充,只是比Collection
接口更加严格了。
特点:
- 元素存取无序
- 没有索引、只能通过迭代器或增强for循环遍历
- 会以某种规则保证存入的元素不重复
6.2 Set的子类
-
HashSet:*
- 基于HashCode实现元素不重复。
- 当存入元素的哈希码相同时,会调用 == 或equals进行确认,结果为true,拒绝后者存入。
-
LinkedHashSet:*
- 链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序。
-
TreeSet:
-
基于排列顺序实现元素不重复。
-
实现了SortedSet接口,对集合元素自动排序。
-
元素对象的类型必须实现Comparrable接口,指定排序规则。
-
通过CopareTo方法确定是否为重复元素。
-
6.3 HashSet *
java.util.HashSet
是Set
接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。java.util.HashSet
底层的实现其实是一个java.util.Ha