Search code examples
javajava-stream

Java stream: map object data members to int list


I need put the A.a and A.b to a int list in sequence:

class A {
    int a;
    int b;
}

A a = new A();
a.a = 1;
a.b = 2;

List<A> list = Arrays.asList(a);
List<Integer> intList = list.stream().map(?).collect(Collectors.toList());
assert intList.equals(Arrays.asList(1,2));

How to do this using a Java stream?
And how to do this in reverse?

NOTE

By "in reverse" I mean to create a List<A> according to List<Integer>, because the example code is create List<Integer> according to List<A>.


Solution

  • Just create a Stream of the integers of A and flatMap this Stream so the integers of A anA become part of the outer Stream.

      List<Integer> intList = list.stream()
        .flatMap(anA -> Stream.of(anA.a, anA.b))
        .collect(Collectors.toList());
    

    EDIT
    You asked also for the other way round:

      IntStream.range(0, intList.size() / 2)
       .mapToObj(i -> new A(intList.get(2*i), intList.get(2*i+1)))
       .collect(Collectors.toList());
    

    This implies a constructor in class A:

    A(int a, int b) {
        this.a = a;
        this.b = b;
    }
    

    A quick test:

    public static void main(String[] args) throws Exception {
        List<A> list = Arrays.asList(new A(1, 2), new A(3, 4), new A(11, 22));
        List<Integer> intList = list.stream().flatMap(anA -> Stream.of(anA.a, anA.b)).collect(Collectors.toList());
        System.out.println(intList);
        List<A> aList = IntStream.range(0, intList.size() / 2).mapToObj(i -> new A(intList.get(2 * i), intList.get(2 * i + 1))).collect(Collectors.toList());
        System.out.println(aList);
    }
    

    The output is:

    [1, 2, 3, 4, 11, 22]
    [[1|2], [3|4], [11|22]]