17 容器深入研究

本文深入探讨Java容器,包括完整的分类、Collection功能、Set的存储顺序、SortedSet特性和使用,队列、Map的理解,尤其是HashMap、TreeMap与LinkedHashMap的区别,以及如何覆盖hashCode()方法。此外,还介绍了List的选择策略和实用的Collections工具类方法。
摘要由CSDN通过智能技术生成

17 容器深入研究

17.1 完整的容器分类法

这里写图片描述

java SE5 新添加了
1. Queue接口,LinkedList已经为实现该接口做了修改,及其实现PriorityQueue和各种风格的BlockingQueue。
2. ConcurrentMap接口和其实现ConcurrentHashMap,它们也是用于多线程机制的。
3. CopyOnWriteArrayList和CopyOnWriteArraySet
4. EnumSet和EnumMap

17.3 Collection的功能方法

下面列出可以通过Collection执行的所有操作,不包括从Object继承来的方法。
因此,它们也可以通过Set和List执行所有的操作(List还有额外的功能),Map不是继承自Collection的,所以会另行介绍。

boolean add(T)

boolean addAll(Collection<? extends T>)
void clear()
boolean contains(T)
Boolean containsAll(Collection<?>)

boolean isEmpty()
Iterator<T> iterator()

Boolean remove(Object)

Boolean retainAll(Collection<?>)  //只保留参数中的元素,求交集

int size()

Object[] toArray()

17.6 Set和存储顺序

Set (interface) 存入Set的每个元素必须是唯一的,Set使用equals()方法确保对象的唯一性。Set和Collection具有完全一样的接口。

HashSet * 为快速查找而设计的Set。存入HashSet的元素必须定义hashCode()

TreeSet 保持次序的Set,底层为数结构。使用它可以从Set中提取有序的序列。元素必须实现Comparable接口。

LinkedHashSet 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果按元素插入的次序显示。元素也必须定义hashcode()方法。

*指如果没有其他限制,HashSet应该是你的默认选择。因为它对速度进行了优化。

你必须为散列存储和树型存储都创建一个equals()方法,但hashCode()只有在这个类被置于HashSet或者LinkedHashSet时才是必须的。但是,对于良好的编程风格而言,你应该在覆盖equals方法的同时总是覆盖hashCode方法。

17.6.1 SortedSet

SortedSet中的元素可以保证处于排序状态。

Comparator comparator()方法返回当前Set使用的Comparator,或者null,表示以自然方式排序。

Object first()

Object last()

SortedSet subSet(formElement,toElement) 生成子集,范围包含fromElement,不包含toElement

SortedSet headSet(toElement)

SortedSet tailSet(fromElement)

17.3 队列

Queue在java SE5中仅有两个实现 LinkedList和PriorityQueue,他们的差异在于排序行为而不是性能。

17.8 理解Map

标准java类库中包含了Map的几种基本实现,包括:
HashMap,TreeMap,LinkedHashMap,WeakHashMap,ConcurrentHashMap,IdentityHashMap

对Map中使用键的要求和对Set中元素的要求一样,任何键都必须有一个equals方法,如果键被用于散列Map,它还必须具有恰当的hashCode方法;如果键被用于TreeMap,它还必须实现Comparable。

17.8.2 SortedMap

TreeMap是现阶段其唯一实现,可以确保键处于排序状态。

17.8.2 LinkedHashMap

为了提高速度,LinkedHashMap散列化所有元素,但在遍历键值对时,却又以插入顺序返回键值对。

17.9.1 覆盖hashCode()

String有个特点,如果程序中有多个String对象,都包含相同的字符串序列1,那么这些String对象都映射到同一块内存区域,所以new String(“hello”)生成的两个实例虽然相互独立,但是hashCode()应该产生同样的结果。

  1. 给int变量result赋予一个非零常量,如17
  2. 给对象中每个有意义的域f(即可以做equals操作的域)计算一个int散列码c。
  3. 合并计算散列码 result = 37*result+c;
  4. 返回result
  5. 检查hashCode生成的结果,确保相同的对象拥有相同的散列码

17.10.2对List的选择

最佳做法,将ArrayList作为默认首选,只有你需要额外功能或者程序性能因为经常从表中进行插入和删除而变差时,才去选择LinkedList。

17.10.4 对Set的选择

HashSet基本性能比TreeSet好,,特别是添加和查询元素时。
用TreeSet迭代通常比HashSet快。

对于插入操作,LinkedHashSet比HashSet的代价更高,这是由维护链表所带来的额外开销造成的。

17.11 实用方法

java中有大量用于容器的卓越的使用方法。它们被表示为java.util.Collections类内部的静态方法。

17.11.1 List的排序和查询

List的排序和查询使用的方法与对象数组所使用的相应的方法有相同的名字与语法,只是用Collections的static方法代替Arrays方法而已。

快速报错

java容器类类库采用快速报错(fail-fast),它会探查容器上的任何除了你的进程所进行的的操作之外的所有变化,一旦它发现进程修改了容器,就会立即抛出ConcurrentModificationException异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值