转载

【吐血整理】Java Collections你必须知道的13件事情

你好,早上、中午、下午、晚上好。我是Java2B哥(微信搜Java2B)。一名无缘985,日常996工程师。

【吐血整理】Java Collections你必须知道的13件事情

今天2B哥和大家说说Java Collections 相关的知识点,这几个点大家是一定要会哦~~~因为 Java Collections Framework是Java编程语言的核心部分之一。集合几乎用于每种编程语言中。大多数编程语言都支持各种类型的集合,例如列表,集合,队列,堆栈等。我们应该如何去了解了?来看下文

1.什么是Java Collections Framework?

集合就像容器一样,将多个项目组合在一个单元中。例如,一罐巧克力,名称列表等。

每种编程语言都使用了Collections,当Java出现时,它也带有一些Collection类-Vector,Stack,Hashtable和Array。

Java 1.2提供了Collections Framework,这是一种以标准方式表示和操纵Java中Collections的体系结构。Java Collections Framework由以下部分组成:

接口:Java Collections Framework接口提供抽象数据类型来表示集合。java.util.Collection是Collections Framework的根接口。它在Collections框架层次结构的顶部。它包含诸如一些重要的方法size(),iterator(),add(),remove(),clear(),每一个集合类必须实现。 其他一些重要的接口是java.util.List,java.util.Set,java.util.Queue和java.util.Map。

Map是唯一一个不从Collection接口继承的接口,但它是Collections框架的一部分。所有集合框架接口都存在于java.util包中。

实现类:Java Collections框架提供了集合的核心实现类。我们可以使用它们在java程序中创建不同类型的集合。 一些重要的集合类是ArrayList,LinkedList,HashMap,TreeMap,HashSet,TreeSet。

这些类满足了我们大多数的编程需求,但是如果我们需要一些特殊的集合类,我们可以扩展它们以创建我们的自定义集合类。

Java 1.5提供了线程安全的集合类,该类允许在迭代它的同时修改Collections。其中有些是CopyOnWriteArrayList,ConcurrentHashMap,CopyOnWriteArraySet。

这些类位于java.util.concurrent包中。所有集合类都存在于java.util和java.util.concurrent包中。

算法:算法是提供一些常用功能的有用方法,例如搜索,排序和改组。 下面的类图显示了Collections Framework层次结构。为简单起见,我仅包括常用的接口和类。

Java中的集合,java Collections Framework

2. Java Collections Framework的好处

Java Collections框架具有以下优点:

减少的开发工作量 –几乎所有常见类型的集合都附带了它,并提供有用的方法来迭代和处理数据。因此,我们可以将更多精力放在业务逻辑上,而不是设计集合API。 提高质量 –使用经过良好测试的核心集合类可以提高我们的程序质量,而不是使用任何自行开发的数据结构。 可重用性和互操作性 减少工作量 –如果我们使用核心集合API类,则可以学习任何新的API。

3. Java Collections接口

Java集合接口是Java集合框架的基础。请注意,所有核心集合接口都是通用的。例如public interface Collection。语法适用于泛型,当我们声明Collection时,应该使用它来指定它可以包含的Object的类型。通过在编译时对对象进行类型检查,它有助于减少运行时错误。

为了使核心集合接口的数量易于管理,Java平台没有为每种集合类型的每个变体提供单独的接口。如果调用了不受支持的操作,则收集实现将引发UnsupportedOperationException。

3.1)Collection Interface接口

这是集合层次结构的根。集合表示一组称为其元素的对象。Java平台不提供此接口的任何直接实现。

该接口有方法来告诉你有多少元素集合中(size,isEmpty),检查给定对象是否是集合(中contains),添加和从集合中删除元素(add,remove),并在提供的迭代器集合(iterator)。

Collection接口还提供批量操作方法,关于整个征集工作- ,containsAll,addAll,removeAll,。retainAllclear

toArray提供这些方法作为集合与期望输入上有数组的旧API之间的桥梁。

3.2)Iterator Interface迭代器接口

迭代器接口提供了对任何Collection进行迭代的方法。我们可以使用iterator方法从Collection中获取迭代器实例。Enumeration在Java Collections Framework中,Iterator代替了。迭代器允许调用者在迭代过程中从基础集合中删除元素。集合类中的迭代器实现“ 迭代器设计模式”。

3.3) Set Interface Set接口

Set是一个不能包含重复元素的集合。此接口对数学集合的抽象进行建模,并用于表示集合,例如纸牌组。

Java平台包含三个通用Set实现:HashSet,TreeSet,和LinkedHashSet。Set接口不允许随机访问Collection中的元素。您可以使用迭代器或foreach循环遍历Set的元素。

3.4) ListInterface列表接口

List是一个有序的集合,可以包含重复的元素。您可以从其索引访问任何元素。列表更像是具有动态长度的数组。列表是最常用的集合类型之一。ArrayList并且LinkedList是List接口的实现类。

列表接口提供了有用的方法,可以在特定索引处添加元素,基于索引移除/替换元素以及使用索引获取子列表。

List strList = new ArrayList<>();

//add at last
strList.add(0, "0");

//add at specified index
strList.add(1, "1");

//replace
strList.set(1, "2");

//remove
strList.remove("1");
复制代码

Collections类提供了列表一些有用的算法- ,sort,,shuffle 等。reversebinarySearch

3.5)Queue Interface队列接口

队列是用于在处理之前保存多个元素的集合。除了基本的收集操作外,队列还提供其他插入,提取和检查操作。

队列通常但不一定以FIFO(先进先出)的方式对元素进行排序。优先队列除外,它们根据提供的比较器或元素的自然顺序对元素进行排序。无论使用哪种顺序,队列的开头都是将通过调用remove或poll删除的元素。在FIFO队列中,所有新元素都插入队列的尾部。

3.6)Dequeue Interface出队接口

支持在两端插入和删除元素的线性集合。deque这个名称是“双端队列”的缩写,通常发音为“ deck”。大多数Deque实现对它们可能包含的元素数量没有固定的限制,但是此接口支持容量受限的双端队列以及没有固定大小限制的双端队列。

此接口定义访问双端队列两端的元素的方法。提供了用于插入,删除和检查元素的方法。

3.7)Map Interface接口

Java Map是一个将键映射到值的对象。映射不能包含重复的键:每个键最多可以映射到一个值。

Java平台包含三个通用Map实现:HashMap,TreeMap,和LinkedHashMap。

地图的基本操作是put,get,containsKey,containsValue,size,和isEmpty。

3.8)ListIterator接口

列表的迭代器,允许程序员在任一方向上遍历列表,在迭代过程中修改列表,并获取迭代器在列表中的当前位置。

Java ListIterator没有当前元素;它的光标位置始终位于通过调用previous()返回的元素和通过调用next()返回的元素之间。

3.9)SortedSet接口

SortedSet是一个Set,它按升序维护其元素。提供了一些其他操作以利用订购的优势。排序的集合用于自然排序的集合,例如单词列表和成员资格列表。

3.10)SortedMap接口

以升序顺序维护其映射的Map。这是SortedSet的Map模拟。排序后的地图用于键/值对的自然排序集合,例如字典和电话簿。

4. Java集合类

Java Collections框架带有许多接口实现类。最常见的实现是ArrayList,HashMap和HashSet。Java 1.5包含并发实现;例如ConcurrentHashMap和CopyOnWriteArrayList。通常,Collection类不是线程安全的,并且其迭代器是快速失败的。在本节中,我们将学习常用的收集类。

4.1)HashSet类

Java HashSet是由HashMap支持的Set接口的基本实现。它不保证集合的迭代顺序,并允许使用null元素。

基本操作(这个类提供了固定的时间性能add,remove,contains和size),假定哈希函数将分散的元素正确的桶中。我们可以为此集合设置初始容量和负载因子。负载因子是散列映射被允许在自动增加其容量之前获得的填充程度的度量。

4.2)TreeSet类

NavigableSet基于的实现TreeMap。元素使用其自然顺序进行排序,或者通过Comparator在设置创建时提供的元素进行排序,具体取决于所使用的构造函数。

参考:Java可比比较器

此实现为基本操作(添加,删除和包含)提供了保证的log(n)时间成本。

请注意,如果要正确实现Set接口,则由集合(无论是否提供显式比较器)维护的顺序必须等于equals。(有关与equals一致的精确定义,请参见Comparable或Comparator。)之所以这样,是因为Set接口是根据equals操作定义的,但是TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此两个从集合的角度来看,此方法认为相等的元素是相等的。

4.3)ArrayList类

Java ArrayList是List接口的可调整大小的数组实现。实现所有可选的列表操作,并允许所有元素,包括null。除了实现List接口之外,此类还提供一些方法来操纵内部用于存储列表的数组的大小。(此类与Vector大致等效,但它是不同步的。)

size isEmpty,get,set,iterator和list迭代器操作在恒定时间内运行。加法运算以固定的固定时间运行,也就是说,添加n个元素需要O(n)时间。所有其他操作均以线性时间运行(大致而言)。与LinkedList实现相比,常数因子较低。

