Java: выбрать из коллекции только элементы указанного типа - PullRequest
4 голосов
/ 27 апреля 2010

У меня есть коллекция элементов типа B и C, которая расширяет A. Мне нужно отфильтровать коллекцию, чтобы получить элементы только типа B.

Есть ли способ сделать это, кроме:

for (A a : initCollection) {
  if (a instanceof B) {
    newCollection.add(a)?
  }
}

Спасибо

Ответы [ 5 ]

11 голосов
/ 27 апреля 2010

Гуава упоминалась в других ответах, но не в конкретном решении, которое даже проще, чем думают люди:

Iterable<B> onlyBs = Iterables.filter(initCollection, B.class);

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

(Однако метод Collections2.filter() не имеет этой конкретной перегрузки, поэтому, если вы действительно хотите Collection, вам придется предоставить Predicates.instanceOf(B.class), и результирующая коллекция все равно будет иметь тип Collection<A> .)

4 голосов
/ 27 апреля 2010

Я не вижу ничего плохого в том, чтобы делать это в соответствии с вашим примером. Однако, если вы хотите стать модным, вы можете использовать библиотеку Google Guava , в частности класс Collections2, для фильтрации вашей коллекции в функциональном стиле. Вы можете предоставить свой собственный предикат, который, конечно, может сделать вещь instanceof.

Collection<Object> newCollection = Collections2.filter(initCollection, new Predicate<Object>() { 
    public boolean apply(Object o) {
        return !(o instanceof String);
    } 
});
2 голосов
/ 27 апреля 2010

AFAIK, нет простого способа сделать это без добавления кода в классы A, B и C. Реальный вопрос: зачем вам нужно отфильтровывать элементы определенного типа? Это противоречит самой идее подтипа в ООП.

0 голосов
/ 05 февраля 2017

Это старый вопрос, но я решил добавить его на тот случай, если кто-нибудь найдет его.

Вы можете сделать это, используя чистую Java 8 и Stream s.

List<B> filtered = listOfA.stream()
    .filter(a -> a instanceof B)
    .map(a -> (B) a)
    .collect(Collectors.toList());
0 голосов
/ 27 апреля 2010

Если вы не хотите создавать новую коллекцию, вы можете удалить нечетные элементы из существующей:

Iterator<A> it = initCollection.iterator();
while (it.hasNext()){
   if (it.next() instanceof C) {
      it.remove();
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...