I'm facing the problem that I get a Vector
object (without generic type), and I need to extract values from there. Right now it works by doing nested foreach:
List<Long> longList = new ArrayList<>();
vector.forEach(item ->
((KnownType)item).getAnotherVector().forEach(nestedItem ->
longList.add(((NestedKnownType)nestedItem).longValue())));
I've tried to change this code to something more readable by using Java 8 Streams:
List<Long> longList = vector.stream()
.flatMap(item -> ((KnownType)item).getAnotherVector().stream())
.flatMap(nestedItem -> ((NestedKnownType)nestedItem).longValue())
.collect(Collectors.toList());
This one above does not work because it says that it returns with List<Object>
instead of List<Long>
. If I add a cast before the longValue it still does not work. However, if I cast the original Vector
at the very beginning like this:
List<Long> longList = ((Vector<KnownType>)vector).stream()
.flatMap(item -> item.getAnotherVector().stream())
.flatMap(nestedItem -> ((NestedKnownType)nestedItem).longValue())
.collect(Collectors.toList());
then it compiles.
Question: is there a nice way with streams to extract out the value I need from this untyped vector? If not, why? In the first flatMap
call I'm casting the current element to a known type so the type context should be known after that... I just don't get it.
Fully working example with different options and outcomes:
// 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>
}
}