Java: select from collection only elements of provided type

北城以北 提交于 2020-01-02 06:48:15

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!