简体   繁体   English

在 Java 8 流的 filter() 和 map() 中使用相同的变量

[英]Use same variable in filter() and map() of a Java 8 stream

To improve performance I want to use the same variable in both filter() and map() of a Java 8 stream.为了提高性能,我想在 Java 8 流的filter()map()中使用相同的变量。 Example-例子-

                list.stream()
                .filter(var -> getAnotherObject(var).isPresent())
                .map(var -> getAnotherObject(var).get())
                .collect(Collectors.toList())

The called method getAnotherObject() looks like-被调用的方法getAnotherObject()看起来像-

private Optional<String> getAnotherObject(String var)

In the above scenario I have to call the method getAnotherObject() twice.在上面的场景中,我必须两次调用getAnotherObject()方法。
If I go with a regular for loop then I have to call the method getAnotherObject() only once.如果我使用常规的for 循环,那么我只需要调用getAnotherObject()方法一次。

List<String> resultList = new ArrayList<>();
        for(String var : list) {
            Optional<String> optionalAnotherObject = getAnotherObject(var);
            if(optionalAnotherObject.isPresent()) {
                String anotherObject = optionalAnotherObject.get();
                resultList.add(anotherObject)
            }
        }

Even with stream I can put all my code in map() -即使使用流,我也可以将所有代码放入map() -

list.stream()
                .map(var -> {
                    Optional<String> anotherObjectOptional = getAnotherObject(var);
                    if(anotherObjectOptional.isPresent()) {
                        return anotherObjectOptional.get();
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

But I believe there must be an elegant way using filter() .但我相信一定有一种优雅的方式使用filter()

You can create a stream like this您可以创建这样的流

list.stream()
        .map(YourClass::getAnotherObject)
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());

YourClass refer to the name of the class where getAnotherObject method is defined YourClass 是指定义getAnotherObject方法的类的名称

You can use flatMap .您可以使用flatMap Usually this is used to flatten stuff, but here you can通常这用于展平东西,但在这里你可以

  1. map the element to that element if the optional has a value如果可选项有值,则将元素映射到该元素
  2. map the element to an empty stream if the optional has no value如果可选项没有值,则将元素映射到空流

Like this:像这样:

stream
    .map(x -> getAnotherObject(x))
    .flatMap(x -> x.map(Stream::of).orElse(Stream.of())))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM