group a list of triples into map with pair key

lapots :

I have a list of triples

List<Triple<String, String, String>> triplets; 

I want to group into a map like this

Map<Pair<String, String>, String> mapping;

Where value of the map is the third element of the triple. And in case of the same key it should override the remaining third value.

For example

def triples = [ {a, b, c} ; {a, d, e} ; {a, b, f } ]
// grouping
def map = [ {a,b} : c ; {a, d} : e ]

How to do that using Java 8 and its grouping in streams?

Ravindra Ranwala :

This should do the trick:

Map<Pair<String, String>, String> result = triplets.stream()
    .collect(
        Collectors.toMap(
            t -> new Pair(t.getOne(), t.getTwo()),
            Triple::getThree,
            (v1, v2) -> v2
        )
    );

Example of a partial pair class:

public class Pair<T, U> {
    //...

    @Override
    public int hashCode() {
        return one.hashCode() + two.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Pair))
            return false;
        Pair p = (Pair) obj;
        return p.one.equals(one) && p.two.equals(two);
    }
}

The HashMap class uses equals method to identify key objects uniquely. So you first need to override equals and hashcode methods to show the logical equality of the Pair objects for the Map class.

Then come back to the streams and lambda. For each triplet use Collectors.toMap with the Pair object as the key and the other remaining value of the Triplet as the value. Then provide a mergeFunction to handle key conflicts. In your case, you need to keep the previous value while discarding new value. That's all you need to do.

Update

I have updated the merge function as per the below comments.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=114162&siteId=1