使用 Java 中的 .stream() 比较整数

3

我有一个ArrayList和另一个来自控制台的int。我想使用stream()方法在列表中找到比这些int更大的最接近的数字。为什么下面的代码无法实现:

Scanner scn = new Scanner(System.in);
int numOfRows = scn.nextInt();
int nextNumber = scn.nextInt();
for (int i = 0; i < numOfRows; i++) {
    String[] input = scn.nextLine().split(" ");
    ArrayList<Integer> nums = new ArrayList<>();
    for (int j = 0; j < input.length; j++) {
        nums.add(Integer.parseInt(input[j]));
    }
    nextNumber = nums.stream().filter(x -> x > nextNumber).findFirst();
    System.out.println(nextNumber); 
}

1
你忘了告诉我们编译器的错误信息(这段代码无法编译)。 - Seelenvirtuose
你需要对筛选后的列表进行排序或应用minimum()操作。findFirst()不是最接近下一个数字的数字,而是第一个比下一个数字大的数字。 - eckes
2个回答

3

您当前的问题非常容易解决:

Optional<Integer> oi = nums.stream()
                           .filter(x -> x > nextNumber)
                           .findFirst();
System.out.println(oi.isPresent()? "Found: "+oi.get() : "Not found");

然而,如果您想编写最优代码以实现所需功能,则不是正确的方法。更好的选择是这样的:
OptionalInt oi = Stream.of(scn.nextLine().split(" "))
                       .mapToInt(Integer::parseInt)
                       .filter(i -> i > nextNumber)
                       .min();
System.out.println(oi.isPresent()? "Found: "+oi.getAsInt() : "Not found");

优点是您不需要涉及ArrayList,也不需要在任何步骤中进行整数自动装箱,并且实际上检索满足条件的最小数字,而不是第一个数字。

2
然后,您还可以保存数组创建:Pattern.compile(" ") .splitAsStream(scn.nextLine()).mapToInt(Integer::parseInt) ... - Holger
是的,非常好的观点。如果OP实际上需要findFirst()语义,甚至可以短路正则表达式评估。 - Marko Topolnik

2
如果您想找到比某个界限大的最小数:
private int smallestLargerThan(int x, List<Integer> list) {
    return list.stream().filter(n -> n > x).mapToInt(n -> n).min();
}

.filter(n -> n > x)会删除所有小于或等于x的值。

.mapToInt(n -> n)Stream转换为IntStream,这是下一个操作所必需的:

.min()返回IntStream中最小的元素。由于此时的流只包含大于x的值,因此返回的元素就是你要找的数字。

你发布的代码无法编译,因为.findFirst()返回的是Optional<Integer>而不是Integer。从语义上讲,这也是错误的,因为第一个元素未必是最小的,因为你的Stream是未排序的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接