2016-07-31 112 views
8

我想了解流和遇到问题: 我想获得列表的最小值并将其分配给一个int变量。 对于我做了以下内容:Java 8流“ifPresent”

List<Integer> list = new ArrayList<>(); 
    list.add(1); 
    list.add(2); 
    list.add(3); 
    int smallest = list.stream().min(Integer::compareTo).get(); 
    System.out.println(smallest); 

这工作得很好,我得到1结果。 问题是在检查.isPresent之前,IDE会提示Optional.get。 要解决,我使用的略有不同ifPresent方法和尝试以下操作:

int smallest = list.stream().min(Integer::compareTo).ifPresent(integer -> integer); 

不幸的是,因为我得到警告,这并不工作:Bad return type in Lambda, Integer cannot be converted to void. 我的问题总算是:我怎样才能分钟值赋给int smallest变量与检查ifPresent?

+1

你首先必须明白为什么你得到一个可选的,而不是一个整数:因为该流可能是空的,因此可能没有任何最小值。然后,如果流为空,则需要决定想要得到的结果。然后,一旦你知道你想要什么,你就可以通过查看Optional的文档来选择正确的方式来获得结果。 –

+1

'ifPresent'接受'Consumer'作为它的参数,它消耗输入值并不返回任何内容。 –

回答

6

Stream#min回报Optional因为一般流可以是空的,所以不可能有极小值。

Optional<Integer> minimal = list.stream().min(Integer::compareTo); 

从可选获得价值,你需要有一些备用值

Integer absent = Integer.MIN_VALUE; 

最简单的办法是使用orElse

Integer smallest = minimal.orElse(absent); 

久一点会是isPresent

Integer smallest = minimal.isPresent() ? minimal.get() : absent; 
+0

所以orElse方法返回一个整数类型而不是像.min方法那样的可选项? –

+1

是的,在这个例子中它将是'Integer'。一般而言'可选'可以包含任何类型'T'的值,所以'orElse'返回那个类型'T' –

+0

非常感谢! –

7

以下是我会怎么做它:结果

package lambdas; 

import java.util.ArrayList; 
import java.util.List; 

/** 
* Created by Michael 
* Creation date 7/31/2016. 
* @link https://stackoverflow.com/questions/38688119/java-8-streams-ifpresent 
*/ 
public class MinimumExample { 

    public static void main(String[] args) { 
     List<Integer> list = new ArrayList<>(); 
     int smallest = list.stream().min(Integer::compareTo).orElse(Integer.MIN_VALUE); 
     System.out.println(smallest); 
    } 
} 
+0

如果'.min'方法返回一个Optional,那么'.orElse'方法需要返回一个Integer。 '.orElse'然后调用'.get'方法吗? –

+0

此代码可以正常运行。它受到你接受的答复的支持。你的问题是什么? – duffymo

1

ifPresent方法以Consumer<? super T>作为参数。简单地说,它应该是一个没有return声明的行动。您可以打印该值,如果它存在,就像

[...].ifPresent(System.out::print); 

但这不是IDEA所说的。我想,你只需要保存Option<Integer>实例,然后通过isPresent检查:

Optional<Integer> o = list.stream().min(Integer::compareTo); 
if (o.isPresent()) { 
    smallest = o.get(); 
} 

当然,还有更方便的方式与orElse

smallest = o.orElse(Integer.MIN_VALUE); 

或三元运算符:

smallest = o.isPresent() ? o.get() : Integer.MIN_VALUE;