简体   繁体   中英

Iterating over unique pairs in a HashSet (Java)

I want to iterate over unique pairs in a HashSet, Ideally, I'd be able to make a copy of the iterator and when it has exhausted itself, iterate the iterator I am making copies of, but Iterators do not like being copied, and I suspect that there is a good reason for this, but I do not know what that is.

More specifically, what prevents this (below) behavior from being supported?

Iterator<Object> iter = myhash.iterator();
while(iter.hasNext()){
    object=iter.next();
    Iterator<Object> iterclone = iter.clone();
    while(iterclone.hasNext()){
        setOfObjectPairs.add(object,iterclone.next());
    }
}

Edit: The point of doing this is to save the current state of the iterator, which is already pointing at the i-th element.

If you cloned an Iterator and the clone modified the underlying Iterable, the original Iterator will throw a ConcurrentModificationException.

You can simply use another iterator for the same set.

Iterator<Object> iter = h.iterator();
        while(iter.hasNext()){
            Object o=iter.next();
            Iterator<Object> iterclone = h.iterator();
            while(iterclone.hasNext()){
                //logic
            }
        }

or you can use and array and iterate over it.

If the order to generate the pairs doesn't matter, then you could use the following code, which avoids having to clone the iterator, while still running in O(n*n) time:

HashSet<Integer> set = new HashSet<Integer>();
for (int i = 0; i < 10; i++) {
    set.add(i);
}
int to = 0;
for (int a : set) {
    int index = 0;
    for (int b : set) {
        if (index++ >= to) {
            break;
        }
        System.out.println(a + ", " + b);
    }
    to++;
}

If you will not change iterator (you're only want to save state)

The best way is to do it here is with for each loop I guess

I expect iterators to be only for cases when I modify collection in loop through this collection. For example remove() method from this iterator.

The best way I see it is:

    HashSet<Integer> set = new HashSet<Integer>();
    for (int i = 0; i < 10; i++) {
        set.add(i);
    }
    LinkedList<Integer> arr = new LinkedList<Integer>(set);
    for (Integer i : set) {
        arr.pollFirst();
        for (Integer k : arr) {
            System.out.println(i + " " + k);
        }
    }

Here you're coping you're hashset to LinkedList and you're droping first element from LinkedList every time you're iterating through hashset

Cloning anything in Java is not good practice. See for example Clone() vs Copy constructor- which is recommended in java

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM