文章目录
简介
所有的集合类都位于 java.util 包下,后来为了处理多线程环境下的并发安全问题,Java 5 还在java.util.concurrent 包下提供了一些多线程支持的集合类。
Java 的集合类主要由两个接口派生而出:Collection 和 Map,是 Java 集合框架的根接口,这两个接口又包含了一些子接口或实现类。
Collection
子接口如下所示:
- Set(无序,元素不可重复)
- List(有序,元素可以重复)
- Queue(队列)
Collection接口定义的方法:
// java.util
public interface Collection<E> extends Iterable<E>
int size();
boolean isEmpty();
boolean contains(Object o);
// 返回Iterator对象,用于遍历集合里的元素。
Iterator<E> iterator();
// 将集合转换成数组
Object[] toArray();
Iterator<E> iterator();
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? entends E> c);
// 取交集
boolean retainAll(Collection<?> c);
void clear();
遍历集合
- Java 8 使用 Lambda 表达式来遍历集合元素(Iterable 接口新增 forEach 默认方法)
- Iterator(迭代器)
- Java 5提供 foreach
Iterator
Iterator 仅用于遍历集合,Iterator 本身并不提供盛装对象的能力。如果需要创建 Iterator 对象,则必须有一个被迭代的集合。
// java.util
public interface Iterator<E>
// 如果被迭代的集合元素还没有被遍历完,则返回true
boolean hasNext();
// 返回集合里的下一个元素
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
// java 8为Iterator新增的默认方法
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
注: Iterator迭代访问 Collection 集合元素时,Collection 集合里的元素不能被改变。
Collections
操作集合的工具类。
List
元素有序、可重复的集合。
public interface List<E> extends Collection<E>
接口
- List
实现类
- ArrayList
- Vector
- LinkedList
ArrayList
线程不安全
LinkedList
LinkedList与ArrayList、ArrayDeque的实现机制完全不同,后者内部以数组的形式来保存集合中的元素,随机访问有较好性能;而LinkedList内部以链表的形式来保存元素,插入、删除元素时性能比较好。
Vector
线程安全,比ArrayList的性能低。子类Stack
Map
Map 用于保存具有映射关系的数据,因此 Map 集合里保存着两组值,一组值用于保存 Map 里的key,另外一组值用于保存 Map 里的 value,key 和 value 都可以是任何引用类型的数据。Map 中 key 是不可以重复的,key 用于标识集合里的每项数据。
public interface Map<K,V>
interface Entry<K,V> {
// 封装了一个 key-value 对
}
// 返回Map里所有key组成的Set集合
Set<K> keySet()
Collection<V> values()
Set<Map.Entry<K, V>> entrySet()
接口
- Map
- SortedMap
实现类
- HashMap
- LinkedHashMap
- Hashtable(不推荐使用)
- Properties
- TreeMap
- WeakHashMap
- IdentityHashMap
- EnumMap
HashMap
根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。
- HashMap 是线程不安全的。即任一时刻可以有多个线程同时写 HashMap,可能导致数据的不一致。如果需要满足线程安全,可以用
Collections
的synchronizedMap
方法,或者使用ConcurrentHashMap
。 - HashMap 最多只允许一条记录的键为 null,允许多条记录的值为 null。
LinkedHashMap
HashMap 的子类,保存了记录的插入顺序。LinkedHashMap 使用双向链表
来维护 key-value 对的次序,迭代顺序与键值对的插入顺序保持一致。
TreeMap
Map 接口派生出一个 SortedMap
子接口。TreeMap 为其实现类,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器。在使用 TreeMap 时,key 必须实现 Comparable 接口或者在构造 TreeMap 传入自定义的 Comparator。
TreeMap 就是一个红黑树
数据结构,每个 key-value 对即作为红黑树的一个节点。
Hashtable
JDK 1.0 出现。不推荐使用 Hashtable 。
- Hashtable 是线程安全的。
- Hashtable 不允许使用 null 作为 key 和 value,如果试图把 null 值放进 Hashtable 中,将会引发空指针异常。
Set
Set 不允许包含重复元素。
接口
- Set
- SortedSet
实现类
- HashSet
- LinkedHashSet
- TreeSet
- EnumSet
HashSet
LinkedHashSet
LinkedHashSet 是 HashSet 的子类。
TreeSet
TreeSet 是 SortedSet 接口的实现类。
Queue
接口
- Queue
- Deque
PriorityQueue
ArrayDeque
Deque
接口是 Queue 接口的子接口,它代表一个双端队列。
ArrayList 和 ArrayDeque 两个集合类的实现机制基本相似,底层都采用一个动态的、可重分配的Object[]数组来存储集合元素,当集合元素超出了该数组的容量时,系统会在底层重新分配一个Object[]数组来存储集合元素。