Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert multiple list into single list using Java streams?

Tags:

I have an class A with multiple List members.

class A {     List<X> xList;     List<Y> yList;     List<Z> zList;          // getters and setters }  class X {      String desc;      String xtype;           // getters and setters     }  class Y {        String name;     String ytype;          //getters and setters }  class Z {     String description;     String ztype;          // getters and setters     } 

And a class B with just 2 attributes:

class B {     String name;     String type;      } 

I need to iterate through the various lists in class A and create class B object and add to a list like this:

public void convertList(A a) {      List<B> b = new ArrayList<>();          if (!a.getXList().isEmpty()) {       for (final X x : a.getXList()) {            b.add(new B(x.getDesc(), x.getXType()));       }     }          if (!a.getYList().isEmpty()) {       for (final Y y : a.getYList()) {            b.add(new B(y.getName(), y.getYType()));       }     }          if (!a.getZList().isEmpty()) {       for (final Z z : a.getZList()) {            b.add(new B(z.getDescription(), z.getZType()));       }     }     } 

As the if and for loops are repeated here.

How can I achieve this using Java streams?

Note: There is no relation between the classes X, Y and Z and there is no common interface.

like image 833
DarkCrow Avatar asked May 25 '20 10:05

DarkCrow


People also ask

How do you combine streams in Java?

concat() in Java. Stream. concat() method creates a concatenated stream in which the elements are all the elements of the first stream followed by all the elements of the second stream. The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel.

How do you flatten a stream List?

The standard solution is to use the Stream. flatMap() method to flatten a List of Lists. The flatMap() method applies the specified mapping function to each element of the stream and flattens it.

Can we convert stream to List in Java?

Stream class has toArray() method to convert Stream to Array, but there is no similar method to convert Stream to List or Set. Java has a design philosophy of providing conversion methods between new and old API classes e.g. when they introduced Path class in JDK 7, which is similar to java.


2 Answers

Since your X, Y and Z types don't have a common super-type, you have to convert them into some common type, such as Map.Entry<String,String>.

You can create a Stream of all pairs of names and types, and then map it to instances of B:

List<B> b =     Stream.of(         a.getXList().stream().map(x -> new SimpleEntry<>(x.getDesc(),x.getXType())),         a.getYList().stream().map(y -> new SimpleEntry<>(y.getName(),y.getYType())),         a.getZList().stream().map(z -> new SimpleEntry<>(z.getDescription(),z.getZType())))           .flatMap(Function.identity())           .map(e -> new B(e.getKey(), e.getValue()))           .collect(Collectors.toList()); 

Or directly generate B instances:

List<B> b =     Stream.of(         a.getXList().stream().map(x -> new B(x.getDesc(),x.getXType())),         a.getYList().stream().map(y -> new B(y.getName(),y.getYType())),         a.getZList().stream().map(z -> new B(z.getDescription(),z.getZType())))           .flatMap(Function.identity())           .collect(Collectors.toList()); 
like image 176
Eran Avatar answered Oct 22 '22 12:10

Eran


You can use Stream.concat() like following

public List<B> convertList (A a) {     return Stream.concat(Stream.concat(a.getXList().stream().map(x -> new B(x.getDesc(), x.getXType()))             , a.getYList().stream().map(y -> new B(y.getName(), y.getYType())))             , a.getZList().stream().map(z -> new B(z.getDescription(), z.getZType()))).collect(Collectors.toList()); } 
like image 29
janith1024 Avatar answered Oct 22 '22 14:10

janith1024