Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reducing Map by using Java 8 Stream API

I have a Map in the following form:

Map<Integer, Map<String,Double>> START

Let INNER be the inner map, i.e.

Map<String,Double>

For example, I'd like to reduce START map in a new one

Map<Integer, Double> END

which have the same keys, but different values. In particular, for each key, I want the new Double value be the SUM of values in the INNER map for the corresponding key.

How could I achieve this by using JAVA 8's STREAM API?

Thanks everyone.

EDIT: A sample map is

------------------------------
|      |  2016-10-02   3.45   |
| ID1  |  2016-10-03   1.23   |
|      |  2016-10-04   0.98   |
------------------------------
|      |  2016-10-02   1.00   |
| ID2  |  2016-10-03   2.00   |
|      |  2016-10-04   3.00   |
------------------------------

e I'd like a new map like the following one:

--------------------------------
|      |                       |
| ID1  |  SUM(3.45,1.23,0.98)  |
|      |                       |
--------------------------------
|      |                       |
| ID2  |  SUM(1.00,2.00,3.00)  |
|      |                       |
--------------------------------
like image 872
Fab Avatar asked Oct 04 '16 11:10

Fab


People also ask

What is map and reduce in stream API?

A map-reduce pipeline is analogous to a query on a data source. The Stream API has various intermediate operations for filtering (e.g., filter, distinct, allMatch) and transforming (e.g., map, flatMap); and terminal operations for collection (e.g., collect) and reduction (e.g., reduce, sum, count, average).

Can Java stream API be used for applying Map Reduce kind of transformations on collections?

stream — supports functional-style operations on streams of elements, such as map-reduce transformations on collections. Let's now dive into few simple examples of stream creation and usage — before getting into terminology and core concepts.

Does Java reduce map?

MapReduce is a processing technique and a program model for distributed computing based on java. The MapReduce algorithm contains two important tasks, namely Map and Reduce. Map takes a set of data and converts it into another set of data, where individual elements are broken down into tuples (key/value pairs).


2 Answers

This should be a good example:

public class Main {

    public static void main(final String[] args) {
        final Map<Integer, Map<String, Double>> tmp = new HashMap<>();
        tmp.put(1, new HashMap<String, Double>() {{
            put("1", 3.45);
            put("2", 1.23);
            put("3", 0.98);
        }});
        tmp.put(2, new HashMap<String, Double>() {{
            put("1", 1.00);
            put("2", 2.00);
            put("3", 3.00);
        }});

        System.out.println(tmp.entrySet().stream()
                .collect(
                    Collectors.toMap(Map.Entry::getKey, 
                    data -> 
                        data.getValue()
                            .values().stream()
                            .mapToDouble(Number::doubleValue).sum())));
    }

}

output will be {1=5.66, 2=6.0} and all this does is takes entry set of map, gets a stream of it and collects to new map sums of inner map values.

like image 97
GROX13 Avatar answered Oct 16 '22 10:10

GROX13


It will work for you

    Map<Integer, Double> collect = START.entrySet()
        .stream()
        .collect(
            Collectors.toMap(
                Map.Entry::getKey, 
                e -> e.getValue()
                      .values()
                      .stream()
                      .reduce(0d, (a, b) -> a + b)
                )
        );
like image 26
cringineer Avatar answered Oct 16 '22 08:10

cringineer