2015-02-07 87 views
1

我有一个ArrayList和来自控制台的另一个int。 我想使用stream()来查找列表中最接近的数字。 为什么这不起作用:在java中使用.stream()的整数

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 2015-02-07 15:00:22

+0

您将需要对过滤的列表进行排序或对其应用最小()操作。 findFirst()不是最接近的,但是大于nextNumber的第一个数字。 – eckes 2015-02-07 17:53:35

回答

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参与,并且不需要在任何步骤来autobox整数,而你实际检索最小数量满足标准,不是第一个之一。

+2

然后你也可以保存数组的创建:'Pattern.compile(“”).splitAsStream(scn.nextLine())。mapToInt(Integer :: parseInt)...' – Holger 2015-02-09 12:59:08

+0

是的,很棒的一点。如果OP实际上需要'findFirst()'语义,那甚至可以短路正则表达式评估。 – 2015-02-09 14:54:56

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)变换StreamIntStream,这是需要的下一个操作:

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

您发布的代码不会编译,因为.findFirst()返回Optional<Integer>而不是Integer。它也是语义错误,因为第一个元素不一定是最小的,因为您的Stream未排序。