简体   繁体   English

如何使用Iterator从集合中删除元素?

[英]How to remove an element from set using Iterator?

I have a scenario that I am iterating over a set using iterator. 我有一种情况,我正在使用迭代器遍历集合。 Now I want to remove 1st element while my iterator is on 2nd element. 现在,我想在迭代器位于第二个元素上时删除第一个元素。 How can I do it. 我该怎么做。 I know Set is unordered and there is nothing like first or second element but my question is I want to remove an element which is not being currently returned by Iterator.next 我知道Set是无序的,没有像第一个或第二个元素一样的东西,但是我的问题是我想删除Iterator.next当前未返回的元素

  1. I dont want to convert this set to list and using listIterator. 我不想将此设置转换为列表并使用listIterator。

  2. I dont want to collect all objects to be removed in other set and call remove all 我不想收集所有要在其他集合中删除的对象,并调用全部删除

  3. I cant store it and remove after the iteration 迭代后我无法存储并删除

sample code. 示例代码。

Set<MyObject> mySet = new HashSet<MyObject>();

mySet.add(MyObject1);
mySet.add(MyObject2);

...
Iterator itr = mySet.iterator();
        while(itr.hasNext())
        {
            // Now iterator is at second element and I want to remove first element
        }

HashSet is unordered and javadoc clearly states that Iterator's remove method Removes from the underlying collection the last element returned by this iterator (optional operation). HashSet是无序的,并且javadoc明确声明Iterator的remove方法Removes from the underlying collection the last element returned by this iterator (optional operation). So the answer is no through an iterator.Since HashSet contains unique elements,you can use Set.remove(Object) after traversing the first element,in thios case you dont even need to go to the 2nd element 因为HashSet包含唯一元素,所以您可以在遍历第一个元素后使用Set.remove(Object),在thios情况下,您甚至不需要转到第二个元素

HashSet<K> hs;// you HashSet containing unique elements

if(!hs.isEmpty())
{
  hs.remove(hs.iterator().next());
}

Just remember HashSet is unordered and there is no such thing as 1st or 2nd element

Alternately,you should use LinkedHashSet which gives you an ordered Set based on insertion order 或者,您应该使用LinkedHashSet ,它根据插入顺序为您提供有序的Set

Set.iterator() returns a java.lang.Iterator . Set.iterator()返回一个java.lang.Iterator This iterator only provides methods to remove the current element and to iterate forward . 此迭代器仅提供删除当前元素并向前迭代的方法。

So if you don't want to convert your set, using only Iterator you cannot remove the previous element. 因此,如果您不想转换集合,则仅使用Iterator不能删除上一个元素。

What you can do for example is that you collect the elements you want to remove, and after you iterated through the whole set, you remove the collected elements after, eg with Set.removeAll(removableCollection) : 例如,您可以做的是收集要删除的元素,然后遍历整个集合,然后例如使用Set.removeAll(removableCollection)删除收集的元素:

List<MyObject> removableList = new ArrayList<>();

MyObject previous;

Iterator<MyObject> itr = mySet.iterator();
while (itr.hasNext()) {
    MyObject current = itr.next();

    // If you find you want to remove the previous element:
    if (someCondition)
        removableList.add(previous);

    previous = current;
}

mySet.removeAll(removeableList);

Given the constraints as you have stated them, I don't think that there is solution to the problem. 考虑到您所说的限制,我认为没有解决问题的办法。

  • The Iterator.remove() method will only remove the "current" element. Iterator.remove()方法将仅删除“当前”元素。
  • You have excluded "remembering" objects and removing them from the HashSet in a second pass / phase. 您已排除“记住”对象,并在第二遍/阶段将其从HashSet中删除。
  • Schemes that involve using two iterators simultaneously and removing using one of them will result in CCMEs on the second one. 涉及同时使用两个迭代器并使用其中一个迭代器进行删除的方案将导致第二个迭代器出现CCME。

The three approaches that you suggested (but then excluded) would all work. 您建议(但随后排除)的三种方法都可以使用。 I think the 2nd one would be the most performant. 我认为第二名将是表现最好的。

Another idea would be to implement a new hash table-based Set type which has an Iterator with an extra remove operation. 另一个想法是实现一个新的基于哈希表的Set类型,该类型具有一个带有额外删除操作的Iterator (You could start with the source code of HashSet etcetera, rename the class and then modify it to do what you need.) (您可以从HashSet等的源代码开始,重命名该类,然后对其进行修改以执行您需要的操作。)

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

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