5

I have a class ABC which contains two integer fields

public class ABC{
  private Integer x;
  private Integer y;

   // getters and setters
}

I have two lists : xValues and yValues, which contain list of integers of x and y values respectively.

List<Integer> xValues = fetchAllXValues();  //say list xValues contains {1,2,3}
List<Integer> yValues = fetchAllYValues();  //say list yValues contains {7,8,9}

Now what I want is to create an ABC object using each values of xValues list with each values of yValues list. I dont want to use nested for loop. What would be a more efficient way to solve this?

sample output objects for ABC are:

     ABC(1,7);
     ABC(1,8);
     ABC(1,9);
     ABC(2,7);
     ABC(2,8);
     ABC(2,9);
     ABC(3,7);
     ABC(3,8);
     ABC(3,9);
Akash Raveendran
  • 559
  • 1
  • 9
  • 22

3 Answers3

10

Iterate over the first list and on every iteration iterate over the second list:

xValues.stream()
    .flatMap(x -> yValues.stream().map(y -> new ABC(x, y)))
    .collect(toList());
Sergii Lagutin
  • 10,561
  • 1
  • 34
  • 43
  • Doesn't lambda expression require constants in its evaluation? I will try this once and come back to you – Akash Raveendran Jul 25 '16 at 13:18
  • 1
    @AkashRaveendran what do you mean `lambda expression require constants in its evaluation`? – Sergii Lagutin Jul 25 '16 at 13:31
  • once I used lambda expression to in forEach function. But I used to get an error that I cant use changing values for a field inside lambda expression. It used to ask me to change the field to a static final. Thats why I asked you Doesn't lambda expression require constants in its evaluation. However when I tried out this code now, there was no such error. – Akash Raveendran Jul 25 '16 at 13:49
  • 1
    @AkashRaveendran yea, you're right. you can't change values outside of lambda. and in this code, you don't do it – Sergii Lagutin Jul 25 '16 at 13:55
  • Can I add an increment value in this flatMap function too? Like I have an increment value 'i' which I initialize to 1 for each 'x' in flatMap and for each 'y' in the map I increment 'i' on each object of 'yValues' list. – Akash Raveendran Jul 26 '16 at 12:15
  • @AkashRaveendran no. you should find other ways – Sergii Lagutin Jul 26 '16 at 12:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/118311/discussion-between-akash-raveendran-and-sergey-lagutin). – Akash Raveendran Jul 26 '16 at 12:22
1

If you are open to using a third party library, you could use Eclipse Collections which has rich and concise APIs directly available under collections.

MutableList<Integer> xValues = ListAdapter.adapt(fetchAllXValues());  
MutableList<Integer> yValues = ListAdapter.adapt(fetchAllYValues());  

xValues.flatCollect(x -> yValues.collect(y -> new ABC(x, y)));

flatCollect() here is equivalent to Java 8 streams flatMap(). Similarly collect() is equivalent to map()

Note: I am a committer for Eclipse Collections.

itohro
  • 151
  • 5
1

To solve this you can also use some external libs, for example with StreamEx it will look like:

    StreamEx.of(xValues).cross(yValues)
      .map(entry -> new ABC(entry.getKey(), entry.getValue()))
      .collect(Collectors.toList());