0

I want to know if there is a way to inspect the iterator object. Is it a kind of map?

Also, is there a a better way to take the contents of the iterator object and put them in mapC?

Here is my code:

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);
  }
}
Jwan622
  • 11,015
  • 21
  • 88
  • 181
  • 3
    What do you mean by _inspect_? An `Iterator` is an `Iterator`. The actual object returned by the `iterator()` method is of a type that implements `Iterator`. – Sotirios Delimanolis Jan 05 '16 at 19:54
  • 3
    What do you want to find out about the iterator by inspecting it? – TangledUpInBlue Jan 05 '16 at 19:55
  • 4
    Side note: don't use raw types. – Sotirios Delimanolis Jan 05 '16 at 19:56
  • `System.out.println(iterator.getClass());` – smac89 Jan 05 '16 at 19:56
  • 1
    In general - don't "inspect" it - use the interface methods `hasNext` and `next` to get the values out. There are a ton of different Iterator implementations (I have more than 100 in my workspace) – Krease Jan 05 '16 at 20:01
  • Hmm, I think you can compare an iterator with an queue. You have got a pointer that points on the current object. Everytime you call the "next()" method this pointer gets increased by one (and you will get the object on this position as return), if there is no element left this will throw an error). – Graphican0 Jan 05 '16 at 20:06

3 Answers3

6

The only thing you can do with an iterator is to call its hasNext(), next(), and remove() methods. The iterator implementations for every different type of collection (and collection view) are likely to be different in every case; there's nothing else you can do with them.

As stated elsewhere, you can use mapC.putAll(mapA) to copy over all contents from mapA. You should generally use generics instead of raw types, though.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
3
  1. Iterator is an interface, which has has no implementation for you to inspect. You have to know the concrete class that implements the interface if you want to have any hope of "inspecting" it. Be aware, though, that there are multiple implementations of the Java API (and implementations evolve over time), so in general you cannot predict which concrete class will be used.

  2. You do not need to use an Iterator at all to create a copy of a HashMap. There is a copy constructor HashMap(Map m) that can be used instead.

cybersam
  • 63,203
  • 6
  • 53
  • 76
1

Using a Java decompiler, some IDEs have one. For example, IntelliJ IDEA and Android Studio bundle one, which enables you to see into classes that otherwise you wouldn't be able to see into.

Or you can actually check the source for public Java APIs because the Java source is bundled with the JDK, it's in your installation folder in src.zip.

Anyhow, here's the iterator implementation for a 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();
    }
}

As for copying contents of one Map to another, there are questions about that kind of thing, but you can do it with a single putAll() method call.

Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • 2
    You know there is a `source.zip` in your JDK home location that you can include - there is no need to decompile the public API. That way your IDE will also integrate the Javadoc... – randers Jan 05 '16 at 20:01
  • @RAnders00 yeah you're right. I actually had it in mind at first but then forgot to add it to the post, so I did. – EpicPandaForce Jan 05 '16 at 20:03