小编Dar*_*iva的帖子

过滤器上的流图

当您拥有对象流时,您可以非常优雅地过滤它们。

\n
swimmingAnimalStream = animalStream\n    .filter(Animal::canSwim);\n
Run Code Online (Sandbox Code Playgroud)\n

当您有稍微复杂的过滤器而不是使用方法引用时,您必须使用 Lambda。

\n
greenAnimals = animalStream\n    .filter(animal -> animal.getColor().equals(Colors.GREEN));\n
Run Code Online (Sandbox Code Playgroud)\n

有没有办法在过滤之前映射值,但在过滤之后仍然拥有完整的对象?\n所以下面的不是我想要的:

\n
animalStream\n    .map(Animal::getColor)\n    .filter(Colors.GREEN::equals)\n
Run Code Online (Sandbox Code Playgroud)\n

这样我就只剩下颜色信息了。\n我还想避免的是提取方法。我正在寻找一种更简化的方法来做到这一点。例如这样的事情:

\n
animalStream\n    .filter(Colors.GREEN::equals, Animal::getColor);\n
Run Code Online (Sandbox Code Playgroud)\n

该过滤器方法的方法签名如下所示。

\n
<MAPPED> Stream<T> filter(Predicate<MAPPED> filter, Function<? super T, MAPPED> mappingFunction);\n
Run Code Online (Sandbox Code Playgroud)\n

更好的是您可以加入多个映射功能的版本。在运行过程中,人们可以使用可变参数来表示映射函数。但老实说,我不知道\xe2\x80\x99 不知道泛型如何实现这一点。但\xe2\x80\x99 是一个不同的故事。

\n

该解决方案还应该能够使用人们可以想象的任何谓词。等于只是一个例子。另一个示例是检查对象中的字段是否存在。

\n
animalWithMotherStream = animalStream\n    .filter(Optional::isPresent, Animal::getMother);\n
Run Code Online (Sandbox Code Playgroud)\n

现在有人有更干净的解决方案,或者已经有这样做的库吗?

\n

java java-stream

5
推荐指数
1
解决办法
318
查看次数

对流中的 Instanceof 应用模式匹配

假设我们有一个动物流。

我们有不同的动物子类,并且我们希望在流上应用过滤器以仅包含流中的斑马。我们现在仍然有动物流,但只包含斑马。为了获得斑马流,我们仍然需要进行投射。

Stream<Zebra> zebraStream = animalStream
    .filter(Zebra.class::isInstance)
    .map(Zebra.class::cast);
Run Code Online (Sandbox Code Playgroud)

Java 14 引入了instanceof 的模式匹配,所以我们现在可以使用:

if (animal instanceof Zebra zebra) {
    System.out.println(zebra.countStripes());
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在流管道中使用模式匹配?当然你可以这样做:

Stream<Zebra> zebraStream = animalStream.map(animal -> {
        if (animal instanceof Zebra zebra) {
            return zebra;
        }
        return null;
    })
    .filter(Objects::nonNull);
Run Code Online (Sandbox Code Playgroud)

但恕我直言,这真的很难看。

java instanceof java-stream

3
推荐指数
1
解决办法
598
查看次数

从可选&lt;Stream&gt;中提取流

假设我有一个Optional包含Stream

Optional<Stream<Integer>> optionalStream = Optional.of(Stream.of(1, 2, 3));
Run Code Online (Sandbox Code Playgroud)

现在我需要提取它Stream本身。如果Optional为空,您想要获得一个空的 Stream。

我正在寻找类似的东西,flatStream()可以一步执行转换。我怎样才能做到这一点?

我目前的尝试:

Stream<Integer> stream = optionalStream.stream().flatMap(Function.identity());
Run Code Online (Sandbox Code Playgroud)

问题的背景

在我的真实场景中,我有这样的东西,它给了我一个Stream<Optional<Foo>>

stream.findFirst().map(e -> e.getChildren())
Run Code Online (Sandbox Code Playgroud)

java java-stream option-type

2
推荐指数
1
解决办法
139
查看次数

如何链接可选的 ifPresent 调用?

假设您有一个Optional,并且您想要多次使用该Optional。\n您现在可以将该Optional保存到一个变量中;然后使用ifPresent两次:

\n
Optional<Animal> optionalAnimal = animalService.getAllAnimals().findFirst();\noptionalAnimal.ifPresent(Animal::eat);\noptionalAnimal.ifPresent(Animal::drink);\n
Run Code Online (Sandbox Code Playgroud)\n

另一种解决方案是放弃方法引用并使用同时执行这两项操作的 lambda:

\n
animalService.getAllAnimals().findFirst()\n    .ifPresent(animal -> {\n        animal.drink();\n        animal.eat();\n    });\n
Run Code Online (Sandbox Code Playgroud)\n

如果我可以控制可选中使用的类,我可以简单地更改方法以使用类似工厂的模式。这样它animal.drink()就会自行返回。\n然后我可以写:

\n
animalService.getAllAnimals().findFirst()\n    .map(Animal::drink)\n    .ifPresent(Animal::eat);\n
Run Code Online (Sandbox Code Playgroud)\n

但这在语义上会很奇怪。而且我不\xe2\x80\x99t 总是可以控制我在可选中使用的每个类。有些类是最终的,所以我什至无法将它们扩展为具有工厂样式的方法。

\n

此外,Optional 类也是final 类,因此扩展Optional 本身也不是选择。\n所有这些对我来说毫无意义。ifPresent()返回无效。如果ifPresent()返回可选本身(类似于peek()流),它将更接近我的目标。

\n

还有其他我没有想到的解决方案吗?

\n
\n

我想要的是这样的:

\n
animalService.getAllAnimals().findFirst()\n    .ifPresent(Animal::drink)\n    .ifPresent(Animal::eat);\n
Run Code Online (Sandbox Code Playgroud)\n

java option-type

1
推荐指数
1
解决办法
592
查看次数

标签 统计

java ×4

java-stream ×3

option-type ×2

instanceof ×1