是否可以在分组时通过集合收集字符串?这就是它在 Java 8 中的工作方式:
Map<String, String> discountOptions = p.getDiscountOptions().Stream()
.collect(groupingBy(
this::getDiscountName,
Collectors.mapping(this::getValue, Collectors.joining(","))));
我很好奇,在 Google Guava 中是否有简洁的方法来做到这一点?这就是我尝试在 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);
}
});
最佳答案
你不会得到比 Java 8 流 API 更简洁的东西,因为它存在的原因是改进这些类型的操作。
Java 8 之前的函数式编程可以使用 Guava 的函数式实用程序进行临时装配,但是 as they warn :
As of Java 7, functional programming in Java can only be approximated through awkward and verbose use of anonymous classes.... Excessive use of Guava's functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code.... Imperative code should be your default, your first choice as of Java 7.
这是您的代码的命令式翻译:
private static final Joiner COMMA_JOINER = Joiner.on(",");
ListMultimap<String, String> groupedByDiscountName = ArrayListMultimap.create();
for (DiscountOption option : p.getDiscountOptions()) {
groupedByDiscountName.put(getDiscountName(option), getValue(option));
}
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
for (Entry<String, Collection<String>> e : groupedByDiscountName.asMap().entrySet()) {
builder.put(e.getKey(), COMMA_JOINER.join(e.getValues());
}
Map<String, String> discountOptions = builder.build();
它更短且更易于阅读。鉴于您当前的 API,这大概是您使用 Java 7 所能做的最好的事情。
也就是说,您可能会考虑重新检查您的 API - 特别是您使用静态方法(getDiscountName()
、getValue()
)来提取数据很奇怪来自您的 DiscountOption
类的数据 - 这些似乎是实例方法的明确候选者。同样,您可能会考虑创建一个 Discounts
类,其中包含一个或多个 DiscountOption
实例并提供一个返回逗号分隔字符串的 toString()
。然后您只需要构造您的 Discounts
对象就可以了。
关于java - 是否可以使用 Java Guava 将连接器(收集器、累加器)应用于函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37588762/