按谓词拆分Java列表,并为每个子列表映射不同的函数



我需要帮助完成一项相当常见的任务,但我不能清楚地完成它。

我有一个整数列表。

我想要的:拆分数组在两个谓词和应用不同的函数为每个

例如,我丑陋的解决方案:

Map<Boolean, List<Integer>> collect = 
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.collect(Collectors.<Integer>partitioningBy(e -> e % 2 == 0));
List<Integer> result = collect.get(true)
.stream()
.map(x -> x * x)
.collect(Collectors.toList());
result.addAll(collect.get(false)
.stream()
.map(x -> x + 2)
.collect(Collectors.toList()));

System.out.println(result);

但我认为这个任务可以用FP的方式解决,用收集器,但不知道怎么做。是的,我只能使用Java 8,没有第三方库,如Guava/Apache Commons等。

希望你能帮助和教我新的方法!

谢谢,对不起我的英语!

如果您不需要更改输入Stream的顺序,则可以跳过分区:

List<Integer> result =
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.map(x -> x % 2 == 0 ? x * x : x + 2)
.collect(Collectors.toList());

输出:

[3, 4, 5, 16, 7, 36, 9, 64, 11]

如果希望对分区进行分组,可以使用自定义Collector:

List<Integer> result =
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.collect(Collector.of (
() -> {
Map<Boolean,List<Integer>> map = new HashMap<>();
map.put (true, new ArrayList<> ());
map.put (false, new ArrayList<> ());
return map;
},
(m,i) -> {
if (i % 2 == 0) 
m.get (true).add(i*i); 
else 
m.get (false).add(i+2);
},
(b1,b2)-> {
b1.putAll (b2);
return b1;
},
m -> {
List<Integer> l = m.get(true);
l.addAll (m.get(false));
return l;
}));

输出:

[4, 16, 36, 64, 3, 5, 7, 9, 11]

您可以使用groupingBy:

Map<Boolean, List<Integer>> grouped = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.collect(Collectors.groupingBy(e -> e % 2 == 0));        
System.out.println("" + grouped);

输出:

{false=[1, 3, 5, 7, 9], true=[2, 4, 6, 8]}

然后根据需要处理地图

最新更新