Коллекции метод removeAll - PullRequest
1 голос
/ 09 июня 2010

Хотелось бы узнать, возможно ли что-то подобное ниже,

list.removeAll(namesToRemove)

Я надеюсь, что контекст понятен.

list имеет тип ArrayList<MyObject>, где MyObject имеет метод getName.

namesToRemove - это ArrayList<String>, содержащий имена удаляемых объектов.

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

Ответы [ 5 ]

4 голосов
/ 09 июня 2010

Java 8:

list.removeIf(obj -> namesToRemove.contains(obj.getName()));

Java 7 и старше:

Iterator<MyObject> iter = list.iterator();
while (iter.hasNext())
    if (namesToRemove.contains(iter.next().getName()))
        iter.remove();

Обратите внимание, что обе альтернативы имеют квадратичнуюсложность.Вы можете сделать его линейным, выполнив

Set<String> namesToRemoveSet = new HashSet<>(namesToRemove);

перед фрагментами, и используйте namesToRemoveSet вместо namesToRemove.

4 голосов
/ 09 июня 2010

Вы можете сделать что-то подобное, используя Google Collections Collections2.filter():

final List<String> namesToKeep = getNamesToFilter();
List<MyObject> filtered = Collections2.filter(originalList, new Predicate<MyObject>() {
  @Override
  public boolean apply(MyObject o) {
    return namesToKeep.contains(o.getName());
  }
});
2 голосов
/ 09 июня 2010

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

Всего этого можно добиться с помощью google guava без нарушения каких-либо стандартов

0 голосов
/ 09 января 2017
Collection<MyObject> list = Collections2.filter(list, mo -> !namesToRemove.contains(mo.getName()));
0 голосов
/ 09 июня 2010

Другой подход: создать подкласс ArrayList и реализовать собственный метод, например:

public class MyArrayList<E> extends ArrayList<E> {

   // all needed constructors

   public void removeAllWithNames(Collection<String> names) {
     // following code is based on aioobe's answer
     Iterator<E> iter = iterator();
       while (iter.hasNext())
         if (names.contains(iter.next().toString()))
           iter.remove();
   }
}

EDIT изменил код - комментарий был хорош, теперь пользовательский список снова стал «List», но теперь мы используем метод toString() (для простоты) для фильтрации (использование метода getName() возможно, но требует больше строк кода)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...