进一步阅读:Java ArrayList和Iterator

4.4)LinkedList类

List和Deque接口的双链接列表实现。实现所有可选的列表操作,并允许所有元素(包括null)。

所有操作均按双链表的预期执行。索引到列表中的操作将从开头或结尾遍历列表,以更接近指定索引的位置为准。

4.5)HashMap类

基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许空值和空键。HashMap类与Hashtable大致等效,但它是不同步的,并且允许为null。此类无法保证地图的顺序。

此实现为基本操作(get和put)提供了恒定时间的性能。它为构造函数提供了设置集合的初始容量和负载因子的功能。

进一步阅读:HashMap与ConcurrentHashMap

4.6)TreeMap类

基于红黑树的NavigableMap实现。根据映射键的自然顺序或在映射创建时提供的Comparator对映射进行排序,具体取决于所使用的构造函数。

此实现为containsKey,get,put和remove操作提供了保证的log(n)时间成本。算法是对Cormen,Leiserson和Rivest的“算法简介”中的算法的改编。

请注意,TreeMap维护的排序(与任何排序的映射一样)以及是否提供显式比较器必须与equals一致,以便此排序的映射正确实现Map接口。(有关与equals一致的精确定义,请参见Comparable或Comparator。)之所以这样,是因为Map接口是根据equals操作定义的,但是排序后的map使用其compareTo(或compare)方法执行所有键比较,因此两个从已排序映射的角度来看,此方法认为相等的键是相等的。排序后的映射的行为是明确定义的,即使其排序与equals不一致也是如此;它只是不遵守Map接口的一般约定。

4.7)PriorityQueue类

队列按FIFO顺序处理其元素,但有时我们希望根据元素的优先级对其进行处理。在这种情况下,我们可以使用PriorityQueue,并且在实例化PriorityQueue时需要提供Comparator实现。PriorityQueue不允许空值,并且它是无界的。有关此的更多详细信息,请转到Java Priority Queue,您可以在其中通过示例程序检查其使用情况。

5.Collections class

Java Collections类仅由对集合进行操作或返回集合的静态方法组成。它包含对集合进行操作的多态算法,“包装器”(包装器),这些包装器返回由指定集合支持的新集合,以及其他一些零碎的结局。

此类包含用于集合框架算法的方法,例如二进制搜索,排序,改组,反向等。

6.Synchronized Wrappers同步包装

同步包装器将自动同步(线程安全)添加到任意集合。六个核心集合接口(集合,集合,列表,地图,SortedSet和SortedMap)中的每个都有一个静态工厂方法。

public static Collection synchronizedCollection(Collection c); public static Set synchronizedSet(Set s); public static List synchronizedList(List list); public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m); public static SortedSet synchronizedSortedSet(SortedSet s); public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m); 这些方法中的每一个都返回一个由指定集合备份的同步(线程安全)集合。

7.Unmodifiable wrappers不可修改的包装器

不可修改的包装器通过拦截所有会修改集合并抛出的操作,从而丧失了修改集合的能力UnsupportedOperationException。它的主要用途是;

使集合一旦建立便不可变。在这种情况下,最好不要保留对后备集合的引用。这绝对保证了不变性。 允许某些客户端以只读方式访问您的数据结构。您保留对后备集合的引用,但分发对包装器的引用。这样,在您保持完全访问权限的同时,客户端可以查看但不能修改。 这些方法是:

public static Collection unmodifiableCollection(Collection<? extends T> c); public static Set unmodifiableSet(Set<? extends T> s); public static List unmodifiableList(List<? extends T> list); public static <K,V> Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m); public static SortedSet unmodifiableSortedSet(SortedSet<? extends T> s); public static <K,V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K, ? extends V> m);

8.线程安全集合

Java 1.5并发包(java.util.concurrent)包含线程安全的集合类,这些类允许在迭代时修改集合。通过设计迭代器是快速失败的,并抛出ConcurrentModificationException。有些班是CopyOnWriteArrayList,ConcurrentHashMap,CopyOnWriteArraySet。

阅读这些帖子以更详细地了解它们。

避免ConcurrentModificationException CopyOnWriteArrayList示例 HashMap与ConcurrentHashMap

9.集合API算法

Java Collections Framework提供了常用的算法实现,例如排序和搜索。集合类包含这些方法实现。这些算法大多数都可以在List上使用,但是其中一些算法适用于所有类型的集合。

9.1)排序

