【问题标题】:Java Iterators. How to inspect the Iterator?Java 迭代器。如何检查迭代器?
【发布时间】:2016-04-09 18:38:42
【问题描述】:

我想知道是否有办法检查迭代器对象。是一种地图吗?

另外,有没有更好的方法来获取迭代器对象的内容并将它们放入 mapC 中?

这是我的代码:

import java.util.HashMap;
import java.util.TreeMap;
import java.util.Map;
import java.util.Iterator;

public class Maps {
  public static void main(String[] args) {
    Map mapA = new HashMap();
    Map mapB = new TreeMap();

    mapA.put("key1", "element 1");
    mapA.put("key2", "element 2");
    mapA.put("key3", "element 3");

    // The three put() calls maps a string value to a string key. You can then
    // obtain the value using the key. To do that you use the get() method like this:

    String element1 = (String) mapA.get("key1");
    // why do I need the type cast on the right?
    System.out.println(element1);

    // Lets iterate through the keys of this map:

    Iterator iterator = mapA.keySet().iterator();
    System.out.println(iterator);  // How to inspect this? Is it a kind of map?

    Map mapC = new HashMap();
    while(iterator.hasNext()){
      Object key   = iterator.next();
      Object value = mapA.get(key);
      mapC.put(key,value);
    } // Is there a better way to take the contents of the iterator and put them in a new map?
    System.out.println(mapC);
  }
}

【问题讨论】:

  • 你说的inspect是什么意思? Iterator 是 Iterator。 iterator() 方法返回的实际对象是实现了Iterator 的类型。
  • 您想通过检查迭代器了解什么?
  • 旁注:不要使用原始类型。
  • System.out.println(iterator.getClass());
  • 一般 - 不要“检查”它 - 使用接口方法 hasNext 和 next 来获取值。有大量不同的迭代器实现(我的工作区中有 100 多个)

标签: java


【解决方案1】:

对迭代器唯一能做的就是调用它的hasNext()、next() 和remove() 方法。每种不同类型的集合(和集合视图)的迭代器实现在每种情况下都可能不同;你对它们无能为力。

如其他地方所述,您可以使用mapC.putAll(mapA) 复制mapA 中的所有内容。不过,您通常应该使用泛型而不是原始类型。

【讨论】:

    【解决方案2】:

    使用 Java 反编译器,一些 IDE 有一个。例如,IntelliJ IDEA 和 Android Studio 捆绑在一起,它使您能够看到您无法看到的类。

    或者您实际上可以检查公共 Java API 的源代码,因为 Java 源代码与 JDK 捆绑在一起,它位于 src.zip 的安装文件夹中。

    无论如何,这是HashMap 的迭代器实现。

    private abstract class HashIterator {
        int nextIndex;
        HashMapEntry<K, V> nextEntry = entryForNullKey;
        HashMapEntry<K, V> lastEntryReturned;
        int expectedModCount = modCount;
    
        HashIterator() {
            if (nextEntry == null) {
                HashMapEntry<K, V>[] tab = table;
                HashMapEntry<K, V> next = null;
                while (next == null && nextIndex < tab.length) {
                    next = tab[nextIndex++];
                }
                nextEntry = next;
            }
        }
    
        public boolean hasNext() {
            return nextEntry != null;
        }
    
        HashMapEntry<K, V> nextEntry() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (nextEntry == null)
                throw new NoSuchElementException();
    
            HashMapEntry<K, V> entryToReturn = nextEntry;
            HashMapEntry<K, V>[] tab = table;
            HashMapEntry<K, V> next = entryToReturn.next;
            while (next == null && nextIndex < tab.length) {
                next = tab[nextIndex++];
            }
            nextEntry = next;
            return lastEntryReturned = entryToReturn;
        }
    
        public void remove() {
            if (lastEntryReturned == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            HashMap.this.remove(lastEntryReturned.key);
            lastEntryReturned = null;
            expectedModCount = modCount;
        }
    }
    
    private final class KeyIterator extends HashIterator
            implements Iterator<K> {
        public K next() { return nextEntry().key; }
    }
    
    private final class KeySet extends AbstractSet<K> {
        public Iterator<K> iterator() {
            return newKeyIterator();
        }
        public int size() {
            return size;
        }
        public boolean isEmpty() {
            return size == 0;
        }
        public boolean contains(Object o) {
            return containsKey(o);
        }
        public boolean remove(Object o) {
            int oldSize = size;
            HashMap.this.remove(o);
            return size != oldSize;
        }
        public void clear() {
            HashMap.this.clear();
        }
    }
    

    至于将一个Map的内容复制到另一个,there are questions about that kind of thing, but you can do it with a single putAll() method call.

    【讨论】:

    • 您知道在您的 JDK 主位置中有一个 source.zip 可以包含 - 无需反编译公共 API。这样您的 IDE 也将集成 Javadoc...
    • @RANders00 是的,你是对的。其实一开始我就想到了,但后来忘了把它添加到帖子中,所以我做到了。
    【解决方案3】:
    1. Iterator 是一个interface,它没有实现供您检查。如果您希望“检查”它,您必须知道实现该接口的具体类。但请注意,Java API 有多种实现(并且实现会随着时间而发展),因此通常您无法预测将使用哪个具体类。

    2. 您根本不需要使用迭代器来创建 HashMap 的副本。有一个拷贝构造函数HashMap(Map m)可以代替使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-10
      • 2011-05-17
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 2014-03-25
      • 1970-01-01
      相关资源
      最近更新 更多