【笔记】Java核心技术卷1-第九章_集合

9.2 具体的集合

在这里插入图片描述

9.2.1 链表

LinkedList
链表与泛型集合之间有个重要区别。链表是一个有序集合,LinkedList.add方法将对象添加到链表的尾部。只有对自然有序的集合使用迭代器添加元素才有实际意义。例如,集(set) 类型,其中的元素完全无序。因此, 在 Iterator 接口中就没有 add 方法。相反地,集合类库提供了子接口 ListIterator, 其中包含 add 方法。
另外,LinkIterator有两个方法,可反向遍历链表。previous()和hasprevious()。

9.2.2 数组列表

ArrayList

9.2.3 散列集

HashSet
采用链表数组实现,每个列表称为桶。想要查找表中对象位置,就要计算它的散列码,然后与桶总数取余,得到的结果就是索引。

9.2.4 树集

TreeSet
有序集合,采用了红黑树排序。

9.2.5 队列与双端队列

有两个端头的队列, 即双端队列,可以让人们有效地在头部和尾部同时添加或删除元 素。不支持在队列中间添加元素。在 Java SE 6中引人了 Deque 接口,并由 ArrayDeque 和 LinkedList 类实现。这两个类都提供了双端队列,而且在必要时可以增加队列的长度。

9.2.6 优先级队列

PriorityQueue
优先级队列中元素按任意顺序插入,总是按排序的顺序检索。所以随时调用remove(),都是删除最小的元素;但优先级队列并没有对所有元素进行排序,而是采用了堆(heap),一个自我调整的二叉树,add和remove时最小元素移动到根。

9.3.1 基本映射操作

映射:用来存放键/值对。如果提供了键,就能找到值。

两个通用实现 HashMap和TreeMap
散列映射对键进行散列。
树映射用键的整体顺序对元素进行排序, 并将其组织成搜索树。
散列或比较函数只能作用于键。与键关联的值不能进行散列或比较。

9.3.2 更新映射项

正常情况下,可以得到与一个键关联的原值,完成更新,再放回更新后的值。不过,必须考虑一个特殊情况,即键第一次出现。下面来看 一个例子,使用一个映射统计一个单词在文件中出现的频度。看到一个单词(word) 时,我们将计数器增 1,如下所示:
counts.put(word, counts.get(word)+ 1) ;
这是可以的, 不过有一种情况除外:就是第一次看到 word时。在这种情况下,get 会返回 null, 因此会出现一个 NullPointerException 异常。
作为一个简单的补救, 可以使用 getOrDefault方法:
counts,put(word, counts.getOrDefault(word, 0)+ 1) ;
另一种方法是首先调用 putlfAbsent 方法。只有当键原先存在时才会放入一个值。

counts.putlfAbsent(word, 0) ; 
counts.put(word, counts.get(word)+ 1) ;// Now we know that get will succeed

9.3.3 映射视图

集合框架不认为映射本身是一个集合。
不过, 可以得到映射的视图(View)— —这是实现了 Collection 接口或某个子接口的对象。
有3种视图:
键集:Set<K> keySet()
值集合(不是一个集):Collection<V> values()
键/值对集:Set<Map.Entry<K, V>> entrySet()

9.3.4 弱散列映射

9.3.5 链接散列集与映射

LinkedHashSet 和 LinkedHashMap类用来记住插人元素项的顺序。这样就可以避免在散列表中的项从表面上看是随机排列的。当条目插入到表中时,就会并入到双向链表中。
链接散列映射将用访问顺序, 而不是插入顺序,对映射条目进行迭代。每次调用 get 或 put, 受到影响的条目将从当前的位置删除,并放到条目链表的尾部(只有条目在链表中的位置会受影响,而散列表中的桶不会受影响。一个条目总位于与键散列码对应的桶中)。要项构造这样一个的散列映射表,请调用
LinkedHashMap<K, V>(initialCapacity, loadFactor, true)

猜你喜欢

转载自blog.csdn.net/Ethan_997/article/details/108582196