排序算法对List进行重新排序,以便其元素根据排序关系以升序排列。提供了两种形式的操作。简单形式采用一个List,并根据其元素的自然顺序对其进行排序。排序的第二种形式除列表外还包含一个Comparator,并使用Comparator对元素进行排序。

9.2)改组

随机播放算法会破坏列表中可能存在的任何顺序跟踪。即,该算法基于来自随机性源的输入对List进行重新排序,从而假定合理的随机性源,所有可能的排列均以相同的可能性发生。该算法在实施机会游戏中很有用。

9.3)搜索

binarySearch算法在排序列表中搜索指定的元素。该算法有两种形式。第一个带有一个List和一个要搜索的元素(“搜索关键字”)。

此格式假定列表根据其元素的自然顺序以升序排序。

第二种形式除列表和搜索键外还采用比较器,并假定根据指定的比较器将列表按升序排序。

排序算法可用于在调用binarySearch之前对List进行排序。

9.4)组成

频率算法和不相交算法测试一个或多个集合的组成的某些方面。

频率:计算指定元素在指定集合中出现的次数 不相交:确定两个集合是否不相交;也就是说,它们是否不包含共同点

9.5)最小值和最大值

最小和最大算法分别返回指定Collection中包含的最小和最大元素。这两种操作都有两种形式。简单形式仅采用Collection并根据元素的自然顺序返回最小(或最大)元素。 第二种形式除了Collection之外还采用Comparator,并根据指定的Comparator返回最小(或最大)元素。

10. Java 8 Collections API功能

Java 8的最大变化与Collection API有关。一些重要的更改和改进是:

有关用于顺序处理和并行处理的Stream API的介绍,您应该阅读Java Stream API Tutorial以获得更多详细信息。 可迭代接口已使用forEach()默认方法扩展,可用于遍历集合。 Lambda表达式和功能性接口最适合Collection API类。

. Java 10 Collections API的更改

List.copyOf,Set.copyOf和Map.copyOf方法,以创建不可修改的集合。 Collectors类获得各种方法来收集不可修改的集合(Set,List,Map)。这些方法名称为toUnmodifiableList,toUnmodifiableSet和toUnmodifiableMap。 让我们看一下这些新的Java 10 Collections API方法用法的示例。

package com.java2b.collections;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class JDK10CollectionFunctions {

	public static void main(String[] args) {

		// 1. List, Set, Map copyOf(Collection) method
		List<String> actors = new ArrayList<>();

		actors.add("Java2B哥");
		actors.add("Marlon Brando");

		System.out.println(actors);
		// prints [Jack Nicholson, Marlon Brando]

		// New API added - Creates an UnModifiable List from a List.
		List<String> copyOfActors = List.copyOf(actors);

		System.out.println(copyOfActors);
		// prints [Jack Nicholson, Marlon Brando]

		// copyOfActors.add("Robert De Niro"); Will generate
		// UnsupportedOperationException

		actors.add("Robert De Niro");

		System.out.println(actors);
		// prints [Jack Nicholson, Marlon Brando, Robert De Niro]

		System.out.println(copyOfActors);
		// prints [Jack Nicholson, Marlon Brando]

		// 2. Collectors class toUnmodifiableList, toUnmodifiableSet, and
		// toUnmodifiableMap methods
		List<String> collect = actors.stream().collect(Collectors.toUnmodifiableList());
		System.out.println(collect);
	}

}
复制代码
  1. Java 11 Collections API的更改 toArray(IntFunction<T[]> generator)Collection界面中添加了一个新的默认方法。此方法使用提供的生成器函数分配返回的数组,该数组返回包含此集合中所有元素的数组。
package com.Java2b.collections;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class JDK11CollectionFunctions {

	public static void main(String[] args) {

		/*
		 * JDK 11 New Method in Collection interface 
		 * default <T> T[] toArray(IntFunction<T[]> generator) {
		 * return toArray(generator.apply(0)); }
		 */

		List<String> strList = new ArrayList<>();
		strList.add("Java");
		strList.add("Python");
		strList.add("Android");

		String[] strArray = strList.toArray(size -> new String[size]);
		System.out.println(Arrays.toString(strArray));

		strArray = strList.toArray(size -> new String[size + 5]);
		System.out.println(Arrays.toString(strArray));

		strArray = strList.toArray(size -> new String[size * 3]);
		System.out.println(Arrays.toString(strArray));
	}

}
复制代码

输出:

[Java, Python, Android] [Java, Python, Android, null, null] [Java, Python, Android]

原文  https://juejin.im/post/5e1d89cd6fb9a02fb85ae10b
正文到此结束
Loading...