JavaSE-集合映射
Java集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类
Collection和Collections
Collection接口
Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可用于操作Set集合也可用于操作List和Queue集合。Collection接口里定义了如下操作集合元素的方法
集合类就像容器,API主要是添加对象、删除对象、清空容器、判断容器是否为空等
Collection 接口常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| add(E e) | boolean | 向集合添加元素e,若指定集合元素改变了则返回true |
| addAll(Collection c) | boolean | 把集合c中的元素全部添加到指定集合中,若指定集合元素改变则返回true |
| remove(Object o) | boolean | 删除集合中的指定元素o;若集合中有多个o元素,则只会删除第一个元素 |
| removeAll(Collection c) | boolean | 从指定集合中删除集合c里包含的所有元素;如果删除了一个或一个以上的元素,则返回true |
| removeIf(Predicate filter) | default boolean | 删除符合filter条件的所有元素 |
| retainAll(Collection c) | boolean | 从指定集合中保留集合c的元素,其他元素都删除 |
| contains(Object o) | boolean | 判断指定集合是否包含对象o |
| containsAll(Collection c) | boolean | 判断指定集合是否包含集合c的所有元素 |
| isEmpty() | boolean | 判断指定集合是否为空;当集合长度为0时返回true,否则返回false |
| size() | int | 返回集合里的元素个数 |
| clear() | void | 清空所有集合元素,将集合长度变为0 |
| equals(Object o) | boolean | 比较指定的对象与此集合是否相等 |
| hashCode() | int | 返回哈希码 |
| spliterator() | default Spliterator | |
| iterator() | Iterator | 返回一个迭代器对象,用于遍历集合里的元素 |
| toArray() | Object[] | 把集合转换成一个Object数组 |
| toArray(T[] a) | T[] | 把集合转换为T类型的数组 |
| toArray(IntFunction generator) | default T[] | |
| stream() | default Stream | |
| parallelStream() | default Stream |
List books = new ArrayList<>();
books.add("选集1");
books.add("选集22");
books.add("选集333");
books.removeIf(ele -> ele.length() > 3);
System.out.println(books); // [选集1]
Collections工具类
Collections工具类静态方法
| 静态方法 | 返回值类型 | 说明 |
|---|---|---|
| reverse(List list) | static void | 翻转指定的List集合中元素的顺序 |
| reverseOrder() | static Comparator | 返回反转后的比较器(自然顺序) |
| reverseOrder(Comparator cmp) | static Comparator | 返回反转后的比较器(指定比较器) |
| shuffle(List list) | static void | 对List集合进行随机排序 |
| shuffle(List list,Random rnd) | static void | 对List集合进行随机排序,同时指定随机种子 |
| sort(List list) | static void | 根据元素的自然顺序对指定List集合的元素按升序进行排序 |
| sort(List list,Comparator c) | static void | 根据指定Comparator产生的顺序对List集合元素进行排序 |
| swap(List list,int i,int j) | static void | 将List集合中的第i处的元素和第j处元素进行交换 |
| rotate(List list,int distance) | static void | 当distance为正数时,将List集合的后distance个元素整体移到前面;当distance为负时,将List的前distance个元素整体移到后面 |
| binarySearch(List list, T key) | static int | 使用二分搜索法搜索指定的List集合,以获得指定对象在List集合中的索引;必须保证List已经处于有序状态 |
| binarySearch(List list,T key,Comparator c) | static int | 同时指定比较器 |
| max(Collection coll) | static T | 根据元素的自然顺序,返回给定集合中的最大元素 |
| max(Collection coll,Comparator comp) | static T | 根据Comparator指定的顺序,返回给定集合中的最大元素 |
| min(Collection coll) | static T | 根据元素的自然顺序,返回给定集合中的最小元素 |
| min(Collection coll,Comparator comp) | static T | 根据Comparator指定的顺序,返回给定集合中的最小元素 |
| fill(List list,T obj) | static void | 使用指定元素obj替换指定List集合中的所有元素 |
| frequency(Collection c,Object o) | static int | 返回指定集合中指定元素的出现次数 |
| indexOfSubList(List source,List target) | static | 返回target在source中第一次出现的位置索引;如果没有则返回-1 |
| lastIndexOfSubList(List source,List target) | static | 返回target在source中最后一次出现的位置索引;如果没有则返回-1 |
| replaceAll(List list,T oldVal,T newVal) | static boolean | 使用一个新值替换List的所有旧值 |
| addAll(Collection c,T... elements) | static boolean | 将所有指定的元素添加到指定的集合 |
| copy(List dest,List src) | static void | 将一个列表中的所有元素复制到另一个列表中 |
| nCopies(int n,T o) | static List | 返回由指定对象的n 个副本组成的不可变列表 |
| disjoint(Collection c1, Collection c2) | static boolean | 如果两个集合没有共同的元素则,返回true |
| enumeration(Collection c) | static Enumeration | 返回指定集合的枚举 |
| list(Enumeration e) | static ArrayList | 返回一个数组列表,其中包含指定枚举返回的元素,按枚举返回的顺序排列 |
| newSetFromMap(Map map) | static Set | 返回由指定映射支持的集合 |
| asLifoQueue(Deque deque) | static Queue | |
| checkedCollection(Collection c,Class type) | static Collection | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedList(List list,Class type) | static List | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedSet(Set s,Class type) | static Set | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedMap(Map m,Class keyType,Class valueType) | static Map | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedQueue(Queue queue,Class type) | static Queue | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedSortedSet(SortedSet s,Class type) | static SortedSet | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedSortedMap(SortedMap m,Class keyType,Class valueType) | static SortedMap | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedNavigableSet(NavigableSet s,Class type) | static NavigableSet | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| checkedNavigableMap(NavigableMap m,Class keyType,Class valueType) | static NavigableMap | 受查异常;如果插入一个错误类型的元素,就会抛出一个异常(用于泛型类型检查) |
| synchronizedCollection(Collection c) | static Collection | 同步视图,确保集合的线程安全 |
| synchronizedList(List list) | static List | 同步视图,确保集合的线程安全 |
| synchronizedSet(Set s) | static Set | 同步视图,确保集合的线程安全 |
| synchronizedMap(Map m) | static Map | 同步视图,确保集合的线程安全 |
| synchronizedNavigableMap(NavigableMap m) | static NavigableMap | 同步视图,确保集合的线程安全 |
| synchronizedNavigableSet(NavigableSet s) | static NavigableSet | 同步视图,确保集合的线程安全 |
| synchronizedSortedMap(SortedMap m) | static SortedMap | 同步视图,确保集合的线程安全 |
| synchronizedSortedSet(SortedSet s) | static SortedSet | 同步视图,确保集合的线程安全 |
| emptyList() | static List | 返回一个空的、不可变的集合对象 |
| emptySet() | Set | 返回一个空的、不可变的集合对象 |
| emptyMap() | static Map | 返回一个空的、不可变的集合对象 |
| emptyIterator() | static Iterator | 返回一个空的、不可变的集合对象 |
| emptyListIterator() | static ListIterator | 返回一个空的、不可变的集合对象 |
| emptyEnumeration() | static Enumeration | 返回一个空的、不可变的集合对象 |
| emptySortedSet() | static SortedSet | 返回一个空的、不可变的集合对象 |
| emptySortedMap() | static SortedMap | 返回一个空的、不可变的集合对象 |
| emptyNavigableSet() | static NabigableSet | 返回一个空的、不可变的集合对象 |
| emptyNavigableMap() | static NavigableMap | 返回一个空的、不可变的集合对象 |
| singleton(T o) | static Set | 返回一个只包含指定对象的、不可变的集合对象 |
| singletonList(T o) | static List | 返回一个只包含指定对象的、不可变的集合对象 |
| singletonMap(K key,V value) | static Map | 返回一个只包含指定对象的、不可变的集合对象 |
| unmodifiableCollection(Collection c) | static Collection | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
| unmodifiableList(List list) | static List | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
| unmodifiableSet(Set s) | static Set | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
| unmodifiableMap(Map m) | static Map | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
| unmodifiableSortedSet(SortedSet s) | static SortedSet | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
| unmodifiableSortedMap(SortedMap m) | static SortedMap | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
| unmodifiableNavigableSet(NavigableSet s) | static NavigableSet | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
| unmodifiableNavigableMap(NavigableMap m) | static NavigableMap | 返回指定集合对象的不可变视图;如果发现试图对集合进行修改,就抛出一个异常 |
迭代器
Iterable接口
Iterable接口是Collection的父接口,因此Collection集合也可直接调用该接口中的方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| forEach(Consumer action) | default void | 可以使用lambda表达式来遍历集合元素 |
| iterator() | Iterator | 获取迭代器 |
| spliterator() | default Spliterator |
Iterator接口
Iterator迭代器通过反复调用next方法,可以逐个访问集合中的每个元素。但是如果到达了集合的末尾,next方法将抛出一个NoSuchElementException。因此,需要在调用next之前调用hasNext方法。如果迭代器对象还有多个供访问的元素,这个方法就返回true。如果想要查看集合中的所有元素,就请求一个迭代器,并在hasNext返回true时反复地调用next方法
JDK8中,可以不写循环来遍历集合元素。Iterator提供了forEachRemaining方法并提供了一个lambda表达式,将对迭代器的每一个元素调用这个lambda表达式,直到没有元素为止。
Iterator 接口常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| hasNext() | boolean | 检查迭代器中是否还有元素 |
| next() | E | 获得迭代器中的下一个元素 |
| remove() | default void | 删除迭代器新返回的元素 |
| forEachRemaining(Consumer action) | default void | 使用lambda表达式来遍历集合元素 |
List books = new ArrayList<>();
books.add("选集1");
books.add("选集2");
books.add("选集3");
Iterator it = books.iterator();
it.forEachRemaining(System.out::println);
Iterator迭代器采用的是快速失败机制(fail-fast),一旦在迭代过程中检测到该集合已经被修改(通常是程序中的其他线程修改),程序立即引发 ConcurrentModificationException 异常,而不是显式修改后的结果,这样可以避免共享资源而引发的潜在问题
当使用Iterator迭代访问Collection集合元素时,Collection集合里的元素不能被改变,只有通过Iterator的remove()方法删除上一次next()方法返回的集合元素才可以;否则将会引发 java.util.ConcurrentModificationException异常
// 不能使用集合的remove()方法删除元素
Iterator it = books.iterator();
while (it.hasNext()) {
String book = it.next();
if (book.equals("选集1")) {
books.remove(book);
}
}
// 可以使用迭代器的remove()方法删除元素
Iterator it = books.iterator();
while (it.hasNext()) {
String book = it.next();
if (book.equals("选集1")) {
it.remove();
}
}
System.out.println(books); // [选集2, 选集3]
ListIterator接口
ListIterator接口是Iterator的子接口。Iterator可以应用于所有的集合(List、Set和Map和这些集合的子类型);而ListIterator只能用于List及其子类型。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator
- ListIterator可以双向遍历:hasNext和next实现顺序向后遍历,hasPrevious和previous实现逆向遍历(Iterator只能顺序向后遍历)
- ListIterator可以定位当前的索引位置,nextIndex和previousIndex可以实现(Iterator没有此功能)
- ListIterator可以使用add方法向List中添加对象(Iterator仅能遍历,不能修改)
- ListIterator可以使用set方法向List中的对象进行修改(Iterator仅能遍历,不能修改)
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| hasNext() | boolean | 以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false |
| hasPrevious() | boolean | 如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false |
| next() | E | 返回列表中ListIterator指向位置后面的元素 |
| previous() | E | 返回列表中ListIterator指向位置前面的元素 |
| nextIndex() | int | 返回列表中ListIterator所需位置后面元素的索引 |
| previousIndex() | int | 返回列表中ListIterator所需位置前面元素的索引 |
| add(E e) | void | 将指定的元素插入列表,插入位置为迭代器当前位置之前 |
| remove() | void | 从列表中删除next()或previous()返回的最后一个元素 |
| set(E e) | void | 从列表中将next()或previous()返回的最后一个元素返回的最后一个元素更改为指定元素e |
List staff = new LinkedList();
staff.add("Amy");
ListIterator it = staff.listIterator();
it.add("Tom");
it.add("Jerry");
System.out.println(staff); // [Tom, Jerry, Amy]
List接口
List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问位置的集合元素。List集合默认按元素的添加顺序设置元素的索引,例如第一次添加的元素索引为0,第二次添加的元素索引为1
List系列集合特点
- 有序:存储和取出的元素顺序一致
- 有索引:可以通过索引操作元素
- 可重复:存储的元素可以重复
List 集合常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| add(int index, E element) | void | 在列表的指定位置插入指定元素 |
| addAll(int index,Collection c) | boolean | 将集合c所包含的元素都插入到List集合的index处 |
| remove(int index) | E | 删除并返回index索引处的元素 |
| replaceAll(UnaryOperator operator) | default void | 根据opeartor指定的计算规则重新设置List集合的所有元素 |
| set(int index,E element) | E | 将index处的元素替换成element,返回被替换的旧元素 |
| get(int index) | E | 返回index处的元素 |
| indexOf(Object o) | int | 返回对象o在List集合中第一次出现的位置索引 |
| lastIndexOf(Object o) | int | 返回对象o在List集合中最后一次出现的位置索引 |
| sort(Comparator c) | default void | 根据Comparator参数对List集合的元素排序 |
| listIterator() | ListIterator | 获得列表迭代器 |
| listIterator(int index) | ListIterator | 获得从指定位置开始的迭代器 |
| subList(int fromIndex,int toIndex) | List | 将指定范围内的元素作为List返回(fromIndex≤元素<toIndex) |
| add(E e) | boolean | 向列表尾部追加指定的元素 |
| addAll(Collection c) | boolean | 追加指定collection中的所有元素到此列表的结尾 |
| remove(Object o) | boolean | 移除列表中出现的首个指定元素 |
| removeAll(Collection c) | boolean | 从列表中移除指定collection中包含的所有元素 |
| retainAll(Collection c) | boolean | 仅在列表中保留指定collection中所包含的元素 |
| contains(Object o) | boolean | 如果列表包含指定的元素,则返回true |
| containsAll(Collection c) | boolean | 如果列表包含指定collection的所有元素,则返回true |
| of(E... elements) | static List | 创建一个不可变集合(集合定义完成后不可以修改/添加/删除) |
| isEmpty() | boolean | 判断集合是否为空 如果为空 则返回true,否则返回false |
| size() | int | 返回列表中的元素数 |
| clear() | void | 从列表中移除所有元素 |
| equals(Object o) | boolean | 比较指定的对象与列表是否相等 |
| hashCode() | int | 返回列表的哈希码值 |
| spliterator() | default Spliterator | |
| iterator() | Iterator | 获得迭代器 |
| toArray() | Object[] | 把集合转换为数组 |
| toArray(T[] a) | T | 把集合转换为数组 |
List books = new ArrayList();
books.add(new String("marmaladehy"));
books.add(new String("不二橘子酱"));
books.sort((o1, o2) -> ((String) o1).length() - ((String) o2).length());
System.out.println(books); // [不二橘子酱, marmaladehy]
books.replaceAll(ele -> ((String)ele).length()); // books = [不二橘子酱, marmaladehy]
System.out.println(books); // [5, 11]
ArrayList类
ArrayList底层是基于数组实现的,根据查询元素快,增删相对慢
- ArrayList封装了一个动态的、允许再分配的Object[]数组
- ArrayList使用initialCapacity参数来设置该数组的长度,当向ArrayList中添加元素超过了该数组的长度时,它们的initialCapacity会自动增加
- 对于通常的编程场景,程序员无需关心ArrayList的initialCapacity;但如果向ArrayList集合中添加大量元素时,可使用ensureCapacity方法一次性增加initialCapacity,这可以减少重分配的次数,从而提高性能
- ArrayList是线程不安全的,当多个线程访问同一个ArrayList集合时,如果有超过一个线程修改了ArrayList集合,则程序必须手动保证该集合的同步性(Collections工具类可以将ArrayList编程线程安全的)
| ArrayList构造方法 | 说明 |
|---|---|
| ArrayList() | 构造一个初始容量为10的空列表 |
| ArrayList(int initialCapacity) | 构造一个具有指定初始容量的空列表 |
| ArrayList(Collection c) | 构造一个包含指定集合的列表 |
ArrayList实现类常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| forEach(Consumer action) | void | 遍历集合 |
| clone() | Object | 返回此ArrayList实例的浅表副本 |
| removeRange(int fromIndex,int toIndex) | protected void | 删除指定范围内的元素 |
| trimToSize() | void | 将此ArrayList实例的容量修剪为列表的当前大小 |
| ensureCapacity(int minCapacity) | void | 将ArrayList集合的Object[]数组长度增加大于或等于minCapacity值 |
| add(E e) | boolean | 向列表尾部追加指定的元素 |
| addAll(Collection c) | boolean | 追加指定collection中的所有元素到此列表的结尾 |
| remove(Object o) | boolean | 移除列表中出现的首个指定元素 |
| removeAll(Collection c) | boolean | 从列表中移除指定collection中包含的所有元素 |
| retainAll(Collection c) | boolean | 仅在列表中保留指定collection中所包含的元素 |
| contains(Object o) | boolean | 如果列表包含指定的元素,则返回true |
| containsAll(Collection c) | boolean | 如果列表包含指定collection的所有元素,则返回true |
| isEmpty() | boolean | 判断集合是否为空 如果为空 则返回true,否则返回false |
| size() | int | 返回列表中的元素数 |
| clear() | void | 从列表中移除所有元素 |
| equals(Object o) | boolean | 比较指定的对象与列表是否相等 |
| hashCode() | int | 返回列表的哈希码值 |
| spliterator() | default Spliterator | |
| iterator() | Iterator | 获得迭代器 |
| toArray() | Object[] | 把集合转换为数组 |
| toArray(T[] a) | T | 把集合转换为数组 |
| add(int index, E element) | void | 在列表的指定位置插入指定元素 |
| addAll(int index,Collection c) | boolean | 将集合c所包含的元素都插入到List集合的index处 |
| remove(int index) | E | 删除并返回index索引处的元素 |
| set(int index,E element) | E | 将index处的元素替换成element,返回被替换的旧元素 |
| get(int index) | E | 返回index处的元素 |
| indexOf(Object o) | int | 返回对象o在List集合中第一次出现的位置索引 |
| lastIndexOf(Object o) | int | 返回对象o在List集合中最后一次出现的位置索引 |
| listIterator() | ListIterator | 获得列表迭代器 |
| listIterator(int index) | ListIterator | 获得从指定位置开始的迭代器 |
| subList(int fromIndex,int toIndex) | List | 将指定范围内的元素作为List返回(fromIndex≤元素<toIndex) |
Vector接口和Stack类
Vector和ArrayList在用法上几乎完全相同,但由于Vector是一个古老的集合(JDK1.0就有了),那时候Java还没有提供系统的集合框架,所以Vector里提供了一些方法名很长的方法,例如addElement(Object obj),实际上这个方法和ArrayList中的add(Object obj)没有任何区别。从JDK1.2以后,Java提供了系统的集合框架,就将Vector改为实现List接口的实现类之一,从而导致Vector里有一些功能重复的方法
- Vector的系列方法中方法名更短的方法属于后来新增的方法,方法名更长的方法是Vector原有的方法
- Vector是线程安全的,所以Vector的性能比ArrayList的性能要低
- 实际上Vector具有很多缺点,通常尽量少用Vector实现类
Vector提供了Stack子类,它用于模拟“栈”这种数据结构,“栈”通常是指后进先出(LIFO)的容器
注意:由于Stack继承了Vector,因此Stack也是一个非常古老的集合类,它同样是线程安全的、性能较差的,因此应该尽量少用Stack类。如果程序需要使用“栈”这种数据结构,则可以考虑使用ArrayDeque
| Stack常用方法 | 返回值类型 | 说明 |
|---|---|---|
| push(E item) | E | 进栈:将指定元素item进栈 |
| pop() | E | 出栈;返回栈顶元素,并将该元素出栈 |
| peek() | E | 返回栈顶元素,但不将该元素出栈 |
| empty() | boolean | 测试此栈是否为空 |
| search(Object o) | int | 返回要搜索的对象o距栈顶最近出现的距离(栈顶为1;如果对象不在栈中则返回-1) |
LinkedList类
LinkedList底层基于双链表实现的,查询元素慢,增删首尾元素是非常快的(栈+队列)
| LinkedList构造器 | 说明 |
|---|---|
| LinkedList() | 构造一个空链表 |
| LinkedList(Collection c) | 构造一个链表,并将集合c中的所有元素添加到这个链表中 |
LinkedList实现类常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| push(E e) | void | 入栈;底层调用addFirst() |
| addFirst(E e) | void | 在集合开头插入指定的元素 |
| pop() | E | 出栈;底层调用addLast() |
| addLast(E e) | void | 在集合末尾追加指定的元素 |
| getFirst() | E | 返回集合第一个元素 |
| getLast() | E | 返回集合最后一个元素 |
| removeFirst() | E | 从集合中删除并返回第一个元素 |
| removeLast() | E | 从集合中删除并返回最后一个元素 |
| removeFirstOccurrence(Object o) | boolean | 删除此列表中第一次出现的指定元素 |
| removeLastOccurrence(Object o) | boolean | 删除此列表中最后一次出现的指定元素 |
| remove() | E | 检索并删除此列表的第一个元素;如果此列表为空抛出异常 |
| offer(E e) | boolean | 添加指定元素作为此列表的尾部 |
| offerFirst(E e) | boolean | 可模拟入队;在此列表的前面插入指定的元素 |
| offerLast(E e) | boolean | 可模拟出队;在此列表的末尾插入指定的元素 |
| peekFirst() | E | 检索但不删除集合的第一个元素,如果此列表为空则返回null |
| peekLast() | E | 检索但不删除集合的最后一个元素,如果此列表为空则返回null |
| poll() | E | 检索并删除此列表的第一个元素;如果此列表为空返回null |
| pollFirst() | E | 检索并删除集合的第一个元素,如果此列表为空则返回null |
| pollLast() | E | 检索并删除集合的最后一个元素,如果此列表为空则返回null |
| element() | E | 检索但不删除集合的第一个元素 |
| peek() | E | 检索但不删除集合的第一个元素 |
| clone() | Object | 返回此LinkedList实例的浅表副本 |
| contains(Object o) | boolean | 判断集合中是否包含指定的元素 |
| descendingIterator() | Iterator | 以相反的顺序返回此双端队列中元素的迭代器 |
| add(E e) | boolean | 向列表尾部追加指定的元素 |
| add(int index, E element) | void | 在列表的指定位置插入指定元素 |
| addAll(Collection c) | boolean | 追加指定collection中的所有元素到此列表的结尾 |
| addAll(int index,Collection c) | boolean | 将集合c所包含的元素都插入到List集合的index处 |
| remove(Object o) | boolean | 移除列表中出现的首个指定元素 |
| remove(int index) | E | 删除并返回index索引处的元素 |
| set(int index,E element) | E | 将index处的元素替换成element,返回被替换的旧元素 |
| get(int index) | E | 返回index处的元素 |
| indexOf(Object o) | int | 返回对象o在List集合中第一次出现的位置索引 |
| lastIndexOf(Object o) | int | 返回对象o在List集合中最后一次出现的位置索引 |
| listIterator(int index) | ListIterator | 获得从指定位置开始的迭代器 |
| size() | int | 返回列表中的元素数 |
| clear() | void | 从列表中移除所有元素 |
| toArray() | Object[] | 把集合转换为数组 |
| toArray(T[] a) | T | 把集合转换为数组 |
| spliterator() | default Spliterator |
Set接口
Set集合和Collection基本相同,没有提供任何额外的方法。实际上Set就是Collection,只是行为略有不同
Set集合特点:
- 无序:存取顺序不一致
- 不重复:可以去除重复
- 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素
Set集合实现类特点:
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:排序、不重复、无索引
Set接口常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| add(E e) | boolean | 向列表尾部追加指定的元素 |
| addAll(Collection c) | boolean | 追加指定collection中的所有元素到此列表的结尾 |
| remove(Object o) | boolean | 移除列表中出现的首个指定元素 |
| removeAll(Collection c) | boolean | 从列表中移除指定collection中包含的所有元素 |
| retainAll(Collection c) | boolean | 仅在列表中保留指定collection中所包含的元素 |
| contains(Object o) | boolean | 如果列表包含指定的元素,则返回true |
| containsAll(Collection c) | boolean | 如果列表包含指定collection的所有元素,则返回true |
| of(E... elements) | static List | 创建一个不可变集合(集合定义完成后不可以修改/添加/删除) |
| iterator() | Iterator | 获得迭代器 |
| isEmpty() | boolean | 判断集合是否为空 如果为空 则返回true,否则返回false |
| size() | int | 返回列表中的元素数 |
| clear() | void | 从列表中移除所有元素 |
| equals(Object o) | boolean | 比较指定的对象与列表是否相等 |
| hashCode() | int | 返回列表的哈希码值 |
| spliterator() | default Spliterator | |
| toArray() | Object[] | 把集合转换为数组 |
| toArray(T[] a) | T | 把集合转换为数组 |
HashSet类
HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找功能
- 不能保证元素的排列顺序,顺序可能和添加顺序不同
- HashSet不是同步的,如果多个线程同时访问一个HashSet,假设有两个或两个以上线程同时修改了HashSet集合时,则必须通过代码来保证其同步
- 集合元素值可以是null
当向HashSet集合存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode值决定该对象在HashSet中的存储位置
- 如果有两个对象通过equals()方法比较返回true,但它们的hashCode()方法返回值不相等,HashSet将会把它们存储在Hash表的不同位置,从而使两个对象都可以添加成功,这就与Set集合的规则冲突了
- 如果两个对象的hashCode()方法返回的hashCode值相同,但它们通过equals()方法比较返回false时更麻烦:因为两个对象的hashCode值相同,HashSet将试图把它们保存在同一个位置,但又不行,所以实际上会在这个位置用链式结构来保存多个对象;而HashSet访问集合元素时也是根据元素的hashCode值来快速定位的,如果HashSet中两个以上的元素具有相同的hashCode值,将会导致性能下降(在一个桶中放多个元素)
也就是说HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法返回值也相等
补充:hash算法的功能是保证快速查找被检索的对象,hash算法的价值在于速度。当需要查询集合中某个元素时,hash算法可以直接根据该元素的hashCode值计算出该元素的存储位置,从而快速定位该元素
具体实现:在Java中散列表(hash table)用链表数组实现,每个列表被称为桶(bucket)。要想查找表中对象的位置,就要先计算它的散列码(hash code),然后与桶的总数取余,所得到的结果就是保存这个元素的桶的索引。例如:某个对象的散列码为76268,并且有128个桶,对象应该保存在第108号桶中(76268除以128余108),如果在这个桶中没有其他元素,此时将元素直接插入到桶中就可以了;如果当桶被占满时(也被称为散列冲突),需要用新对象与桶中的所有对象进行比较,查看这个是否已经存在。如果散列码是合理且随机分布的,桶的数目也足够大,需要比较的次数就会很少
如果想要更多地控制散列表的运行性能,就要指定一个初始的桶数。桶数是指用于收集具有相同散列值的桶的数目。如果要插入到散列表中的元素太多,就会增加冲突的可能性,降低运行性能。如果大致知道最终会有多少个元素要插入到散列表中,就可以设置桶数。通常将桶数设置为预计元素个数的75%~150%。有些研究人员认为:尽管还没有确凿的证据,但最好将桶数设置为一个素数,以防键的集聚。标准类库使用的桶数是2的幂,默认值为16
当然,并不是总能够知道需要存储多少个元素的,也有可能最初的估计过低。如果散列表太慢,就需要再散列(rehashed)。如果要对散列表再散列,就需要创建一个桶数更多的表,并将所有元素插入到这个新表中,然后丢弃原来的表。填装因子(load factor:确定散列表填充的百分比,当大于这个百分比时,散列表进行再散列)决定何时对散列表进行再散列。例如如果填装因子为0.75(默认值),而表中超过75%的位置已经填入元素,这个表就会用双倍的桶数自动地进行再散列
补充:在JDK8中,桶满时会从链表变为平衡二叉树
| HashSet构造方法 | 说明 |
|---|---|
| HashSet() | 构造一个空散列表 |
| HashSet(Collection c) | 构造一个散列集,并将集合中的所有元素添加到这个散列集中 |
| HashSet(int initialCapacity) | 构造一个空的具有指定容量(桶数)的散列集 |
| HashSet(int initialCapacity,float loadFactor) | 构造一个具有指定容量(桶数)和填装因子的空散列集(一个0.0-1.0之间的数值) |
HashSet实现类常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| add(E e) | boolean | 如果此集合尚未包含指定的元素则返回true;如果已包含则返回false |
| clear() | void | 从此集合中删除所有元素.调用后,该集合将为空 |
| clone() | Object | 浅复制 |
| contains(Object o) | boolean | 如果此集合包含指定的元素,则返回true |
| isEmpty() | boolean | 如果此集合不包含任何元素,则返回true |
| iterator() | Iterator | 获取迭代器 |
| remove(Object o) | boolean | 如果集合包含指定的元素,将之删除并返回false |
| size() | int | 返回此集合中的元素数 |
| spliterator() | Spliterator |
LinkedHashSet类
LinkedHashSet特点:有顺序,不重复
- LinkedHashSet也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的(元素有序)。也就是说,当遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素
- LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问Set里的全部元素时将有很好的性能,因为它以链表来维护内部顺序
| LinkedHashSet构造方法 | 说明 |
|---|---|
| LinkedHashSet() | 构造一个空链接散列集 |
| LinkedHashSet(Collection c) | 构造一个链接散列集,并将集合中的所有元素添加到这个链接散列集中 |
| LinkedHashSet(int initialCapacity) | 构造一个空的具有指定容量(桶数)的链接散列集 |
| LinkedHashSet(int initialCapacity, float loadFactor) | 构造一个具有指定容量(桶数)和填装因子的空链接散列集(一个0.0-1.0之间的数值) |
| LinkedHashSet常用方法 | 返回值类型 | 说明 |
|---|---|---|
| spliterator() | spliterator |
TreeSet类
TreeSet是SortedSet接口的实现类,TreeSet采用红黑树的数据结构来存储集合元素,每次将一个元素添加到树中时,都被放置在正确的排序位置上,因此迭代器总是以排好序的顺序访问每个元素
(对于TreeSet而言,它判断两个对象是否相等的唯一标准是:两个对象通过compareTo方法比较是否返回0,只有返回0才会认为它们相等,否则就认为它们不相等)
TreeSet支持两种排序方法:自然排序和定制排序;在默认情况下,TreeSet采用自然排序
- 自然排序:TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按升序排列
- 定制排序:需要在创建TreeSet对象时,提供一个Comparator对象与该TreeSet集合关联。该Comparator接口对象中的compare方法负责集合元素的排序逻辑
如果把一个对象添加到TreeSet时,则该对象的类必须实现Comparable接口,否则程序将会抛出异常
- 添加第一个对象时,TreeSet中没有任何元素,所以不会出现任何问题
- 添加第二个对象时,TreeSet就会调用对象的compareTo方法与集合中的其他元素进行比较
- 如果其对应的类没有实现Comparable接口,则会引发ClassCastException异常
class People {}
public class Main {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new People());
ts.add(new People());
}
}
向TreeSet中添加的应该是同一个类的对象,否则也会引发ClassCastException异常。当把一个对象添加到TreeSet集合时,TreeSet会调用该对象的compareTo方法与集合中的其他元素进行比较,这就要求集合中的其他元素与该元素是同一个类的实例
TreeSet ts = new TreeSet();
ts.add(new String("hello world!"));
ts.add(new Date());
如果希望TreeSet能正常运作,TreeSet只能添加同一种类型的对象
| TreeSet构造方法 | 说明 |
|---|---|
| TreeSet() | 构造一个空树集 |
| TreeSet(Collection c) | 根据指定参数,构造一个树集 |
| TreeSet(Comparator comparator) | 根据指定参数,构造一个树集 |
| TreeSet(SortedSet s) | 根据指定参数,构造一个树集 |
TreeSet 集合常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| comparator() | Comparator | 获取比较器;如果采用了定制排序则返回使用的Comparator,如果是自然排序则返回null |
| first() | E | 返回集合中第一个元素 |
| last() | E | 返回集合中最后一个元素 |
| higher(E e) | E | 返回大于value的最小元素;如果没有这样的元素则返回null |
| lower(E e) | E | 返回小于value的最大元素;如果没有这样的元素则返回null |
| ceiling(E e) | E | 返回大于等于value的最小元素;如果没有这样的元素则返回null |
| floor(E e) | E | 返回小于等于value的最大元素;如果没有这样的元素则返回null |
| pollFirst() | E | 删除并返回这个集合中的最大元素;这个集合为空时返回null |
| pollLast() | E | 删除并返回这个集合中的最小元素;这个集合为空时返回null |
| headSet(E toElement) | SortedSet | 返回此Set的子集,由小于toElement的元素组成 |
| headSet(E toElement,boolean inclusive) | NavigableSet | |
| tailSet(E fromElement) | SortedSet | 返回此Set的子集,由大于或等于toElement的元素组成 |
| tailSet(E fromElement,boolean inclusive) | NavigableSet | |
| subSet(E fromElement,E toElement) | SortedSet | 返回此Set的子集,(fromIndex ≤ 元素范围 < toElement) |
| subSet(E fromElement,boolean fromInclusive,E toElement,boolean toInclusive) | NavigableSet | |
| iterator() | Iterator | 获取迭代器 |
| descendingIterator() | Iterator | 返回一个按照递减顺序遍历集合中元素的迭代器 |
| descendingSet() | NavigableSet | |
| clone() | Object | 浅复制 |
| spliterator() | Spliterator | |
| add(E e) | boolean | 向集合添加元素e,若指定集合元素改变了则返回true |
| addAll(Collection c) | boolean | 把集合c中的元素全部添加到指定集合中,若指定集合元素改变则返回true |
| remove(Object o) | boolean | 删除集合中的指定元素o;若集合中有多个o元素,则只会删除第一个元素 |
| contains(Object o) | boolean | 判断指定集合是否包含对象o |
| isEmpty() | boolean | 判断指定集合是否为空;当集合长度为0时返回true,否则返回false |
| size() | int | 返回集合里的元素个数 |
| clear() | void | 清空所有集合元素,将集合长度变为0 |
EnumSet抽象类
EnumSet是一个专为枚举类设计的集合类,EnumSet中所有元素都必须是指定枚举类型的枚举值
EnumSet 常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| allOf(Class elementType) | static EnumSet | 创建一个包含指定枚举类里所有枚举值的EnumSet集合 |
| clone() | EnumSet | |
| complementOf(EnumSet s) | static EnumSet | 创建一个其元素类型与指定EnumSet里元素类型相同的EnumSet集合 |
| copyOf(Collection c) | static EnumSet | 使用一个普通集合来创建EnumSet集合 |
| copyOf(EnumSet s) | static EnumSet | 创建一个与指定EnumSet具有相同元素类型、相同集合元素的EnumSet集合 |
| noneOf(Class elementType) | static EnumSet | 创建一个元素类型为枚举类型的空EnumSet |
| of(E first, E... rest) | static EnumSet | 创建一个包含一个或多个枚举值的EnumSet集合,传入的多个枚举值必须属于同一个枚举类 |
| range(E from, E to) | static EnumSet | 创建一个包含从from枚举值到to枚举值范围内所有枚举值的EnumSet集合 |
// 方法一:创建一个EnumSet集合,集合元素就是Season枚举类的全部枚举值
EnumSet es1 = EnumSet.allOf(Season.class);
System.out.println(es1); // [SPRING, SUMMER, FALL, WINTER]
// 方法二:创建一个EnumSet空集合,指定其集合元素是Season类的枚举值
EnumSet es2 = EnumSet.noneOf(Season.class);
System.out.println(es2); // []
es2.add(Season.WINTER); // 手动添加元素
// 方法三:以指定的枚举值创建EnumSet集合
EnumSet es3 = EnumSet.of(Season.SUMMER, Season.WINTER);
System.out.println(es3); // [SUMMER, WINTER]
// 方法四:以指定的区间创建EnumSet集合
EnumSet es4 = EnumSet.range(Season.SUMMER, Season.WINTER);
System.out.println(es4); // [SUMMER, FALL, WINTER]
// 方法五:es5集合元素 + es4集合元素 = Season枚举类的全部枚举值
EnumSet es5 = EnumSet.complementOf(es4);
System.out.println(es5); // [SPRING]
// 方法六:赋值Collection集合中的所有元素来创建EnumSet集合
Collection c = new HashSet();
c.add(Season.SUMMER);
c.add(Season.WINTER);
// 注意:c集合中的元素必须保证都是同一个枚举类里的枚举值,否则会抛出ClassCastException异常
EnumSet es6 = EnumSet.copyOf(c);
Map接口
Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value,key和value都可以存放任何引用类型的数据
- Map的key不允许重复,且key和value之间存在单向一对一关系,即通过指定的key总能找到唯一的、确定的value
- Map里的所有key放在一起就组成了一个Set集合(所有的key没有顺序,key与key之间不能重复)
- Map里的所有value放在一起非常类似与一个List,元素之间可以重复;从Map中取出元素,则需要提供该元素的key索引
- Map提供了一个Entry内部类来封装key-value对。从源码来看Java先实现了Map,然后通过包装一个所有value都为null的map就实现了Set集合
Map接口常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| put(K key, V value) | V | 添加一个键值对;如果已有一个与该key相等的键值对,则新的会覆盖原来的 |
| putAll(Map m) | void | 将参数Map中的键值对复制到本Map中 |
| putIfAbsent(K key,V value) | default V | 自动检测指定的key对应的value是否为null;如果为null则用value替换原来的null值 |
| remove(Object key) | V | 删除指定的键值对 |
| remove(Object key,Object value) | default boolean | 删除指定键值对;如果成功删除则返回true |
| replace(K key,V value) | default V | 将指定的key对应的值替换为value;如果key不存在则该方法不会添加键值对,返回null |
| replace(K key,V oldValue,V newValue) | default boolean | 将指定的键值对中的value替换为新的value;成功替换则返回true |
| replaceAll(BiFunction function) | default void | 使用BiFunction对原key-value执行计算,并将计算结果作为该键值对的value值 |
| get(Object key) | V | 返回指定的key所对应的value;如果Map中不包含该key则返回null |
| getOrDefault(Object key,V defaultValue) | default V | 获得指定key对应的value,如何key不存在则返回defaultValue |
| keySet() | Set | 返回键集合 |
| values() | Collection | 返回值集合 |
| entrySet() | Set | 返回键值对集合,每个集合元素都是Map.Entry对象 |
| containsKey(Object key) | boolean | 查询Map中是否包含指定的key,如果包含则返回true |
| containsValue(Object value) | boolean | 查询Map中是否包含指定的value,如果包含则返回true |
| of(E... elements) | static List | 创建一个不可变集合(集合定义完成后不可以修改/添加/删除) |
| isEmpty() | boolean | 查询该Map是否为空;如果为空则返回null |
| size() | int | 返回该Map里的键值对个数 |
| clear() | void | 删除该Map对象中的所有key-value对 |
| equals(Object o) | boolean | 判断是否相等 |
| hashCode() | int | 返回哈希码 |
| forEach(BiConsumer action) | default void | 遍历所有的键值对 |
| merge(K key,V value,BiFunction remappingFunction) | default V | 根据key获取对应的value,如果获取的value为null,则直接用传入的value覆盖;如果不为null则使用BiFunction函数根据原key和新value计算一个新的结果,并用得到的结果区覆盖原有的value |
| compute(K key,BiFunction remappingFunction) | default V | 使用BiFunction原key-value计算一个新value,只要新value不为null,就用新value覆盖原value;如果原value不为null,新value为null,则删除原key-value对;如果原value,新value同时为null,那该方法不改变任何键值对直接返回null |
| computeIfAbsent(K key,Function mappingFunction) | default V | 如果参数key对应的value为null,则Function函数根据key计算一个新结果,如果计算结果不为null,则用计算结果覆盖原有的value;如果原Map不包含该key,那该方法可能会添加一组键值对 |
| computeIfPresent(K key,BiFunction remappingFunction) | default V | 如果参数key对应的value不为null,将使用BiFunction函数根据原key-value计算一个新的值,如果计算的结果不为null,则使用该结果覆盖原来的 |
Map map = new HashMap();
map.put("让子弹飞", 1);
map.put("我不是药神", 2);
System.out.println(map); // {让子弹飞=1, 我不是药神=2}
map.replace("哪吒", 3); // 因为原Map中没有对应的key,因此Map不会添加新的key-value对
System.out.println(map); // {让子弹飞=1, 我不是药神=2}
map.merge("让子弹飞", 10, (oldValue, newValue) -> (Integer) oldValue + (Integer) newValue);
System.out.println(map); // {让子弹飞=11, 我不是药神=2}
// 如果key对应的value为null(或不存在),使用计算的结果作为新的value
map.computeIfAbsent("哪吒", (key) -> ((String) key).length());
System.out.println(map); // {哪吒=2, 让子弹飞=11, 我不是药神=2}
// 如果key对应的value存在时,使用计算的结果作为新value
map.computeIfPresent("哪吒", (key, value) -> (Integer) value * (Integer) value);
System.out.println(map); // {哪吒=4, 让子弹飞=11, 我不是药神=2}
HashMap类
HashMap是Map接口的典型实现类
- 它是线程不安全的,因此性能更好点,但如果有多个线程访问同一个Map对象时,会不安全
- HashMap可以存放null值作为key,但由于HashMap中key不能重复,所以HashMap里最多只有一个key为null,但value为null可以有无数个
- HashMap不能保证元素的顺序
| HashMap构造方法 | 说明 |
|---|---|
| HashMap() | 构造一个具有默认初始容量(16)和默认负载因子(0.75)的空HashMap |
| HashMap(int initialCapacity) | 构造一个具有指定初始容量和默认负载因子(0.75)的空HashMap |
| HashMap(int initialCapacity, float loadFactor) | 构造一个具有指定初始容量和负载因子的空HashMap |
| HashMap(Map m) | 使用与指定Map相同的映射构造一个新的HashMap |
HashMap 常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| put(K key, V value) | V | 添加一个键值对;如果已有一个与该key相等的键值对,则新的会覆盖原来的 |
| putAll(Map m) | void | 将参数Map中的键值对复制到本Map中 |
| putIfAbsent(K key,V value) | V | 自动检测指定的key对应的value是否为null;如果为null则用value替换原来的null值 |
| remove(Object key) | V | 删除指定的键值对 |
| remove(Object key,Object value) | boolean | 删除指定键值对;如果成功删除则返回true |
| replace(K key,V value) | V | 将指定的key对应的值替换为value;如果key不存在则该方法不会添加键值对,返回null |
| replace(K key,V oldValue,V newValue) | boolean | 将指定的键值对中的value替换为新的value;成功替换则返回true |
| replaceAll(BiFunction function) | void | 使用BiFunction对原key-value执行计算,并将计算结果作为该键值对的value值 |
| get(Object key) | V | 返回指定的key所对应的value;如果Map中不包含该key则返回null |
| getOrDefault(Object key,V defaultValue) | V | 获得指定key对应的value,如何key不存在则返回defaultValue |
| keySet() | Set | 返回键集合 |
| values() | Collection | 返回值集合 |
| entrySet() | Set | 返回键值对集合,每个集合元素都是Map.Entry对象 |
| containsKey(Object key) | boolean | 查询Map中是否包含指定的key,如果包含则返回true |
| containsValue(Object value) | boolean | 查询Map中是否包含指定的value,如果包含则返回true |
| isEmpty() | boolean | 查询该Map是否为空;如果为空则返回null |
| size() | int | 返回该Map里的键值对个数 |
| clear() | void | 删除该Map对象中的所有key-value对 |
| clone() | Object | 浅复制 |
| forEach(BiConsumer action) | void | 遍历所有的键值对 |
| merge(K key, V value,BiFunction remappingFunction) | V | 根据key获取对应的value,如果获取的value为null,则直接用传入的value覆盖;如果不为null则使用BiFunction函数根据原key和新value计算一个新的结果,并用得到的结果区覆盖原有的value |
| compute(K key,BiFunction remappingFunction) | V | 使用BiFunction原key-value计算一个新value,只要新value不为null,就用新value覆盖原value;如果原value不为null,新value为null,则删除原key-value对;如果原value,新value同时为null,那该方法不改变任何键值对直接返回null |
| computeIfAbsent(K key,Function mappingFunction) | V | 如果参数key对应的value为null,则Function函数根据key计算一个新结果,如果计算结果不为null,则用计算结果覆盖原有的value;如果原Map不包含该key,那该方法可能会添加一组键值对 |
| computeIfPresent(K key,BiFunction remappingFunction) | V | 如果参数key对应的value不为null,将使用BiFunction函数根据原key-value计算一个新的值,如果计算的结果不为null,则使用该结果覆盖原来的 |
LinkedHashMap类
LinkedHashMap使用双向链表来维护key-value对的次序(其实只要维护key的次序),该链表维护Map的迭代顺序,迭代顺序与价值对的插入顺序保持一致。LinkedHashMap需要维护元素的插入顺序,因此性能略低于HashMap的性能;但因为它以链表来维护内部顺序,所以在迭代访问Map里的全部元素时将有较好的性能
| LinkedHashMap构造方法 | 说明 |
|---|---|
| LinkedHashMap() | 使用默认的初始容量(16)和加载因子(0.75)构造一个空的LinkedHashMap实例 |
| LinkedHashMap(int initialCapacity) | 构造一个空的LinkedHashMap实例,具有指定的初始容量和默认加载因子(0.75) |
| LinkedHashMap(int initialCapacity,float loadFactor) | 使用指定的初始容量和加载因子构造一个空的LinkedHashMap实例 |
| LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder) | 构造一个具有指定初始容量、负载因子和排序模式的空LinkedHashMap实例 |
| LinkedHashMap(Map m) | 构造一个与指定映射具有相同映射关系的LinkedHashMap实例 |
LinkedHashMap 常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| keySet() | Set | 获取键的集合 |
| values() | Collection | 获取值的集合 |
| entrySet() | Set | 获取键值对的集合 |
| forEach(BiConsumer action) | void | 遍历集合 |
| get(Object key) | V | 获取指定的key对应的value值 |
| getOrDefault(Object key,V defaultValue) | V | 获得指定key对应的value,如何key不存在则返回defaultValue |
| removeEldestEntry(Map.Entry eldest) | protected boolean | 判断是否从Map中删除了最老的条目;每次将新元素添加到集合时,最旧的条目都会从Map中删除 |
| replaceAll(BiFunction function) | void | 使用BiFunction对原key-value执行计算,并将计算结果作为该键值对的value值 |
| containsValue(Object value) | boolean | 判断是否包含指定的value值 |
| clear() | void | 清空集合元素 |
TreeMap类
TreeMap就是一个红黑树数据结构,每个key-vlaue对即作为红黑树的一个节点,在存储时需要根据key对节点进行排序,这样可以保证所有的键值对处于有序状态
- 自然排序:TreeMap的所有key必须实现comparable接口,而且所有的key应该是同一个类的对象,否则会抛出 ClassCastException异常
- 定制排序:创建TreeMap时传一个Comparator对象,该对象负责对TreeMap中的所有key进行排序,采用定制排序时不要求Map的key实现Comparable接口
| 构造方法 | 说明 |
|---|---|
| TreeMap() | 构造一个空的树映射 |
| TreeMap(Comparator comparator) | 构造一个树映射,并使用指定的比较器对键进行排序 |
| TreeMap(Map m) | 构造一个树映射,并将映射m添加到本树映射中 |
| TreeMap(SortedMap m) | 按照参数构建一个树映射 |
TreeMap 常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| put(K key, V value) | V | 添加键值对 |
| putAll(Map map) | void | 添加指定参数的键值对 |
| remove(Object key) | V | 删除指定的键对应的键值对 |
| replace(K key,V value) | V | 替换键值对 |
| replace(K key,V oldValue,V newValue) | boolean | 替换键值对 |
| replaceAll(BiFunction function) | void | 替换键值对 |
| get(Object key) | V | 获取键值对 |
| keySet() | Set | 获取键集合 |
| values() | Collection | 获取值集合 |
| entrySet() | Set | 获取键值对 |
| forEach(BiConsumer action) | void | 遍历集合 |
| descendingKeySet() | NavigableSet | 反向遍历key |
| descendingMap() | NavigableMap | 反向遍历map |
| navigableKeySet() | NavigableSet | |
| firstEntry() | Map.Entry | 返回Map中最小key所对应的键值对,如果该Map为空则返回null |
| lastEntry() | Map.Entry | 返回Map中最大key所对应的键值对,如果该Map为空则返回null |
| higherEntry(K key) | Map.Entry | 返回Map中位于key后一位的键值对,如果该Map为空则返回null |
| lowerEntry(K key) | Map.Entry | 返回Map中位于key前一位的键值对,如果该Map为空则返回null |
| ceilingEntry(K key) | Map | 返回与大于或等于给定键的最小键关联的键值映射 |
| floorEntry(K key) | Map.Entry | 返回与小于或等于给定键的最大键相关联的键值映射 |
| pollFirstEntry() | Map.Entry | 删除并返回与此映射中最少键关联的键值映射 |
| pollLastEntry() | Map.Entry | 删除并返回与此映射中最大键关联的键值映射 |
| firstKey() | K | 返回Map中的最小key值,如果该Map为空则返回null |
| lastKey() | K | 返回Map中的最大key值,如果该Map为空则返回null |
| ceilingKey(K key) | K | 返回大于或等于给定键的最小键 |
| floorKey(K key) | K | 返回小于或等于给定键的最大键 |
| higherKey(K key) | K | 返回Map中位于key后一位的key值,如果该Map为空不存在这样的key则返回null |
| lowerKey(K key) | K | 返回Map中位于key前一位的key值,如果该Map为空不存在这样的key则返回null |
| containsKey(Object key) | boolean | 是否包含指定的key |
| containsValue(Object value) | boolean | 是否包含指定的value |
| headMap(K toKey) | SortedMap | 返回Map的子Map;其key范围是小于tokKey的所有key |
| headMap(K toKey,boolean inclusive) | NavigableMap | 返回Map的子Map;其key范围是小于tokKey的所有key(是否包括取决于第二个参数) |
| tailMap(K fromKey) | SortedMap | 返回Map的子Map;其key范围是大于等于fromKey的所有key |
| tailMap(K fromKey,boolean inclusive) | NavigableMap | 返回Map的子Map;其key范围是大于fromkKey的所有key(是否包括取决于第二个参数) |
| subMap(K fromKey,K toKey) | SortedMap | 返回Map的子Map;其key范围是fromKey(包括)到toKey(不包括) |
| subMap(K fromKey,boolean fromInclusive,K toKey,boolean toInclusive) | NavigableMap | 返回Map的子Map;其key范围是fromKey(是否包括取决于第二个参数)到toKey(是否包括取决于第四个参数) |
| size() | int | 获取映射的数量 |
| clear() | void | 清空映射 |
| clone() | Object | 浅复制 |
| comparator() | Comparator | 设置比较器 |
Properties类
Properties类是Hashtable类的子类,主要用于处理属性文件,将属性文件和Map对象关联起来,从而可以把Map对象中的key-value对写入属性文件中,也可以把属性文件中的"属性名=属性值"加载到Map对象中。由于属性文件里的属性名、属性值只能是字符串类型,所以Properties里的key、value都是字符串类型
| Properties构造方法 | 说明 |
|---|---|
| Properties() | 创建一个没有默认值的空属性列表 |
| Properties(Properties defaults) | 创建具有指定默认值的空属性列表 |
Properties 常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| getProperty(String key) | String | 获取Properties中指定属性名对应的属性值 |
| getProperty(String key,String defaultValue) | String | 如果Properties中不存在指定的key时,则该方法指定默认值 |
| setProperty(String key,String value) | Object | 设置键值对 |
| load(InputStream inStream) | void | 从输入字节流中读取属性列表(键和元素对),不能保证加载次序 |
| load(Reader reader) | void | 从输入字符流中以简单的面向行的格式读取属性列表(键和元素对),不能保证加载次序 |
| loadFromXML(InputStream in) | void | 将指定输入流上的 XML 文档表示的所有属性加载到此属性表中 |
| store(OutputStream out,String comments) | void | 将Properties中的键值对输出到指定的属性文件中(以输出流表示) |
| store(Writer writer,String comments) | void | 将Properties中的键值对输出到指定的属性文件中(以写入流表示) |
| storeToXML(OutputStream os,String comment) | void | 发出一个XML文档,表示该表中包含的所有属性 |
| storeToXML(OutputStream os,String comment,String encoding) | void | 使用指定的编码发出一个XML文档,表示该表中包含的所有属性 |
| list(PrintStream out) | void | 将此属性列表打印到指定的输出流 |
| list(PrintWriter out) | void | 将此属性列表打印到指定的输出流 |
| propertyNames() | Enumeration | 返回此属性列表中所有键的枚举 |
| stringPropertyNames() | Set | 返回此属性列表中的一组键,其中键及其对应的值是字符串 |
// 需求:使用Properties把键值对信息存入属性文件中
Properties prop1 = new Properties();
prop1.setProperty("admin", "root");
prop1.setProperty("password", "123456");
prop1.store(new FileWriter("D:/a.txt"), "备注信息");
// 需求:把Properties文件中的数据加载到内存中
Properties prop2 = new Properties();
prop2.load(new FileReader("D:/a.txt"));
Set keys = prop2.stringPropertyNames();
for (String key : keys) {
System.out.println(prop2.getProperty(key));
}
EnumMap类
EnumMap是一个与枚举类一起使用的Map实现,EnumMap中的所有key都必须是单个枚举类的枚举值。创建EnumMap是必须显式或隐式指定它对应的枚举类
- EnumMap在内部以数组形式保存
- EnumMap根据key的自然顺序(即枚举值在枚举类中的定义顺序)来维护键值对的顺序
- EnumMap不允许使用null作为key,但允许使用null作为value
enum Season {
SPRING, SUMMER, FALL, WINTER
}
public class Main {
public static void main(String[] args) {
EnumMap enums = new EnumMap(Season.class);
enums.put(Season.SUMMER, "夏日炎炎");
enums.put(Season.SPRING, "春暖花开");
System.out.println(enums); // {SPRING=春暖花开, SUMMER=夏日炎炎}
}
}
WeakHashMap类
WeakHashMap与HashMap用法基本类似,与HashMap的区别在于,HashMap的key保留了对实际对象的强引用,这意味着只要该HashMap对象不被销毁,该HashMap的所有key所引用的对象就不会被垃圾回收,HashMap也不会自动删除这些key所对应的key-value对;但WeakHashMap的key只保留了对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,WeakHashMap也可能自动删除这些key所对应的key-value对(WeakHashMap中每一个可以对象只持有对实际兑现的弱引用,因此当垃圾回收了该key所对应的实际对象之后,WeakHashMap会自动删除该key对应的key-value对)
WeakHashMap whm = new WeakHashMap();
whm.put(new String("语文"),new String("良好"));
whm.put(new String("数学"),new String("优秀"));
whm.put("Java",new String("及格"));
System.out.println(whm); // {Java=及格, 数学=优秀, 语文=良好}
System.gc();
System.runFinalization();
System.out.println(whm); // {Java=及格}
IdentityHashMap
| IdentityHashMap构造方法 | 说明 |
|---|---|
| IdentityHashMap() | |
| IdentityHashMap(int expectedMaxSize) | |
| IdentityHashMap(Map m) |
IdentityHashMap类常用方法
| 常用方法 | 返回值类型 | 说明 |
|---|---|---|
| clear() | void | |
| clone() | Object | |
| containsKey(Object key) | boolean | |
| containsValue(Object value) | boolean | |
| entrySet() | Set | |
| equals(Object o) | boolean | |
| forEach(BiConsumer action) | void | |
| get(Object key) | V | |
| hashCode() | int | |
| isEmpty() | boolean | |
| keySet() | Set | |
| put(K key,V value) | V | |
| putAll(Map m) | void | |
| remove(Object key) | V | |
| replaceAll(BiFunction function) | void | |
| size() | int | |
| values() | Collection |
Queue接口
Queue用于模拟队列这种数据结构,队列是指“先进先出”(FIFO)的容器。新元素插入(offer)到队列的尾部,访问元素(poll)会返回队列头部的元素
| Queue接口常用方法 | 返回值类型 | 说明 |
|---|---|---|
| add(E e) | boolean | 将指定元素添加到队列尾部 |
| element() | E | 获取队列头部的元素,但是不删除该元素 |
| offer(E e) | boolean | 将指定元素添加到队列尾部;当使用容量有限制的队列时,此方法比add方法更好用 |
| peek() | E | 获取队列头部的元素,但是不删除该元素;如果队列为空则返回null |
| poll() | E | 获取队列头部的元素,删除该元素;如果队列为空则返回null |
| remove() | E | 获取队列头部的元素,并删除该元素 |
Queue接口有一个PriorityQueue实现类。除此之外,Queue还有一个Deque接口,Deque代表一个“双端队列”,双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可以当成队列来使用,也可以当成栈来使用。Java为Deque提供了ArrayDeque和LinkedList两个实现类
队列可以让人们有效地在尾部添加一个元素,在头部删除一个元素。有两个端头的队列,即双端队列,可以让人们有效地在头部的尾部同时添加或删除元素。不支持在队列中间添加元素。在JDK6中引入了Deque接口,并由ArrayDeque和LinkedList类实现,这两个类都提供了双端队列,而且在必要时可以增加队列的长度