background image
15.为何Iterator接口没有具体的实现?
    Iterator接口定义了遍历集合的方法,但它的实现则是集合实现类的责任。每个能够返回用于遍历的
Iterator的集合类都有它自己的Iterator实现内部类。
这就允许集合类去选择迭代器是fail-fast还是fail-safe的。比如,ArrayList迭代器是fail-fast的,而
CopyOnWriteArrayList迭代器是fail-safe的。
16.UnsupportedOperationException是什么?
    UnsupportedOperationException是用于表明操作不支持的异常。在JDK类中已被大量运用,在集合框
架java.util.Collections.UnmodifiableCollection将会在所有add和remove操作中抛出这个异常。
17.在Java中,HashMap是如何工作的?
    HashMap在Map.Entry静态内部类实现中存储key-value对。HashMap使用哈希算法,在put和get方
法中,它使用hashCode()和equals()方法。当我们通过传递key-value对调用put方法的时候,HashMap
使用Key hashCode()和哈希算法来找出存储key-value对的索引。Entry存储在LinkedList中,所以如果存
在entry,它使用equals()方法来检查传递的key是否已经存在,如果存在,它会覆盖value,如果不存在,
它会创建一个新的entry然后保存。当我们通过传递key调用get方法时,它再次使用hashCode()来找到数
组中的索引,然后使用equals()方法找出正确的Entry,然后返回它的值。下面的图片解释了详细内容。
    其它关于HashMap比较重要的问题是容量、负荷系数和阀值调整。HashMap默认的初始容量是32,负
荷系数是0.75。阀值是为负荷系数乘以容量,无论何时我们尝试添加一个entry,如果map的大小比阀值大
的时候,HashMap会对map的内容进行重新哈希,且使用更大的容量。容量总是2的幂,所以如果你知道
你需要存储大量的key-value对,比如缓存从数据库里面拉取的数据,使用正确的容量和负荷系数对
HashMap进行初始化是个不错的做法。
18.hashCode()和equals()方法有何重要性?
    HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引。当我们试着从
HashMap中获取值的时候,这些方法也会被用到。如果这些方法没有被正确地实现,在这种情况下,两个
不同Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,然后覆盖它
们,而非把它们存储到不同的地方。同样的,所有不允许存储重复数据的集合类都使用hashCode()和
equals()去查找重复,所以正确实现它们非常重要。equals()和hashCode()的实现应该遵循以下规则:
(1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的。
(2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。
19.我们能否使用任何类作为Map的key?
    我们可以使用任何类作为Map的key,然而在使用它们之前,需要考虑以下几点:
(1)如果类重写了equals()方法,它也应该重写hashCode()方法。
(2)类的所有实例需要遵循与equals()和hashCode()相关的规则。请参考之前提到的这些规则。
(3)如果一个类没有使用equals(),你不应该在hashCode()中使用它。
(4)用户自定义key类的最佳实践是使之为不可变的,这样,hashCode()值可以被缓存起来,拥有更好的
性能。不可变的类也可以确保hashCode()和equals()在未来不会改变,这样就会解决与可变相关的问题
了。
    比如,我有一个类MyKey,在HashMap中使用它。
//
传递给
MyKey
name
参数被用于
equals()
hashCode()
 MyKey key = new MyKey('Pankaj'); //assume hashCode=1234 
myHashMap.put(key, 'Value'); // 
以下的代码会改变
key
hashCode()
equals()
 key.setName('Amit'); //assume new hashCode=7890 
//
下面会返回
null
,因为
HashMap
会尝试查找存储同样索引的
key
,而
key
已被改变了,匹配失败,返回
null 
myHashMap.get(new MyKey('Pankaj'));
    那就是为何String和Integer被作为HashMap的key大量使用。
20.Map接口提供了哪些不同的集合视图?