1

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>
    }
}
maestro
  • 671
  • 1
  • 13
  • 27

0 Answers0