Как безопасно удалить другие элементы из Набора при итерации через Набор

У меня была такая же проблема. Я использовал Intellisense для построения отображения пространства имен, и он не включал атрибут сборки, поэтому он выглядел так:

xmlns:converters="clr-namespace:XYZ.UI.Converters;

, когда я сравнивал его с рабочим поведением в другом окне, я заметил разницу , Когда я изменил его на

xmlns:converters="clr-namespace:XYZ.UI.Converters;assembly=XYZ.UI"

, очистил его и построил, это сработало.

6
задан Raedwald 13 March 2019 в 12:49
поделиться

7 ответов

Вы хотите удалить элемент из списка и продолжить итерацию в том же списке. Можете ли вы реализовать двухэтапное решение, в котором на шаге 1 вы собираете элементы, которые нужно удалить, во временную коллекцию, а на шаге 2 удаляете их после их идентификации?

8
ответ дан 8 December 2019 в 05:57
поделиться

Некоторые мысли (это зависит от того, какие именно отношения существуют между двумя объектами в коллекции):

  1. Карта с объектом в качестве ключа и партнером в качестве значения.
  2. ] CopyOnWriteArrayList, но вы должны заметить, когда вы ударяете по партнеру
  3. Сделайте копию в другой объект Collection и перебирайте один, удаляя другой. Если эта исходная Коллекция может быть Сетом, это наверняка поможет при удалении.
3
ответ дан 8 December 2019 в 05:57
поделиться

CopyOnWriteArrayList сделает то, что вы хотите.

1
ответ дан 8 December 2019 в 05:57
поделиться

Вы можете попробовать сначала найти все элементы, которые нужно удалить, а затем удалить их, когда закончите обработку всего списка. Пропуск удаленных элементов по мере их нахождения.

myCollection<BusinessObject>
List<BusinessObject> deletedObjects = new ArrayList(myCollection.size());

for (BusinessObject anObject : myCollection) 
{ 
  if (!deletedObjects.contains(anObject))
  {
      if (someConditionIsTrue) 
      { 
          deletedObjects.add(anObjectsPartner);
      }
  }
}
myCollection.removeAll(deletedObjects);
1
ответ дан 8 December 2019 в 05:57
поделиться

Лучший ответ - второй, используйте итератор.

0
ответ дан 8 December 2019 в 05:57
поделиться

Это не ошибка коллекции, а то, как вы ее используете. Изменение коллекции на полпути итерации приводит к этой ошибке (что хорошо, поскольку итерацию в целом невозможно продолжить однозначно).

Изменить : Перечитав вопрос, этот подход не сработает, хотя я оставляю его здесь в качестве примера того, как избежать этой проблемы в общем случае.

Вы хотите примерно следующее:

for (Iterator<BusinessObject> iter = myCollection.iterator; iter.hasNext(); )
{
    BusinessObject anObject = iter.next();
    if (someConditionIsTrue) 
    { 
        iter.remove();
    }        
}

Если вы удаляете объекты через сам итератор, он знает об удалении и все работает так, как и следовало ожидать. Что должна делать итерация, если вы удалите элемент, который еще не достиг ? Удаление (или нет) текущего элемента относительно четко определено, но вы говорите об удалении партнера текущего элемента , который, как я полагаю, может находиться в случайной точке итерируемого объекта. Поскольку нет четкого способа справиться с этим, вам необходимо самостоятельно предоставить некоторую форму логики, чтобы справиться с этим. В этом случае я бы предпочел создать и заполнить новую коллекцию во время итерации, а затем присвоить это переменной myCollection в конце. Если это невозможно, то можно будет отслеживать удаляемые партнерские элементы и вызывать myCollection.removeAll .

т еще не достиг ? Удаление (или нет) текущего элемента относительно четко определено, но вы говорите об удалении партнера текущего элемента , который, как я полагаю, может находиться в случайной точке итерируемого объекта. Поскольку нет четкого способа справиться с этим, вам необходимо самостоятельно предоставить некоторую форму логики, чтобы справиться с этим. В этом случае я бы предпочел создать и заполнить новую коллекцию во время итерации, а затем присвоить это переменной myCollection в конце. Если это невозможно, то можно будет отслеживать удаляемые партнерские элементы и вызывать myCollection.removeAll .

т еще не достиг ? Удаление (или нет) текущего элемента относительно четко определено, но вы говорите об удалении партнера текущего элемента , который, как я полагаю, может находиться в случайной точке итерируемого объекта. Поскольку нет четкого способа справиться с этим, вам необходимо самостоятельно предоставить некоторую форму логики, чтобы справиться с этим. В этом случае я бы предпочел создать и заполнить новую коллекцию во время итерации, а затем присвоить это переменной myCollection в конце. Если это невозможно, то можно будет отслеживать удаляемые партнерские элементы и вызывать myCollection.removeAll .

который, как я полагаю, может быть в случайной точке итерации. Поскольку нет четкого способа справиться с этим, вам необходимо самостоятельно предоставить некоторую форму логики, чтобы справиться с этим. В этом случае я бы предпочел создать и заполнить новую коллекцию во время итерации, а затем присвоить это переменной myCollection в конце. Если это невозможно, то можно будет отслеживать удаляемые партнерские элементы и вызывать myCollection.removeAll .

который, как я полагаю, может быть в случайной точке итерации. Поскольку нет четкого способа справиться с этим, вам необходимо самостоятельно предоставить некоторую форму логики, чтобы справиться с этим. В этом случае я бы предпочел создать и заполнить новую коллекцию во время итерации, а затем присвоить это переменной myCollection в конце. Если это невозможно, то можно будет отслеживать удаляемые партнерские элементы и вызывать myCollection.removeAll .

а затем присвоить это переменной myCollection в конце. Если это невозможно, то можно будет отслеживать удаляемые партнерские элементы и вызывать myCollection.removeAll .

а затем присвоить это переменной myCollection в конце. Если это невозможно, то можно будет отслеживать удаляемые партнерские элементы и вызывать myCollection.removeAll .

9
ответ дан 8 December 2019 в 05:57
поделиться

Почему бы не использовать Коллекцию всех исходных BusinessObject, а затем отдельный класс (например, Map), который их связывает (т. Е. Создает партнера)? Поместите их как составные элементы в свой собственный класс, чтобы вы всегда могли удалить партнера при удалении бизнес-объекта. Не возлагайте на вызывающего абонента ответственность каждый раз, когда ему нужно удалить BusinessObject из коллекции.

IE

class BusinessObjectCollection implements Collection<BusinessObject> {
  Collection<BusinessObject> objects;
  Map<BusinessObject, BusinessObject> associations;

 public void remove(BusinessObject o) {
  ...
// remove from collection and dissasociate...
 }
}
0
ответ дан 8 December 2019 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: