未经检查的调用 ifPresent 检查,为啥? [复制]
Posted
技术标签:
【中文标题】未经检查的调用 ifPresent 检查,为啥? [复制]【英文标题】:Unchecked call to ifPresent inspection, why? [duplicate]未经检查的调用 ifPresent 检查,为什么? [复制] 【发布时间】:2019-12-25 13:35:24 【问题描述】:我的代码:
public static boolean searchLineOnLogFile(String...keywords)
Collection select = null;
try (final Stream<String> lines = Files.lines(get(getServerLog().toString())))
select = CollectionUtils.select(lines.collect(Collectors.toCollection(LinkedList::new)),
new Predicate()
public boolean evaluate(Object object)
String line = (String) object;
return Arrays.stream(keywords).allMatch(line::contains);
);
catch (IOException e)
e.printStackTrace();
Assert.fail(e.getMessage());
select.stream().findFirst().ifPresent(firstLine -> LogAutomation.info((String)firstLine));
return select.size() > 0;
select.stream().findFirst().ifPresent(firstLine -> log.info((String)firstLine));
为什么我会收到“取消选中 isPresent 调用”检查?如何改进我的代码?
full inspection message
从我读到的所有想法都是避免空检查:
“所以不要写这样的东西:
if(optional.isPresent)
doSomething(optional.get);
你可以写:
optional.ifPresent(val->doSomething(val));
或者如果您愿意:
optional.ifPresent(this::doSomething);
【问题讨论】:
您能分享一下您收到的确切警告吗?我猜问题出在(String)firstLine
并且警告与可选方法无关
向我们展示select
的声明。
可能是因为您的select
变量已使用raw type 声明。
正如我所怀疑的,select
有一个 原始类型。将声明更改为Collection<String> select
。其他人指出的仍然是正确的,您的异常处理......需要改进,因为在捕获异常后,您将继续使用select
成为null
。但这不是编译器警告的原因。
除了使用raw type引起的编译器警告外,很扭曲,收集一个流到一个集合,无缘无故坚持LinkedList
,然后使用第 3 方库方法CollectionUtils.select
,终于再次获取流。您可以直接过滤原始流:Optional<String> o = lines.filter(line -> Arrays.stream(keywords) .allMatch(line::contains)) .findFirst(); o.ifPresent(firstLine -> LogAutomation.info((String)firstLine)); return o.isPresent();
。无需收藏到LinkedList
,无需第三方图书馆。
【参考方案1】:
您可以使用 Optional.ofNullable,正如 Butiri 所回答的那样。 您也可以使用 Objects.requireNonNullElse。
在第二种情况下,如果为空,您可以定义默认值。 示例:
public class Main
public static void main(String[] args)
Collection<Integer> select = null;
if (Math.random() > 0.5)
select = Arrays.asList(1, 2, 3);
Objects.requireNonNullElse(select, Collections.singletonList(99)).stream().
findFirst().
ifPresent(e -> System.out.println("found: " + e));
【讨论】:
【参考方案2】:警告是因为select
可以为空。可以通过Optional.ofNullable修复
Optional.ofNullable(select).stream().findFirst().ifPresent(firstLine -> LogAutomation.info((String) firstLine));
【讨论】:
你是对的,select
可以是null
,这可能会导致问题。但这不是 unchecked 警告的原因。除此之外,在可选项上调用 .stream()
需要 Java 9,并且与在包含的集合上调用 stream()
不同。以上是关于未经检查的调用 ifPresent 检查,为啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
用 Optional#ifPresent 替换空检查的好处 [重复]
Linux Kernel 4.2.x:为啥检查时预期的系统调用地址与实际地址不匹配?