Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8: Executing reduce operation on Stream

Tags:

I've got a java.util.stream.Stream containing key value pairs like:

<1,3> <1,5> <3,1> <4,2> <4,7> <4,8>

Now I would like to merge all entries, which have got the same key:

<1,[3,5]>  <3,[1]> <4,[2,7,8]>

The data is already sorted, so only consecutive datasets have to be merged.

Now I'm searching for a way to transform the the content of the stream like above, without loading all datasets into memory.

I'd prefer to get a java.util.stream.Stream as result with a different object type containing a list of values instead of a single value.

My only approach is a custom iterator, which performs the merge, but it seems to be pretty ugly to convert to an iterator and back to stream.

What is the best approach for it?

like image 285
Spille Avatar asked Jun 05 '17 23:06

Spille


People also ask

What does reduce () method does in stream?

Reducing is the repeated process of combining all elements. reduce operation applies a binary operator to each element in the stream where the first argument to the operator is the return value of the previous application and second argument is the current stream element.

What is reduce in Java 8 streams?

In Java, reducing is a terminal operation that aggregates a stream into a type or a primitive type. Java 8 provides Stream API contains set of predefined reduction operations such as average(), sum(), min(), max(), and count(). These operations return a value by combining the elements of a stream.

Which terminal operations on the stream class are reductions?

A reduction is a terminal operation that aggregates a stream into a type or a primitive. The Java 8 Stream API contains a set of predefined reduction operations, such as average , sum , min , max , and count , which return one value by combining the elements of a stream.

Does Java 8 stream improve performance?

Java 8 introduced streams. Not to be confused with input/output streams, these Java 8+ streams can also process data that goes through them. It was hailed as a great new feature that allowed coders to write algorithms in a more readable (and therefore more maintainable) way.


1 Answers

Here is the solution by SteamEx.

int[][] datasets = { { 1, 3 }, { 1, 5 }, { 3, 1 }, { 4, 2 }, { 4, 7 }, { 4, 8 } };

StreamEx.of(datasets) //
        .collapse((a, b) -> a[0] == b[0], groupingBy(a -> a[0], mapping(a -> a[1], toList()))) //
        .forEach(System.out::println);

you can replace int[] with your dataset object. We can add peek to verify if it's lazy loading/calculation:

StreamEx.of(datasets) //
        .peek(System.out::println) //
        .collapse((a, b) -> a[0] == b[0], groupingBy(a -> a[0], mapping(a -> a[1], toList()))) //
        .limit(1) //
        .forEach(System.out::println);
like image 192
user_3380739 Avatar answered Oct 04 '22 14:10

user_3380739