集合接口与实现分离
java集合设计的特点之一:接口与实现分离。比如队列的接口为Queue,而具体的实现类有ArrayDeque和Linkedlist,前者使用循环数组实现,后者使用链表实现。
过时的类与接口
由于Java的集合设计非常久远,中间经历过大规模改进,我们要注意到有一小部分集合类是遗留类,不应该继续使用:
- Hashtable:一种线程安全的Map实现;
- Vector:一种线程安全的List实现;
- Stack:基于Vector实现的LIFO的栈。
还有一小部分接口是遗留接口,也不应该继续使用:
- Enumeration:已被Iterator取代。
Collection接口
集合类的基本接口是Collection接口,这个接口有两个基本方法:
public interface Collection<E>{
bollean add(E element);
Iterator<E> iterator();
...
}
add向集合中添加元素。成功返回true,失败返回false。iterator用于返回一个实现了Iterator接口的对象,可以使用这个迭代器对象依次访问集合中的元素。
迭代器
Iterator接口包含四个方法:
public interface Iterator<E>{
E next();
boolean hasNext();
void remove();
default void forEachRemaining(Consumer<? super E> action);
}
通过反复调用next方法访问每一个集合元素,调用Next之前应该先使用hasNext判断是否存在下一个元素。
使用for each可以直接迭代所有集合元素而不需要使用Next方法。
另外,也可以不使用循环,直接调用forEachRemaining方法并提供一个lambda表达式,对所有集合元素调用这个lambda表达式进行处理。
Iterator接口的remove方法会删除上次调用next方法时返回的元素。
集合框架中的接口
具体集合
除了以map结尾的类,都实现了Collection接口,以map结尾的类都实现了map接口。
使用List
List接口几个主要的接口方法:
- 在末尾添加一个元素:boolean add(E e)
- 在指定索引添加一个元素:boolean add(int index, E e)
- 删除指定索引的元素:E remove(int index)
- 删除某个元素:boolean remove(Object e)
- 获取指定索引的元素:E get(int index)
- 获取链表大小(包含元素的个数):int size()
List接口有数组ArrayList实现方式以及链表LinkedList实现方式。
ArrayList是一个可变长数组。
ArrayList与LinkedList的比较:
ArrayList | LinkedList | |
---|---|---|
获取指定元素 | 速度很快 | 需要从头开始查找元素 |
添加元素到末尾 | 速度很快 | 速度很快 |
在指定位置添加/删除 | 需要移动元素 | 不需要移动元素 |
内存占用 | 少 | 较大 |
一般情况下,有限考虑使用ArrayList。
- 创建List
可以通过List接口提供的of()方法,根据给定元素快速创建List
List<Integer> list = List.of(1, 2, 5);
- 遍历List
方法一:for循环根据索引配合get(int)方法遍历:
for (int i=0; i<list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
这种方法不推荐使用,可以使用Iterator来访问List。
方法二:使用Iterator迭代List
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
String s = it.next();
System.out.println(s);
}
直接使用Iterator比较复杂,for each循环帮助我们实现了Iterator遍历。
方法三:使用for each遍历
for (String s : list) {
System.out.println(s);
}
- List和Array的转换
方法一:使用toArray()方法直接转换
List<String> list = List.of("apple", "pear", "banana");
Object[] array = list.toArray();
方法二:将相同类型的Array传入toArray()
List<Integer> list = List.of(12, 34, 56);
Integer[] array = list.toArray(new Integer[3]);
方法三:通过List接口定义的T[] toArray(IntFunction<T[]> generator)
方法
Integer[] array = list.toArray(Integer[]::new);
把array变成list只需要使用List<Integer> list = List.of(array);