Is it possible to collect Strings over collection while grouping? That's how it works in Java 8:
Map<String, String> discountOptions = p.getDiscountOptions().Stream()
.collect(groupingBy(
this::getDiscountName,
Collectors.mapping(this::getValue, Collectors.joining(","))));
I'm curious, is there concise way to do it in Google Guava? That's how I try to replicate it in Guava:
Map<String, Collection<String>> stringCollectionMap = Multimaps.transformValues(
Multimaps.index(p.getDiscountOptions(),
new Function<DiscountOption, String>() {
@Override
public String apply(DiscountOption d) {
return getDiscountName(d);
}
}),
new Function<DiscountOption, String>() {
@Override
public String apply(DiscountOption d) {
return getValue(d);
}
}).asMap();
Map<String, String> discountOptions = Maps.transformValues(
stringCollectionMap,
new Function<Collection<String>, String>() {
@Override
public String apply(Collection<String> strings) {
return Joiner.on(",").join(strings);
}
});
You're not going to get anything more concise than the Java 8 streams API, since the reason it exists is to improve these kind of operations.
Pre-Java 8 functional programming can be jury-rigged with Guava's functional utilities, but as they warn:
Here's an imperative translation of your code:
It's shorter and easier to read. Given your current API this is roughly the best you can do with Java 7.
That said you might consider re-examining your API - in particular it's odd that you'd use static methods (
getDiscountName(),getValue()) to extract data from yourDiscountOptionclass - these seem like clear candidates to be instance methods. Similarly you might consider creating aDiscountsclass that contains one or moreDiscountOptioninstances and provides atoString()that returns your comma separated string. Then you just need to construct yourDiscountsobjects and you're good to go.