相关疑难解决方法(0)

Java 8的Optional.ifPresent和if-not-Present的功能风格?

在Java 8中,我想对一个Optional对象做一些事情,如果它存在,并做另一件事,如果它不存在.

if (opt.isPresent()) {
  System.out.println("found");
} else {
  System.out.println("Not found");
}
Run Code Online (Sandbox Code Playgroud)

但这不是一种"功能风格".

Optional有一个ifPresent()方法,但我无法链接一个orElse()方法.

因此,我不能写:

opt.ifPresent( x -> System.out.println("found " + x))
   .orElse( System.out.println("NOT FOUND"));
Run Code Online (Sandbox Code Playgroud)

在回复@assylias时,我认为不适Optional.map()用于以下情况:

opt.map( o -> {
  System.out.println("while opt is present...");
  o.setProperty(xxx);
  dao.update(o);
  return null;
}).orElseGet( () -> {
  System.out.println("create new obj");
  dao.save(new obj);
  return null;
});
Run Code Online (Sandbox Code Playgroud)

在这种情况下,当opt存在时,我更新其属性并保存到数据库.当它不可用时,我创建一个新的obj并保存到数据库.

请注意我必须返回的两个lambda null.

但是当opt存在时,两个lambdas都将被执行.obj将更新,并将新对象保存到数据库.这是因为return null在第一个lambda中.并且orElseGet()将继续执行.

java functional-programming optional java-8

239
推荐指数
7
解决办法
28万
查看次数

Java 8中的链接选项

寻找一种链接选项的方法,以便返回第一个存在的选项.如果没有,Optional.empty()则应退回.

假设我有几个像这样的方法:

Optional<String> find1()
Run Code Online (Sandbox Code Playgroud)

我想把它们链起来:

Optional<String> result = find1().orElse( this::find2 ).orElse( this::find3 );
Run Code Online (Sandbox Code Playgroud)

但当然这不起作用,因为orElse期望一个值,并orElseGet期望一个Supplier.

java lambda optional java-8

59
推荐指数
4
解决办法
3万
查看次数

从一个可选或另一个获得价值

我有两个java.util.Optional实例,我想得到一个Optional:

  • 如果它有值,则具有第一个Optional的值.
  • 如果它有值,则具有第二个Optional的值.
  • 是空的既不是Optional也有值.

是否有直接的方法来做到这一点,即是否已经有一些API来做到这一点?

以下表达式会这样做,但我必须提到第一个可选的两次:

firstOptional.isPresent() ? firstOptional : secondOptional
Run Code Online (Sandbox Code Playgroud)

这正是com.google.common.base.Optional.or()如此,但Java 8的API中不存在该方法.


aioobe接受的答案列出了一些替代方法来克服这种遗漏OptionalAPI的权利,在这种情况下必须计算这样的值(这回答了我的问题).我现在选择在我的代码库中添加一个实用程序函数:

public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
    if (a.isPresent())
        return a;
    else
        return b;
}
Run Code Online (Sandbox Code Playgroud)

java optional java-8

48
推荐指数
3
解决办法
2万
查看次数

如何从Optional <T>列表中获取第一个非空Optional <T>

我正在将一些代码移动到java8,尝试(有时强迫自己)使用stream和lambdas,我对它们感到不舒服.

我在类中有一些验证业务对象的方法.每个方法看起来都像

Optional<Fail> validate1(BusinessObject bo)
Run Code Online (Sandbox Code Playgroud)

其中Fail是以某种方式描述错误的枚举,如果没有错误,则该方法返回Optional.empty().我不需要收集所有错误,但返回第一个错误,而不执行以下验证.

我正在做的是

//first convert methods to suppliers
Supplier<Optional<Fail>> validate1= () -> validate1(bo);
Supplier<Optional<Fail>> validate2= () -> validate2(bo);
Supplier<Optional<Fail>> validate3= () -> validate3(bo);
//then some stream magic
return Stream.of(validate1, validate2, validate3)
    .map(Supplier::get)
    .filter(f -> f.isPresent())
    .findFirst()
    .orElse(Optional.empty()); //without the orElse, no error would return
                                         // Optional(Optional.empty()) 
                                         // instead of Optional.empty()
Run Code Online (Sandbox Code Playgroud)

它工作,它完成工作,它不执行不必要的方法,它是清晰的(如果Optional.orElse被命名为getOrElse,它会更清晰,但这是我无法实现的).我想要找出的是,如果这是一个合理的方式来做我想要的,如果这个代码被认为是'好风格'或'惯用java8',或者我误用Stream或Optional,或者遗漏了一些明显的东西.

如果它们都是空的,那么返回第一个非空的Optional或者一个空的Optional的想法看起来很普遍,以为有一个正式的方法可以做到这一点,在我脑后的东西是大喊"Monads!",但我的无知Haskell几乎是完美的,所以我不知道.

lambda functional-programming java-8

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

级联方法,每个方法都返回一个Java8 Optional <>

我有几个方法,每个方法返回一个可选的字符串.我如何组合,以便java调用每个方法,直到找到结果?

我想最终得到这样的东西,但没有orElseFlatMap()方法:

import java.util.Optional;

public class OptionalCascade {

    public static void main(String[] args) {
        Optional<String> result = 

                // try to get a result with method A
                methodA()

                // if method A did not return anything, then try method B
                .orElseFlatMap(methodB());
    }


    static Optional<String> methodA() {
        return Optional.empty();
    }

    static Optional<String> methodB() {
        return Optional.empty();
    }
}
Run Code Online (Sandbox Code Playgroud)

java optional java-8

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

在Java 8中懒惰地返回第一个非空列表

我有N个列表从存储库返回数据.我想返回这三个列表中的第一个非空(每个列表执行不同的SQL来获取数据).

问题是我想懒得这样做,所以如果我已经找到了可接受的结果,我就不需要在数据库上执行SQL.我的代码是(修改过的)

@Override
public List<Something> dataService(Data data) {

return firstNonEmptyList(repository.getDataWayOne(data.getParameter()), 
                         repository.getDataWayTwo(data.getParameter()),
                         repository.getDataWayThree(data.getParameter().getAcessoryParameter())
                         Collections.singletonList(repository.getDefaultData(data.getParameter()));

}

@SafeVarargs
private final List<Something> firstNonEmptyList(List<Something>... lists) {
for (List<Something> list : lists) {
  if (!list.isEmpty()) {
    return list;
  }
}

return null;

}
Run Code Online (Sandbox Code Playgroud)

这有效,但它不是懒惰的.有任何想法吗?

java lambda lazy-loading list

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

如何以函数式风格多次编写“如果可选为空,则调用下一个方法返回可选,如果不返回此非空可选”?

假设我有这个方法

public Optional<String> validateAndReturnErrorMessage(SomeEcommerceSale s) {
    Optional<String> errorWithItem = validateItem(s.getItem());
    if (errorWithItem.isPresent()) return errorWithItem;

    Optional<String> errorWithPayment = validatePayment(s.getPayment());
    if (errorWithPayment.isPresent()) return errorWithPayment;
    
    // assume I have several other cases like the 2 above

    return Optional.empty(); // meaning there were no errors
Run Code Online (Sandbox Code Playgroud)

我的问题是,由于OrElse and OrElseGetreturn<T>而不是Optional<T>,是否有一种本地方法可以将其重写为更实用的方式,而无需几个松散耦合的 return 语句?

编辑

我想一一检查验证,因为它们是外部且沉重的。这样,我只会调用必要的

java functional-programming optional java-8

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

如果不存在,我如何将Optional映射到另一个Optional?

我有这个Java 8代码:

public Optional<User> getUser(String id) {
    Optional<User> userFromCache = cache.getUser(id);
    if (userFromCache.isPresent()) {
        return userFromCache;
    }
    return repository.getUser(id);
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我想知道如何将呼叫链接到不使用if.我试过orElseGet但它不允许返回另一个Optional<User>但是User.

我想要这样的东西:

Optional<User> userFromCache = cache.getUser(id)
    .orElseGet(() -> repository.getUser(id));
Run Code Online (Sandbox Code Playgroud)

java optional

4
推荐指数
2
解决办法
398
查看次数

直到找到值 - 可选

我想在找到第一个值时终止流的执行.但是,当我在下面运行代码时,它会显示即使第一个方法存在值,也会调用两个方法.

public static void main(String[] args) {

        Optional<String> s = Stream.of(first(), second())
                .filter(Optional::isPresent)
                .findFirst()
                .flatMap(Function.identity());

        System.out.println(s.get());
    }

    private static Optional<String> first() {
        System.out.println("first");
        return Optional.of("someValue");
    }

    private static Optional<String> second() {
        System.out.println("second");
        return Optional.empty();
    }
Run Code Online (Sandbox Code Playgroud)

我在文档中检查了:

  1. 存在

如果存在值,则返回{@code true},否则返回{@code false}.

  1. 使用FindFirst()

返回描述此流的第一个元素的{@link Optional},如果流为空,则返回空的{@code Optional}.如果流没有遭遇顺序,则可以返回任何元素.

所以它遇到的第一个条件,第二个条件似乎也满足,因为它返回:

first
second
someValue
Run Code Online (Sandbox Code Playgroud)

如果第一个值存在,如何退出执行,而不执行第二个方法?

java optional java-stream

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

Guava是Java 8的可选项,可选择多种选择

这是一个具有多个可能值的Guava可选项.

long numberToUse = Long.parseLong(Optional
            .ofNullable(System.getenv(ENV_VAR))
            .or(Optional.ofNullable(System.getProperty(PROP_VAR)))
            .or("15"));
Run Code Online (Sandbox Code Playgroud)

如何将其转换为干净的Java 8语法?

optional guava java-8

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