问题
I have a collection of elements of type B and C, which all extends A. I need to filter the collection to get elements of only B type.
Is there any way to do it except:
for (A a : initCollection) {
if (a instanceof B) {
newCollection.add(a)?
}
}
Thanks
回答1:
Guava was alluded to in other answers, but not the specific solution, which is even simpler than people realize:
Iterable<B> onlyBs = Iterables.filter(initCollection, B.class);
It's simple and clean, does the right thing, only creates a single instance and copies nothing, and doesn't cause any warnings.
(The Collections2.filter() method does not have this particular overload, though, so if you really want a Collection, you'll have to provide Predicates.instanceOf(B.class) and the resulting collection will still sadly be of type Collection<A>.)
回答2:
I don't see anything wrong with doing it as per your example. However, if you want to get fancy you could use Google's Guava library, specifically the Collections2 class, to do a functional-style filtering on your collection. You get to provide your own predicate, which can of course do the instanceof thing.
Collection<Object> newCollection = Collections2.filter(initCollection, new Predicate<Object>() {
public boolean apply(Object o) {
return !(o instanceof String);
}
});
回答3:
AFAIK, there is no plain way to do it without adding code to classes A, B, and C. The real question is: Why do you need to filter out elements of a specific type? It goes against the very idea of sub-typing in OOP.
回答4:
If you don't want to create new collection you can remove odd elements from existing one:
Iterator<A> it = initCollection.iterator();
while (it.hasNext()){
if (it.next() instanceof C) {
it.remove();
}
}
回答5:
This is an old question, but I thought I'd add this in case anyone finds it.
You can do this using pure Java 8 and its Streams.
List<B> filtered = listOfA.stream()
.filter(a -> a instanceof B)
.map(a -> (B) a)
.collect(Collectors.toList());
来源:https://stackoverflow.com/questions/2722343/java-select-from-collection-only-elements-of-provided-type