Как использовать выражение Java 8 Lambda для преобразования списка одного типа в список его подтипа

Я могу только найти, как это сделать на С#, а не на Java.

У меня есть List<TypeX>, но я знаю, что каждый отдельный элемент в этом списке фактически является подклассом TypeX Called TypeY.

Как я могу написать выражение Lambda, которое принимает List<TypeX> и возвращает List<TypeY>?

Ответы

Ответ 1

В моем примере я буду использовать следующие классы:

class TypeX {}
class TypeY extends TypeX {}

Тогда у меня есть List<TypeX>:

final List<TypeX> xList = ...

Все, что вам нужно сделать, это использовать ссылку метода на TypeY.class.cast:

final List<TypeY> yList = xList.stream()
                               .map(TypeY.class::cast)
                               .collect(toList());

Вы также можете filter() исключить элементы, которые вызывают ошибку:

final List<TypeY> yList = xList.stream()
                               .filter(TypeY.class::isInstance)
                               .map(TypeY.class::cast)
                               .collect(toList());

Примеры использования:

import static java.util.stream.Collectors.toList;

Ответ 2

Проецирование в Java выполняется с помощью метода map:

List<TypeY> res = listTypeX
    .stream()
    .map((x) -> (TypeY)x)
    .collect(Collectors.toList());

Ответ 3

Просто все map с лямбдой, которая отличает элементы:

List<TypeX> list = ...;
List<TypeY> castList = 
    list.stream().map(x -> (TypeY)x).collect(Collectors.toList());

Ответ 4

Вы можете использовать selectInstancesOf() из Eclipse Collections:

MutableList<TypeX> xList = Lists.mutable.empty();
MutableList<TypeY> yList = xList.selectInstancesOf(TypeY.class);

Если вы не можете изменить xList из List:

List<TypeX> xList = Lists.mutable.empty();
List<TypeY> yList = ListAdapter.adapt(xList).selectInstancesOf(TypeY.class);

Примечание. Я участвую в коллекциях Eclipse.