Java中的集合几乎用于每个应用程序。Java Collections Framework是Java编程语言的核心部分之一。Java Collections教程将详细介绍Java Collections Framework。
集合就像是将多个项目组合在一个单元中的容器。例如; 一罐巧克力,名单等。几乎每种编程语言都使用集合,当Java到达时,它也带有少量的Collection类; 矢量,堆栈,哈希表,数组。Java 1.2提供了Collections Framework,它是以标准方式表示和操作java中的集合的体系结构。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
包中。ArrayList
,LinkedList
,HashMap
,TreeMap
,HashSet
,TreeSet
。这些类解决我们大部分的编程需求,但如果我们需要一些特殊的集合类,我们可以扩展它们来创建我们的自定义集合类。 Java 1.5中想出了允许修改集合在遍历它,他们中的一些是线程安全的集合类CopyOnWriteArrayList
,ConcurrentHashMap
,CopyOnWriteArraySet
。这些类位于java.util.concurrent包中。所有集合类存在于java.util
和java.util.concurrent
包。
下面的类图显示了Collections Framework层次结构。为简单起见,我只包括常用的接口和类。
Java Collections框架具有以下优点:
Java集合接口是Java Collections Framework的基础。请注意,所有核心集合接口都是通用的; 例如public interface Collection<E>
。<E>语法用于泛型,当我们声明Collection时,我们应该使用它来指定它可以包含的Object的类型。它通过在编译时对对象进行类型检查来帮助减少运行时错误。
为了保持核心集合接口的数量可管理,Java平台不为每个集合类型的每个变体提供单独的接口。如果调用了不受支持的操作,则集合实现会抛出一个UnsupportedOperationException
。
这是集合层次结构的根。集合表示一组称为其元素的对象。Java平台不提供此接口的任何直接实现。
接口有方法告诉你集合中有多少元素(size
,isEmpty
),以检查给定对象是否在collection(contains
)中,从集合中添加和删除元素(add
,remove
),并提供迭代器集合(iterator
)。
Collection接口还提供了对整个收集工作批量操作方法- ,containsAll
,addAll
,removeAll
,。retainAll
clear
这些toArray
方法是作为集合和旧API之间的桥梁提供的,这些API期望输入数组。
Iterator接口提供迭代任何Collection的方法。我们可以使用iterator
方法从Collection中获取iterator实例。Iterator取代了Enumeration
Java Collections Framework。迭代器允许调用者在迭代期间从底层集合中删除元素。集合类中的迭代器实现了迭代器设计模式。
Set是一个不能包含重复元素的集合。该界面对数学集抽象进行建模,并用于表示集合,例如卡片组。
Java平台包含三个通用Set实现:HashSet
,TreeSet
,和LinkedHashSet
。Set接口不允许随机访问Collection中的元素。您可以使用迭代器或foreach循环遍历Set的元素。
List是有序集合,可以包含重复元素。您可以从其索引中访问任何元素。List更像是具有动态长度的数组。List是最常用的Collection类型之一。ArrayList
并且LinkedList
是List接口的实现类。
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");
-集合类列表提供了一些有用的算法sort
,shuffle
,reverse
,binarySearch
等。
队列是用于在处理之前保存多个元素的集合。除了基本的Collection操作外,Queue还提供额外的插入,提取和检查操作。
队列通常(但不一定)以FIFO(先进先出)方式对元素进行排序。除了优先级队列之外,优先级队列根据提供的比较器或元素的自然顺序对元素进行排序。无论使用什么顺序,队列的头部是通过调用删除或轮询删除的元素。在FIFO队列中,所有新元素都插入队列的尾部。
线性集合,支持两端插入和移除元素。名称deque是“双端队列”的缩写,通常发音为“deck”。大多数Deque实现对它们可能包含的元素数量没有固定限制,但是此接口支持容量限制的deques以及没有固定大小限制的deques。
此接口定义了访问双端队列两端元素的方法。提供了插入,移除和检查元素的方法。
Java Map是将键映射到值的对象。地图不能包含重复键:每个键最多可映射一个值。
Java平台包含三个通用Map实现:HashMap
,TreeMap
,和LinkedHashMap
。
地图的基本操作是put
,get
,containsKey
,containsValue
,size
,和isEmpty
。
列表的迭代器,允许程序员在任一方向上遍历列表,在迭代期间修改列表,并获取迭代器在列表中的当前位置。
Java ListIterator没有当前元素; 它的光标位置总是位于调用previous()返回的元素和调用next()返回的元素之间。
SortedSet是一个按升序维护其元素的Set。提供了几个额外的操作以利用订购。排序集用于自然排序的集合,例如单词列表和成员资格卷。
以升序键顺序维护其映射的映射。这是SortedSet的Map模拟。排序映射用于自然排序的键/值对集合,例如字典和电话目录。
Java Collections框架附带了许多接口实现类。最常见的实现是ArrayList,HashMap和HashSet。Java 1.5包括并发实现; 例如ConcurrentHashMap和CopyOnWriteArrayList。通常,Collection类不是线程安全的,它们的迭代器是快速失败的。在本节中,我们将了解常用的集合类。
Java HashSet是由HashMap支持的Set接口的基本实现。它不保证集合的迭代顺序并允许null元素。
这个类提供了固定的时间表现为基本操作(add
,remove
,contains
和size
),假定哈希函数将分散的桶中正确的元素。我们可以为此集合设置初始容量和负载因子。负载因子是在其容量自动增加之前允许哈希映射获得的完整程度的度量。
NavigableSet
基于a 的实现TreeMap
。元素按照它们的自然顺序排序,或者根据Comparator
设置的创建时间提供,具体取决于使用的构造函数。
此实现为基本操作(添加,删除和包含)提供了有保证的log(n)时间成本。
请注意,如果要正确实现Set接口,则由set维护的排序(无论是否提供显式比较器)必须与equals一致。(有关与equals一致的精确定义,请参阅Comparable或Comparator。)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用compareTo(或compare)方法执行所有元素比较,因此从集合的角度来看,通过这种方法被认为相等的元素是相等的。
Java ArrayList是List接口的可调整大小的数组实现。实现所有可选列表操作,并允许所有元素,包括null。除了实现List接口之外,此类还提供了一些方法来操作内部用于存储列表的数组的大小。(这个类大致相当于Vector,除了它是不同步的。)
size,isEmpty,get,set,iterator和listIterator操作以恒定时间运行。添加操作以分摊的常量时间运行,即添加n个元素需要O(n)时间。所有其他操作都以线性时间运行(粗略地说)。与LinkedList实现相比,常数因子较低。
进一步阅读:Java ArrayList和Iterator
List和Deque接口的双链表实现。实现所有可选列表操作,并允许所有元素(包括null)。
对于双向链表,所有操作都可以预期。索引到列表中的操作将从开头或结尾遍历列表,以较接近指定索引为准。
基于哈希表的Map接口实现。此实现提供所有可选的映射操作,并允许空值和空键。HashMap类大致相当于Hashtable,除了它是不同步的并允许null。此类不保证地图的顺序。
此实现为基本操作(get
和put
)提供了恒定时间性能。它提供构造函数来设置集合的初始容量和负载因子。
进一步阅读:HashMap vs ConcurrentHashMap
基于红黑树的NavigableMap实现。地图根据其键的自然顺序进行排序,或者根据使用的构造函数在地图创建时提供的比较器进行排序。
此实现为containsKey,get,put和remove操作提供有保证的log(n)时间成本。算法是Cormen,Leiserson和Rivest的算法导论中的算法的改编。
请注意,如果此有序映射要正确实现Map接口,则TreeMap维护的排序(如任何有序映射,以及是否提供显式比较器)必须与equals一致。(有关与equals一致的精确定义,请参见Comparable或Comparator。)这是因为Map接口是根据equals操作定义的,但是有序映射使用compareTo(或compare)方法执行所有键比较,因此从排序映射的角度来看,通过此方法被视为相等的键是相等的。即使排序与equals不一致,也可以很好地定义有序映射的行为。它只是不遵守Map接口的一般合同。
队列按FIFO顺序处理它的元素,但有时我们希望根据优先级处理元素。在这种情况下我们可以使用PriorityQueue,我们需要在实例化PriorityQueue时提供Comparator实现。PriorityQueue不允许空值,并且它是无限制的。有关这方面的更多详细信息,请转到Java Priority Queue,您可以使用示例程序检查它的使用情况。
Java Collections类仅包含对集合进行操作或返回集合的静态方法。它包含对集合进行操作的多态算法,“包装器”,它返回由指定集合支持的新集合,以及其他一些可能的结果。
此类包含用于集合框架算法的方法,例如二进制搜索,排序,重排,反向等。
同步包装器将自动同步(线程安全性)添加到任意集合。六个核心集合接口(Collection,Set,List,Map,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);
这些方法中的每一个都返回由指定集合备份的同步(线程安全)Collection。
不可修改的包装器通过拦截将修改集合并抛出的所有操作来消除修改集合的能力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);
Java 1.5 Concurrent package(java.util.concurrent
)包含线程安全的集合类,允许在迭代时修改集合。通过设计迭代器是快速失败并抛出ConcurrentModificationException。有些班是CopyOnWriteArrayList
,ConcurrentHashMap
,CopyOnWriteArraySet
。
阅读这些帖子以更详细地了解它们。
Java Collections Framework提供常用的算法实现,例如排序和搜索。Collections类包含这些方法实现。大多数这些算法都在List上工作,但其中一些算法适用于各种集合。
排序算法重新排序List,以便其元素根据排序关系按升序排列。提供了两种形式的操作。简单形式采用List并根据其元素的自然顺序对其进行排序。排序的第二种形式除了List之外还使用Comparator并使用Comparator对元素进行排序。
随机播放算法会破坏列表中可能存在的任何顺序跟踪。也就是说,该算法基于来自随机源的输入重新排序列表,使得假设公平的随机源,所有可能的排列以相等的可能性发生。该算法在实现机会游戏时很有用。
binarySearch算法搜索已排序List中的指定元素。该算法有两种形式。第一个采用List和要搜索的元素(“搜索关键字”)。此表单假定List按照其元素的自然顺序按升序排序。除了List和搜索键之外,第二种形式还使用Comparator,并假定List按照指定的Comparator按升序排序。排序算法可用于在调用binarySearch之前对List进行排序。
频率和不相交算法测试一个或多个集合的组成的某些方面。
min和max算法分别返回指定Collection中包含的最小和最大元素。这两种操作都有两种形式。简单形式只接受一个Collection,并根据元素的自然顺序返回最小(或最大)元素。
第二种形式除了Collection之外还带有一个Comparator,并根据指定的Comparator返回最小(或最大)元素。
Java 8最大的变化与Collection API有关。一些重要的变化和改进是:
让我们看一下这些新的Java 10 Collections API方法用法的示例。
package com.journaldev.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("Jack Nicholson"); 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); } }
toArray(IntFunction<T[]> generator)
Collection接口中添加了一个新的默认方法。此方法返回一个包含此集合中所有元素的数组,使用提供的生成器函数来分配返回的数组。
package com.journaldev.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]
下表提供了常用集合类的基本细节。
下载URL:Java集合类
采集 | 订购 | 随机访问 | 核心价值 | 重复元素 | 空元素 | 线程安全 |
---|---|---|---|---|---|---|
数组列表 | ||||||
链表 | ||||||
HashSet的 | ||||||
TreeSet中 | ||||||
HashMap中 | ||||||
TreeMap的 | ||||||
向量 | ||||||
哈希表 | ||||||
属性 | ||||||
堆 | ||||||
的CopyOnWriteArrayList | ||||||
的ConcurrentHashMap | ||||||
CopyOnWriteArraySet |