Collections removeAll method

前端 未结 5 596

I would like to know if something like below is possible,

list.removeAll(namesToRemove)

I hope the context is understandable.

The

相关标签:
5条回答
  • 2021-01-07 09:47

    You can do something like this using 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());
      }
    });
    
    0 讨论(0)
  • 2021-01-07 09:47

    Java 8:

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

    Java 7 and older:

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

    Note that both alternatives have quadratic complexity. You can make it linear by doing

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

    before the snippets, and use namesToRemoveSet instead of namesToRemove.

    0 讨论(0)
  • 2021-01-07 09:55

    You don't want to override anything in the Object class. You need to use either a filter utility or a collection that uses your own semantics instead of equals, maybe a ForwardingCollection wrapped around your own implementation of equivalence.

    All this can be achieved with google guava without breaking any standards

    0 讨论(0)
  • 2021-01-07 09:58
    Collection<MyObject> list = Collections2.filter(list, mo -> !namesToRemove.contains(mo.getName()));
    
    0 讨论(0)
  • 2021-01-07 10:09

    Another approach: Subclass ArrayList and implement a custom method like:

    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 changed the code - the comment was good, now the custom list is a 'List' again, but now we use the toString() method (for simplicity) for filtering. (using a getName() method is possible but requires more lines of code)

    0 讨论(0)
提交回复
热议问题