Java 8:从列表中查找最小值的索引

2022-09-03 04:41:45

假设我有一个包含元素的列表。(34, 11, 98, 56, 43)

使用Java 8流,我如何找到列表中最小元素的索引(例如,在本例中为1)?

我知道这可以在Java中使用轻松完成。但是,我正在研究一个类似Scala的解决方案,我们可以简单地说要获得最小值的指数。list.indexOf(Collections.min(list))List(34, 11, 98, 56, 43).zipWithIndex.min._2

使用流或lambda表达式(例如Java 8特定功能)可以完成任何事情来实现相同的结果。

注意:这仅用于学习目的。我在使用实用程序方法时没有任何问题。Collections


答案 1
import static java.util.Comparator.comparingInt;

int minIndex = IntStream.range(0,list.size()).boxed()
            .min(comparingInt(list::get))
            .get();  // or throw if empty list

正如@TagirValeev在他的回答中提到的,你可以通过使用而不是来避免拳击,但代价是模糊了意图:IntStream#reduceStream#min

int minIdx = IntStream.range(0,list.size())
            .reduce((i,j) -> list.get(i) > list.get(j) ? j : i)
            .getAsInt();  // or throw

答案 2

你可以这样做:

int indexMin = IntStream.range(0, list.size())
                .mapToObj(i -> new SimpleEntry<>(i, list.get(i)))
                .min(comparingInt(SimpleEntry::getValue))
                .map(SimpleEntry::getKey)
                .orElse(-1);

如果列表是随机访问列表,则为常量时间操作。API 缺少标准元组类,因此我使用 from 该类作为替代。getSimpleEntryAbstractMap

因此,从列表中生成索引流,从该列表中将每个索引映射到其相应的值。然后,您可以通过在值(列表中的值)上提供比较器来获得最小元素。从那里将 映射到从中获取索引的 (如果可选值为空,则为 -1)。IntStream.rangeOptional<SimpleEntry<Integer, Integer>>Optional<Integer>

顺便说一句,我可能会使用一个简单的for循环来获取最小值的索引,因为/ do 2的组合会传递到列表中。minindexOf

您可能还有兴趣检查使用JDK8和lambda(java.util.stream.Streams.zip)的Zipping流


推荐