Я столкнулся с проблемой, что я получаю объект Vector
(без универсального типа), и мне нужно извлечь оттуда значения. Прямо сейчас он работает, выполняя вложенный foreach:
List<Long> longList = new ArrayList<>();
vector.forEach(item ->
((KnownType)item).getAnotherVector().forEach(nestedItem ->
longList.add(((NestedKnownType)nestedItem).longValue())));
Я попытался изменить этот код на что-то более читабельное с помощью потоков Java 8:
List<Long> longList = vector.stream()
.flatMap(item -> ((KnownType)item).getAnotherVector().stream())
.flatMap(nestedItem -> ((NestedKnownType)nestedItem).longValue())
.collect(Collectors.toList());
Этот выше не работает, потому что он говорит, что возвращает List<Object>
вместо List<Long>
. Если я добавлю приведение перед longValue, это все равно не сработает. Однако, если я приведу исходное Vector
в самом начале следующим образом:
List<Long> longList = ((Vector<KnownType>)vector).stream()
.flatMap(item -> item.getAnotherVector().stream())
.flatMap(nestedItem -> ((NestedKnownType)nestedItem).longValue())
.collect(Collectors.toList());
затем он компилируется.
Вопрос: есть ли хороший способ с потоками извлечь нужное мне значение из этого нетипизированного вектора? Если нет, то почему? В первом вызове flatMap
я привожу текущий элемент к известному типу, поэтому контекст типа должен быть известен после этого... Я просто не понимаю.
Полностью рабочий пример с разными вариантами и исходами:
// KnownType.java
package tryvector;
import java.util.Vector;
import lombok.Builder;
import lombok.Value;
@Builder
@Value
public class KnownType {
private final Vector nestedTypeList;
}
// NestedType.java
package tryvector;
import lombok.Builder;
import lombok.Value;
@Builder
@Value
public class NestedType {
private final Long longValue;
}
// Main.java
public class Main {
public static void main(String[] args) {
tryVector();
}
private static void tryVector() {
Vector nestedVector = new Vector();
nestedVector.add(NestedType.builder().longValue(1L).build());
nestedVector.add(NestedType.builder().longValue(2L).build());
Vector vector = new Vector();
vector.add(KnownType.builder().nestedTypeList(nestedVector).build());
List<Long> longList = (List<Long>)vector.stream()
.flatMap(item -> ((KnownType)item).getNestedTypeList().stream())
.map(nestedItem ->((NestedType)nestedItem).getLongValue())
.collect(Collectors.toList()); // works
longList.forEach(System.out::println);
List<Long> longList2 = ((Vector<KnownType>)vector).stream()
.flatMap(item -> ((Vector<NestedType>)item.getNestedTypeList()).stream())
.map(nestedItem -> nestedItem.getLongValue())
.collect(Collectors.toList()); // works
longList2.forEach(System.out::println);
List<Long> longList3 = vector.stream()
.flatMap(item -> ((KnownType)item).getNestedTypeList().stream()
.map(e -> (NestedType)e))
.map(NestedType::getLongValue) // Non-static method cannot be referenced from a static context
.collect(Collectors.toList());
List<Long> longList4 = vector.stream()
.flatMap(item -> ((KnownType)item).getNestedTypeList().stream())
.flatMap(nestedItem -> ((NestedType)nestedItem).getLongValue())
.collect(Collectors.toList()); // Required: List<Long> Found: List<Object>
}
}