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?
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.