18
List<Rate> rateList = 
       guestList.stream()
                .map(guest -> buildRate(ageRate, guestRate, guest))
                .collect(Collectors.toList());  

class Rate {
    protected int index;
    protected AgeRate ageRate;
    protected GuestRate guestRate;
    protected int age;
}

In the above code, is it possible to pass index of guestList inside buildRate method. I need to pass index also while building Rate but could not manage to get index with Stream.

Jacob G.
  • 28,856
  • 5
  • 62
  • 116
Amit
  • 451
  • 1
  • 6
  • 19
  • 2
    you will need to fold(or reduce in java8). it's very annoying that java 8 implements (so-called) functional programming without providing tuple. – Jason Hu Mar 03 '18 at 03:55
  • @JasonHu Update: Java 16+ offers a nominal tuple, [`record`](https://openjdk.org/jeps/395). A record can even be declared locally within a method as well as nested in another class or written separately. – Basil Bourque Mar 28 '23 at 16:06

2 Answers2

12

You haven't provided the signature of buildRate, but I'm assuming you want the index of the elements of guestList to be passed in first (before ageRate). You can use an IntStream to get indices rather than having to deal with the elements directly:

List<Rate> rateList = IntStream.range(0, guestList.size())
    .mapToObj(index -> buildRate(index, ageRate, guestRate, guestList.get(index)))
    .collect(Collectors.toList());
Jacob G.
  • 28,856
  • 5
  • 62
  • 116
  • Is there `Instream. range(0, size). stream()` ? – Amit Mar 03 '18 at 04:12
  • `IntStream` is already a `Stream`, so there's no need to *re-stream* it. – Jacob G. Mar 03 '18 at 04:13
  • There is one extra `.stream` in your code, please remove that. I will accept your answer – Amit Mar 03 '18 at 05:36
  • Oh whoops! I originally copied your code and forgot to remove the call to `stream`. My apologies. – Jacob G. Mar 03 '18 at 05:37
  • 3
    To be nitpicking, `IntStream` is not already a `Stream`, but supports almost the same operations, as far as there are `int` specific specializations. For all other operations, you can call `boxed()` to truly have a `Stream`. – Holger Mar 03 '18 at 09:06
5

If you have Guava in your classpath, the Streams.mapWithIndex method (available since version 21.0) is exactly what you need:

List<Rate> rateList = Streams.mapWithIndex(
        guestList.stream(),
        (guest, index) -> buildRate(index, ageRate, guestRate, guest))
    .collect(Collectors.toList());
fps
  • 33,623
  • 8
  • 55
  • 110