【发布时间】:2021-01-11 03:15:27
【问题描述】:
你如何使用纯函数式编程(没有 if 条件)来完成下面的 transform() 方法的等效操作。
Meta:我很感激标题编辑,我不知道如何用“功能性”来表达这个问题
public class Playground {
private static Optional<Map<String,Integer>> transform(List<Tuple<String,Optional<Integer>>> input) {
if (input.stream().anyMatch(t->t.second.isEmpty())) return Optional.empty();
Map<String, Integer> theMap = input.stream()
.map(t -> new Tuple<>(t.first, t.second.get()))
.collect(Collectors.groupingBy(
t1 -> t1.first,
Collectors.mapping(t2 -> t2.second, toSingle())));
return Optional.of(theMap);
}
@Test
public void collect() {
List<Tuple<String,Optional<Integer>>> input1 = new ArrayList<>();
input1.add(new Tuple<>("foo", Optional.of(1)));
input1.add(new Tuple<>("bar", Optional.empty()));
Optional<Map<String,Integer>> result1 = transform(input1);
assertTrue(result1.isEmpty());
List<Tuple<String,Optional<Integer>>> input2 = new ArrayList<>();
input2.add(new Tuple<>("foo", Optional.of(1)));
input2.add(new Tuple<>("bar", Optional.of(2)));
Optional<Map<String,Integer>> result2 = transform(input2);
assertTrue(result2.isPresent());
assertEquals((int)1, (int)result2.get().get("foo"));
assertEquals((int)2, (int)result2.get().get("bar"));
}
private static class Tuple<T1,T2> {
public T1 first;
public T2 second;
public Tuple(T1 first, T2 second) {
this.first = first;
this.second = second;
}
}
public static <T> Collector<T, ?, T> toSingle() {
return Collectors.collectingAndThen(
Collectors.toList(),
list -> list.get(0)
);
}
}
【问题讨论】:
-
唯一的
if语句的目的似乎是在两个替代返回值之间进行选择。我不确定它是否符合您的标准,但应该可以改用三元运算符。 -
或者,您应该能够强制
Optional.filter()完成if的工作,然后在您真正想要执行计算的情况下跟进Optional.map()。 -
你可以简单地使用
.collect(Collectors.toMap(t -> t.first, t -> t.second.get(), (a,b) -> a))而不是.map(t -> new Tuple<>(t.first, t.second.get())) .collect(Collectors.groupingBy(t1 -> t1.first, Collectors.mapping(t2 -> t2.second, toSingle()))) -
@Holger 谢谢你,一个有用的简化!
标签: java java-8 functional-programming