Java8:流findFirst结果
我想知道是否有一种方法可以消除Java8:流findFirst结果,java,intellij-idea,java-8,java-stream,optional,Java,Intellij Idea,Java 8,Java Stream,Optional,我想知道是否有一种方法可以消除findFirst().get()上的警告,而不使用.orElse(),因为我100%地知道每次都有结果,所以我从来没有得到NoTouchElementException 例如,让我们看看以下代码: List<String> myList = new ArrayList<>(); myList.add("Test"); myList.add("Example"); myList.add("Sth");
findFirst().get()
上的警告,而不使用.orElse()
,因为我100%地知道每次都有结果,所以我从来没有得到NoTouchElementException
例如,让我们看看以下代码:
List<String> myList = new ArrayList<>();
myList.add("Test");
myList.add("Example");
myList.add("Sth");
String fisrstString = myList.stream().findFirst().get(); // here I surely get "Test"
List myList=new ArrayList();
myList.添加(“测试”);
myList.add(“示例”);
我的清单。加上(“某物”);
字符串FIRSTSTRING=myList.stream().findFirst().get();//在这里,我肯定得到了“测试”
我不知道其他IDE是如何看待这一点的,但IntelliJ将其视为一个警告
不带“isPresent()”的“Optional.get()”
我想它可能不知道什么时候你能在那里得到NoTouchElementException,什么时候没有,或者我不知道为什么。我知道有很多方法可以解决这个警告(isPresent()
check,.orElse(something)
),但是使用无用的代码,所以我不想使用这些解决方案,因为它们太不必要了
你知道我能做什么,或者解释一下IDE是如何处理的吗?对我来说,最好的方法是使用函数编程并继续使用可选的。例如,如果需要将此字符串传递给某个服务,可以执行以下操作:
String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);
但这看起来不太好。相反,您可以使用函数式编程的优点,并执行以下操作:
myList.stream().findFirst().ifPresent(service::doSomething);
首先,您将不会得到一个
NPE
,而是一个NoTouchElementException
。第二,你可能会确定;但是其他人可能会出现,并且没有意识到它不会抛出异常
对于沙箱项目-是的,你不会在意,可以忽略警告;对于生产代码,我不会禁用它(即使可以)
最后一点是,如果您非常确定,为什么不抛出一个异常呢
orElseThrow(IAmSureThisWillNotHappenException::new)
您可以毫无问题地流式处理空列表,但是如果您尝试获取空列表上的第一个元素,您将得到一个NoTouchElementException Stream API意识到这一点,因此它们为您提供了多种处理方法: 选项1:
orElse
如果未找到第一个元素,则可以返回“默认”值
String firstString = myList.stream().findFirst().orElse("Ups!");
firstString = myList.stream().findFirst().orElseGet(mySupplier);
firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);
选项2:orElseGet
如果找不到第一个元素,您可以使用供应商
返回字符串
String firstString = myList.stream().findFirst().orElse("Ups!");
firstString = myList.stream().findFirst().orElseGet(mySupplier);
firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);
选项3:或lsetrow
如果未找到第一个元素,则可以引发异常
String firstString = myList.stream().findFirst().orElse("Ups!");
firstString = myList.stream().findFirst().orElseGet(mySupplier);
firstString = myList.stream().findFirst().orElseThrow(WhatTerribleFailException::new);
如果您知道您的
可选
从不为空,您可以使用@SuppressWarnings
注释,如下所示:
@SuppressWarnings("ConstantConditions") String foo = Optional.of("bar").get();
有时可选。get
将引发一个空点异常
,例如:
Optional<String> it = Optional.empty();
String foo = it.get();
// ^--- throws NullPointerException when this method is invoked
Optional it=Optional.empty();
字符串foo=it.get();
//^---调用此方法时引发NullPointerException
因此使用此表达式时,Intellij将报告警告检查
如果要禁用所有合同检验,可以执行以下操作:设置->检验->取消选中恒定条件和例外选项->不要忘记单击底部的应用按钮保存设置
如果您不想禁用除可选之外的所有合同检查。get()
警告您可以执行以下操作:设置->检查->选中了恒定条件和异常选项->在右下方有一个要配置的框架可选。get()
warnings->别忘了单击底部的应用按钮保存设置
您应该使用
findFirst()
返回的可选的,而不是试图获取它的值(如果它确实存在)
该方法接收一个仅当可选
包含非空值时才会使用的值
问题是我们Java开发人员已经习惯了命令式范例。。。特别是,我们习惯于获取一个对象并推它,即推到一个方法:
String myString = "hello"; // getting an object here
System.out.println(myString); // pushing the object to System.out here
// (via the println method)
使用Stream.findFirst()
返回的可选,您执行的操作与上面相同:
String myString = myList.stream()
.findFirst()
.get(); // getting a string here
System.out.println(myString); // pushing the string here
另一方面,功能范式(包括可选)通常以另一种方式工作:
myList.stream()
.findFirst()
.ifPresent(myString -> System.out.println(myString));
在这里,您不会获取字符串,然后将其推送到某个方法。相反,您为Optional
的ifPresent
操作提供一个参数,并让Optional
的实现将值推送到您的参数。换句话说,您可以通过ifPresent
的参数拉取可选
所包装的值<代码>如果存在
则仅当值存在时才会使用此使用者
参数
这种拉模式在函数式编程中非常常见,一旦您习惯了它,它将非常有用。它只需要我们开发人员以不同的方式开始思考(和编程)。我认为有一个选项可以禁用IntelliJ所做的某些检查。尝试在设置中查找它您可以在空列表中创建一个流,没有问题,但是如果您尝试在空列表中获取1s元素,您将获得一个NoTouchElementException?我知道有可能禁用警告,但是如果禁用,则即使我需要该通知,它也不会再通知我。使用myList.get(0)
…但我不想打印它,我只是用字符串编写,因为它很简单,我想要的东西很清楚,但例如,如果我想将结果传递给一个方法,我不能这样做,所以我必须使用带有警告的get。@Sunflame您可以将结果传递给ifPresent
中的一个方法<代码>.ifPresent(结果->剂量测定(结果))
@Sunflame单子的概念,它是可选的,