集合基本概念
-
集合(Collection)
一个包含元素的序列,其中元素都遵循一条或多条规则。
- List 必须以插入的顺序保存元素
- Set 不能包含重复元素
- Queue 按照排队规则来确定对象产生的顺序
-
映射(Map) : 一组成对的“键值对”对象,使用键来查找值。
又称为字典(dictionary),因为可以使用一个键对象来查找值对象,就像在字典中使用单词查找定义一样。
列表List
List 接口在 Collection 的基础上添加了许多方法,允许在 List 的中间插入和删除元素。也就是有索引的一些操作。
Lists 是存储和检索对象(次于数组)的最基本方法,基本操作包括:
add()
用于插入元素get()
用于随机访问元素iterator()
获取序列上的一个 Iteratorstream()
生成元素的一个 Stream
常用的 List 类型有两种:
-
ArrayList
随机访问的速度快,但是插入和删除元素的速度慢。这是由于
ArrayList
,底层是用数组来实现的。 -
LinkedList
插入与删除的效率高,随机访问的效率低。这是由于
LinkedList
底层是链表实现的。
对于 LinkedList ,在列表中间插入和删除效率高,但对于 ArrayList ,效率低。这意味着,只要将涉及到插入与删除的操作,我们都应该选择LinkedList 吗?
不是。它只是意味着,我们应该意识到这个问题。如果我们的程序,某个 ArrayList 相关的代码,执行速度变慢,那么我们可以排查一下,是否有这个原因。
迭代器Iterators
Java 5中,引入了Iterable
。
Collection 是所有序列集合共有的根接口,Collection
继承了Iterable
,所以所有Collenction
的字类,都能使用迭代器。for-in语法,底层也是使用迭代器实现。
迭代器是个很抽象的东西,它可以忽略集合基层实现,来遍历集合。它在一个序列中移动并选择该序列中的每个对象。
Java的迭代器功能只有四个:
iterator()
获取一个迭代器。 Iterator 已经准备好返回序列中的第一个元素。next()
获取序列的下一个元素hasNext()
是否还有下一个元素remove()
移除当前的元素。调用remove()
之前必须先调用next()
集合Set
Set 不保存重复的元素。 Set的接口与 Collection 完全相同。
Set常用实现:
-
HashSet
无序。早期所有都是无序,现在Integer会按顺序排列。
针对快速查找,进行了优化。
-
TreeMap
有序。默认数字,字母顺序。可以传入Comparator比较器。
-
LinkedHashSet
有序。插入顺序。
映射Map
Map(也称为 关联数组 )维护键值关联(对)。key-value形式。
Map 实现 | 描述 |
---|---|
HashMap* | 基于哈希表的实现。(使用此类来代替 Hashtable 。)为插入和定位键值对提供了常数时间性能。可以通过构造方法调整性能,这些构造方法允许你设置哈希表的容量和装填因子。 |
LinkedHashMap | 与 HashMap 类似,但是当遍历时,可以按插入顺序或最近最少使用(LRU)顺序获取键值对。只比 HashMap 略慢,一个例外是在迭代时,由于其使用链表维护内部顺序,所以会更快些。 |
TreeMap | 基于红黑树的实现。当查看键或键值对时,它们按排序顺序(由 Comparable 或 Comparator 确定)。 TreeMap 的侧重点是按排序顺序获得结果。 TreeMap 是唯一使用 subMap() 方法的 Map ,它返回红黑树的一部分。 |
WeakHashMap | 一种具有 弱键(weak keys) 的 Map ,为了解决某些类型的问题,它允许释放 Map 所引用的对象。如果在 Map 外没有对特定键的引用,则可以对该键进行垃圾回收。 |
ConcurrentHashMap | 不使用同步锁定的线程安全 Map 。 |
IdentityHashMap | 使用 == 而不是 equals() 来比较键(key)。仅用于解决特殊问题,不适用于一般用途。 |
-
HashMap
基于哈希表的实现。哈希码是一种从相关对象中获取一些信息并将其转换为该对象的“相对唯一” int 的方法。
-
SortedMap
这是一个接口,实现类:
TreeMap
、ConcurrentSkipListMap
。key 按照指定顺序排列。 -
LinkedHashMap
有序。此外,可以在构造方法中,配置使用最近最少使用(
LRU
)算法。配置后,符合算法的元素,将排在前面。linkedMap = new LinkedHashMap<>(16, 0.75f, true);
通过流操作Map:
MAP.entrySet().stream()
.map(Map.Entry::getValue)
.filter(v -> v.startsWith("Dark"))
.map(v -> v.replaceFirst("Dark", "Hot"))
.forEach(System.out::println);
附图:
黄色为接口,绿色为抽象类,蓝色为具体类。