keyset
的使用和實(shí)現(xiàn)
keyset可以獲取Map中所有的key值乾蓬,查看keyset
方法辙谜。
KeySet是HashMap的內(nèi)部類芳杏,在keyset
方法中返回KeySet實(shí)例,沒有添加key元素怕吴;
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
final class KeySet extends AbstractSet<K> {
public final int size() { return size; }
public final void clear() { HashMap.this.clear(); }
public final Iterator<K> iterator() { return new KeyIterator(); }
public final boolean contains(Object o) { return containsKey(o); }
public final boolean remove(Object key) {
return removeNode(hash(key), key, null, false, true) != null;
}
public final Spliterator<K> spliterator() {
return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
}
public final void forEach(Consumer<? super K> action) {
Node<K,V>[] tab;
if (action == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
for (int i = 0; i < tab.length; ++i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next)
action.accept(e.key);
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
}
通過編譯keyset的使用方法雀彼,查看keyset的本質(zhì);
public class MapTest {
public static void main(String[] args)
{
Map<String, String> map = new HashMap<String, String>();
map.put("1","uranus");
map.put("2", "leon");
Set<String> ks = map.keySet();
for (String s : ks)
{
System.out.println(s);
}
}
}
使用jad編譯上述代碼瘸彤,jad .\MapTest.class
修然。從編譯后代碼可以看出,keyset的使用是通過iterator獲取所有鍵值质况。
public class MapTest
{
public MapTest()
{
}
public static void main(String args[])
{
Map map = new HashMap();
map.put("1", "uranus");
map.put("2", "leon");
Set ks = map.keySet();
String s;
for(Iterator iterator = ks.iterator(); iterator.hasNext(); System.out.println(s))
s = (String)iterator.next();
}
}
查看類KeySet
中的迭代器愕宋,返回外部類HashMap中的KeyIterator
類。
public final Iterator<K> iterator() { return new KeyIterator(); }
查看KeyIterator
類结榄,繼承了HashIterator
類中贝。
final class KeyIterator extends HashIterator
implements Iterator<K> {
public final K next() { return nextNode().key; }
}
查看HashIterator
類
abstract class HashIterator {
Node<K,V> next; // next entry to return
Node<K,V> current; // current entry
int expectedModCount; // for fast-fail
int index; // current slot
HashIterator() {
expectedModCount = modCount;
Node<K,V>[] t = table;
current = next = null;
index = 0;
if (t != null && size > 0) { // advance to first entry
do {} while (index < t.length && (next = t[index++]) == null);
}
}
public final boolean hasNext() {
return next != null;
}
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (e == null)
throw new NoSuchElementException();
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
public final void remove() {
Node<K,V> p = current;
if (p == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
current = null;
K key = p.key;
removeNode(hash(key), key, null, false, false);
expectedModCount = modCount;
}
}