views:

139

answers:

4

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

list<MyObject>.removeAll(list<String>)

I hope the context is understandable.

The list<MyObject> : is a ArrayList<MyObject>

The list<String> : is a ArrayList<String>

I know this can be achieved by overriding equals method in MyObject class. I would like to know if any other choice is prsent.

Thanks,Srinivas N

+4  A: 

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());
  }
});
Joachim Sauer
formatting is broken. I would fix it but I don't have the rights yet. Also, google collections is deprecated. use guava instead: http://code.google.com/p/guava-libraries
seanizer
+1 for proposing google collections (guava)
Schildmeijer
thanks, @seanizer. I hate that JavaDoc produces spaces in their link, but am not sure who to blame: Them for doing it or the SO software for not handling it ;-) I prefer to link Google Collections, because it has a final release, which Guava doesn't have yet (and switching from Google Collections to Guava is pretty easy anyway).
Joachim Sauer
on my machine, firefox does it correctly (converting space to %20), while ie leaves the spaces. both fail, however, when it comes to converting parentheses to %28 and %29
seanizer
@Joachim Sauer Guava had a proper binary release on April 9 and has already had two more since then. The newest is called version "5" since there were two "source releases" before all this.
Kevin Bourrillion
+1  A: 
Iterator<MyObject> iter = list.iterator();
while (iter.hasNext())
    if (iter.next().fulfillsCondition())
        iter.remove();
aioobe
I'm not targetting to loop
srinannapa
You'll have to do it with a loop (unless you accept 3rd party libs like google collections as Joachim mentioned above)
Andreas_D
and those libs also use loops, of course :-)
seanizer
+2  A: 

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

seanizer
A: 

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)

Andreas_D
bad style, as it breaks the interface. unless you create an interface first that extends list and includes this method, but that's a bit like swatting flies with a Buick
seanizer
@seanizer, in what sense does it "break the interface"?
aioobe
@seanizer - If you'd argued 'bead style', because you should favour composition of inheritance, then I'd agreed. Like aioobe I have no clue which interface is broken. This is a customized Arraylist, limited to MyObject objects, nothing else.
Andreas_D
it means that I have to code against this custom list, not against the list interface. This is a bad thing in itself, but it also breaks all kinds of wrapper / delegate methods e.g. in the java.util.Collections class
seanizer
your edit doesn't really change anything, what I mean is: you have public methods that are not accessible from an interface. This is fine for pojos, but bad for collections. so you could do it like this: http://pastebin.com/ZKFkAE9s to fix that, but still you would be losing methods like Collections.synchronizedList() etc.
seanizer