gpt4 book ai didi

lambda - Java 8 - 查找数组中的领导者

转载 作者:行者123 更新时间:2023-12-02 06:39:51 26 4
gpt4 key购买 nike

我正在尝试学习 Java 8 的功能,尤其是它的函数式编程方面。所以我试图解决一个问题:在数组中查找领导者 - 领导者是一个比数组中右侧所有元素都大的元素。

例如:

输入数组:{ 98, 23, 54, 12, 20, 7, 27 }

输出:领导者 - 27 54 98

现在,我已经使用通常的迭代方法解决了这个问题,如下所示。

private static void findLeaders(int[] array) {
int currentLeader = array[array.length - 1];
System.out.println(currentLeader);
for(int i = array.length - 1; i >= 0; i--) {
if(array[i] > currentLeader) {
System.out.println(array[i]);
currentLeader = array[i];
}
}
}

我尝试使用 Java 8 解决这个问题,但除了编写这段代码之外我无能为力,该代码再次出现编译错误:

Function<Integer, Integer> checkLeader = i ->  i > currentLeader ? i : currentLeader;

Error: Local variable currentLeader defined in an enclosing scope must be final or effectively final

现在我如何使用 Java 8 的功能解决同样的问题。

最佳答案

传统的命令式方法对我来说似乎是最好的方法,同时考虑到性能和可读性/易于维护。尽管如此,这是我使用流和一些函数式编程的尝试:

List<Integer> leaders = IntStream.rangeClosed(1, array.length)
.mapToObj(i -> array[array.length - i])
.collect(toLeaders());

在这里我创建了一个 1..n封闭范围,然后在mapToObj内,转换索引1n - 1 ,索引2n - 2 , 等等。我立即使用这个转换后的索引来获取数组的相应元素,最终在自定义收集器的帮助下将其收集到列表中。此自定义收集器由 toLeaders() 返回辅助方法:

private static Collector<Integer, ?, List<Integer>> toLeaders() {
BiConsumer<List<Integer>, Integer> accumulator = (leaders, n) -> {
if (leaders.isEmpty() || n > leaders.get(leaders.size() - 1)) {
leaders.add(n);
}
};
return Collector.of(ArrayList::new, accumulator, (leaders1, leaders2) -> {
leaders2.forEach(n -> accumulator.accept(leaders1, n));
return leaders1;
});
}

BiConsumer<List<Integer>, Integer> accumulator接受两个值:包含迄今为止找到的领导者的列表,以及流中的元素。这个 Biconsumer 检查给定的数字是否是领导者,如果检查成功,则将该数字添加到给定的领导者列表中。

然后,通过 Collector.of 创建使用该累加器的收集器。实用程序,它也接受 Supplier 将容纳领导者的可变结构(这是 ArrayList::new )和 BinaryOperator 组合器负责合并先前创建的两个领导者列表(仅当流并行时才使用)。该组合器使用先前声明的 accumulator双消费者。

关于lambda - Java 8 - 查找数组中的领导者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44319044/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com