简体   繁体   English

遍历HashSet(Java)中的唯一对

[英]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. 我想遍历HashSet中的唯一对,理想情况下,我将能够制作迭代器的副本,并且在耗尽自身之后,迭代要为其制作副本的迭代器,但是迭代器不喜欢被复制,并且我怀疑这有充分的理由,但我不知道那是什么。

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. 编辑:这样做的目的是保存迭代器的当前状态,该状态已经指向第i个元素。

If you cloned an Iterator and the clone modified the underlying Iterable, the original Iterator will throw a ConcurrentModificationException. 如果克隆了Iterator,并且克隆修改了基础Iterable,则原始Iterator将抛出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. 或者您可以使用and数组并对其进行迭代。

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: 如果生成对的顺序无关紧要,则可以使用以下代码,该代码避免了必须在O(n * n)时间运行的情况下克隆迭代器的过程:

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. 例如,此迭代器的remove()方法。

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 在这里,您要处理的是将哈希表设置为LinkedList,并且每次通过哈希表进行迭代时都将从LinkedList中删除第一个元素

Cloning anything in Java is not good practice. 用Java克隆任何东西都不是好习惯。 See for example Clone() vs Copy constructor- which is recommended in java 参见例如Clone()vs Copy构造函数-在Java中推荐

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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