简体   繁体   中英

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. Example-

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

The called method getAnotherObject() looks like-

private Optional<String> getAnotherObject(String var)

In the above scenario I have to call the method getAnotherObject() twice.
If I go with a regular for loop then I have to call the method getAnotherObject() only once.

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() -

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() .

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

You can use 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())))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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