6

I am trying to get into Java 8 and get my head around streams and lambdas to solve various problems and got stuck on this specific one which I normally use a forEach and store the values in a Map to solve.

How would you write the code to get the expected list using the new features in Java 8 ?

List<Integer> voterA = Arrays.asList(1,2,3,4,5);
List<Integer> voterB = Arrays.asList(1,2,3,4,5);
List<List<Integer>> votes = Arrays.asList(voterA, voterB);

// expected list = (2,4,6,8,10)
List<Integer> sumVotes = ...
2
  • 2
    How would you solve it with enhanced-for-loop(s)? Commented Feb 18, 2015 at 19:48
  • Take a look to question Commented Feb 18, 2015 at 21:23

2 Answers 2

7

That one isn't really doable the way you're hoping. The closest you could get would probably be

IntStream.range(0, voterA.size())
    .mapToObj(i -> voterA.get(i) + voterB.get(i))
    .collect(toList());

...but there's no "zip" operation on streams, largely because two different streams can have backing spliterators that split at different points, so you can't line them up properly.

Sign up to request clarification or add additional context in comments.

8 Comments

It's annoying that I can see exactly how I'd do this in C# in LINQ - in a pretty general way - but I'm still groping around when it comes to Java streams. Maybe when I get more practice...
I mean...I look at the Spliterator interface, and I don't think there's any nice way to do zipping, just because trySplit allows the split to happen at an arbitrary point. You can do indexing efficiently with SUBSIZED spliterators, and fall back to a less-efficient sequential approach for other spliterators, but I don't think there's anything you can do with zipping.
Here's the C# version, complete with 3 voters with different lengths of lists: gist.github.com/jskeet/2c1db126e424cf58cb69
I mean, that translates pretty directly to gist.github.com/lowasser/e1b57e1a9358cbf52cc6
@LouisWasserman Getting the spliterators to line up their splits, especially in parallel, is certainly a big issue. Another issue is that you really want the result of zipping two (or N) streams to be another stream. What would its element type be? A Pair or Tuple class? Or provide a BiFunction that combines elements pairwise? But we don't have N-ary functions. We're still wrestling with this, but it doesn't look like anything will emerge until we have value types (> Java 9).
|
2

JDK doesn't provide the 'zip' API. But it can be done with third library abacus-common:

List<Integer> voterA = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> voterB = Arrays.asList(1, 2, 3, 4, 5);

List<Integer> sumVotes = Stream.zip(voterA, voterB, (a, b) -> a + b).toList();

Disclosure: I'm the developer of abacus-common.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.