1.获得HashMap的keySet(),对keySet()的操作会不会影响HashMap本身,如删除操作。
HashMap从抽象类AbstractMap中继承keySet属性,并用一个内部私有类进行创建,而且该内部类的方法均是调用HashMap的方法或对其this属性进行操作,是影响HashMap本身的,见源码:
/**
* Returns a {@link Set} view of the keys contained in this map.
* The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. If the map is modified
* while an iteration over the set is in progress (except through
* the iterator's own <tt>remove</tt> operation), the results of
* the iteration are undefined. The set supports element removal,
* which removes the corresponding mapping from the map, via the
* <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
* operations. It does not support the <tt>add</tt> or <tt>addAll</tt>
* operations.
*/
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
private final class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return HashMap.this.removeEntryForKey(o) != null;
}
public void clear() {
HashMap.this.clear();
}
}
2.获得ArrayList的iterator,然后调用arrayList.remove()方法删除一个元素,问这个iterator还是否可用?
每个容器类均有一个modCount属性,标示这个容器类对象创建后修改的次数,比如删除等操作都会进行modCount++。
每个容器类的迭代器都有一个expectedModCount,当通过迭代器对容器对象进行操作的时候基本都会调用一个checkForComodification()方法:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
迭代器类像上面entrySet一样是一个内部私有类,用迭代器进行的操作均是调用容器本身的方法或对其this属性进行操作,所以都会影响到容器对象本身。而每个容器修改的操作都会进行modCount++操作。有一点不同的是:通过迭代器进行的操作都会进行expectedModCount = modCount赋值,而容器对象本身的操作则会致使expectedModCount != modCount。这样上面的问题就有了答案,报异常或者得到非期望数据(hasNext()没有调用checkForComodification方法)。
3.如何比较好的重写hashCode()?
充分利用^、质数。
如:return new Integer(num1).hashCode() ^ (31 * new Integer(num2).hashCode());//num为类中两个属性