21

我是 Java8 的新手。我已经实现了列表和过滤器。我在我的代码中做了一个空检查。对于如何检查同一代码段中的列表是否不为空,我将不胜感激。如果列表不为空,则代码应继续进行断言。

    list.stream().filter(listElement -> listElement != null).
    forEach((listElement) -> Assert.assertEquals(
        ValueType.CANDY,
        listElement.getCandyType()));
4

4 回答 4

31

你在问一个过时的问题。Streams 处理源的所有元素,因此,如果没有元素,则不会执行任何操作。因此,您无需检查列表是否为空。

不过,您可以简化代码:

list.stream().filter(Objects::nonNull)
    .map(listElement -> listElement.getCandyType())
    .forEach(candyType -> Assert.assertEquals(ValueType.CANDY, candyType));

或者

Assert.assertTrue(list.stream().filter(Objects::nonNull)
                      .map(listElement -> listElement.getCandyType())
                      .allMatch(Predicate.isEqual(ValueType.CANDY));

allMatch遵循此检查所需的规则。如果没有元素,则没有矛盾的元素,因此全部 match。请注意,listElement -> listElement.getCandyType()也可以替换为形式的方法引用ClassName::getCandyType;我没有在这里做,因为我不知道正确的类名。

两种变体之间没有性能差异。allMatch遇到第一个不匹配的元素会立即返回,并assertEquals在第一个不匹配的元素上抛出。在第二种情况下,堆栈跟踪不会显示流 API 实现的工件。

当您为生产代码提供检查而不是单元测试并允许关闭这些检查时,第二个是首选,就像 Java 语言assert功能一样,例如

assert list.stream().filter(Objects::nonNull)
           .map(listElement -> listElement.getCandyType())
           .allMatch(Predicate.isEqual(ValueType.CANDY));

因为这种形式保证在关闭断言时不会产生任何开销,而第一个变体具有带有操作的assert语句forEach仍可能导致迭代所有元素并执行管道的中间步骤。

于 2015-12-23T12:45:40.737 回答
25

选择的答案很棒,只是一个小建议来处理新引入的​​ Java8 Optional 类Optional.ofNullable的null 情况:

  Optional.ofNullable(list)
            .orElseGet(Collections::emptyList)
            .stream().filter(Objects::nonNull)
            .map(listElement -> listElement.getCandyType())
            .forEach(candyType -> Assert.assertEquals(ValueType.CANDY, candyType)););
于 2016-08-29T15:02:02.893 回答
8

看看isEmpty方法

if (list.isEmpty()) { ... }

这是文档:https://docs.oracle.com/javase/7/docs/api/java/util/List.html#isEmpty()

于 2015-12-22T23:24:04.607 回答
0

断言列表为空与断言列表的任何特定元素具有某种形式(即getCandyType() == ValueType.CANDY)是不同的。试图将这两个想法联系在一起并不是正确的做事方式。

您需要做的是在 之前或之后添加第二个断言,forEach这确实

assertThat(list.isEmpty(), not(equalTo(Boolean.FALSE)))

...或任何类似的东西。

关于空列表的要点之一是它们可以以与包含元素的列表相同的方式进行处理。这就是存在诸如Optional 类Null 模式之类的东西的原因。因此,如果您真的关心列表是空的,那么您真的应该将其设为一个单独的、不同的断言。

于 2015-12-23T01:32:00.623 回答