Java8可选资产()

Java8可选资产(),java,guava,java-8,optional,Java,Guava,Java 8,Optional,因此,我已经使用了Guava的Optional一段时间了,现在我要转到Java 8,所以我想使用它的Optional类,但它没有我最喜欢的Guava方法:asSet()。有没有一种方法可以用Java 8可选的来实现这一点,我还没有看到。我喜欢将可选视为一个集合,这样我就可以做到: for (final User u : getUserOptional().asSet()) { return u.isPermitted(getPermissionRequired()); } 在某些情况下,

因此,我已经使用了Guava的
Optional
一段时间了,现在我要转到Java 8,所以我想使用它的
Optional
类,但它没有我最喜欢的Guava方法:
asSet()
。有没有一种方法可以用Java 8
可选的
来实现这一点,我还没有看到。我喜欢将
可选
视为一个集合,这样我就可以做到:

for (final User u : getUserOptional().asSet()) {
   return u.isPermitted(getPermissionRequired());
}
在某些情况下,可以避免使用附加变量

例如:

 Optional<User> optUser = getUserOptional();
 if (optUser.isPresent()) {
     return optUser.get().isPermitted(getPermissionRequired());
 }
Optional optUser=getUserOptional();
if(optUser.isPresent()){
返回optUser.get().isPermitted(getPermissionRequired());
}
有没有一种简单的方法可以在Java8的
可选
中复制番石榴风格


谢谢

您可以修改getUserOptional,使其返回一个集合或实现您自己的资产方法:

public Set<User> getUserOptional() {
     Optional<User> optUser;
     //your code
     Set<User> result = new HashSet<>();
     if (optUser.isPresent())
         result.add(optUser.get());
     return result;
}
public Set getUserOptional(){
可选的optUser;
//你的代码
Set result=new HashSet();
if(optUser.isPresent())
add(optUser.get());
返回结果;
}

公共静态集合资产(可选选项){
Set result=new HashSet();
if(opt.isPresent())
result.add(opt.get());
返回结果;
}

但是,我不知道是否有一种内置的方法。您可以使用
map

return optUser.map(u -> u.isPermitted(getPermissionRequired()));
但它将返回一个
可选的

公共可选映射(函数映射器)

如果存在值,则将提供的映射函数应用于该值,然后 如果结果非空,则返回一个描述结果的可选值。 否则,返回一个空的可选值


我也不认为有一种真正优雅的内置方法可以做到这一点,但我想提出一种类似于Dici的解决方案:

public static <T> Set<T> asSet(Optional<T> opt) {
    return opt.isPresent() ?
        Collections.singletonSet(opt.get()) :
        Collections.emptySet();
}

有一种简单的方法可以将
可选
转换为
集合
。它的工作原理与
可选的任何其他转换一样:

给定一个
可选的o
,您可以调用

o.map(Collections::singleton).orElse(Collections.emptySet())
要获取
。如果您不喜欢在任何情况下都调用
Collections.emptySet()
,您可以将其转换为惰性计算:

o.map(Collections::singleton).orElseGet(Collections::emptySet)
但是,该方法过于简单,无法改变性能。所以这只是编码风格的问题

您还可以使用它进行类似预期的迭代:

for(T t: o.map(Collections::singleton).orElse(Collections.emptySet()))
    // do something with t, may include a return statement

您似乎只使用了
asSet
,因此可以编写for循环,但在Java8中这是不必要的。而不是你的代码

Optional<User> optUser = getUserOptional();
if ( optUser.isPresent() ) {
    return optUser.get().isPermitted(getPermissionRequired());
}

…或者,在许多情况下,您可以使用
可选。如果存在(消费者)

另一种选择是:

getUserOptional().stream().collect(Collectors.toSet())

我不认为这样更好,但我只是想把它添加到这里以获得完整性。

这正是我所担心的,只是在我看来它没有那么优雅。对我来说,将Optionals看作是一个由零个或一个项目组成的集合,然后对其进行处理是有意义的。因此,在本例中,我想我可以这样做:返回optUser.map(u->u.isPermitted(getPermissionRequired()).get();它会产生效果。@csyperski get()在可选项没有值时抛出一个异常,因此我认为这不是您想要的。@csyperski如果在没有值的情况下需要null,请使用
.orElse(null)
。但是如果这种情况下它会返回一个布尔值,那么调用get可以安全地打开布尔值,对吗?@csyperski我认为如果
isPermitted
返回布尔值,映射操作将返回可选值,因此在其上调用get将在其为空时抛出异常(即,如果原始可选值为空)。这就是为什么您应该使用.orElse,并提供一个默认值(例如:
.orElse(Boolean.FALSE)
)。另请看,这是我一直在寻找的@csyperski我不明白你为什么要坚持你在Guava中使用的这个空集合+for循环技巧,当你可以简单地对可选项执行所需的操作(当前在循环中的操作),如果可选项为空,就有一个默认值-
return optUser.map(u->u.isPermitted(getPermissionRequired()).orElse(Boolean.FALSE)
。因为在这种情况下它可以工作,但并不总是如此。假设我们有以下选项:公共可选的attemptLogin(字符串电子邮件…){//首先让我们看看用户是否被禁止(最终失败登录失败登录:getFailedLogin(电子邮件,ipAddress).map(Collections::singleton).orElGet(Collections::emptySet)){logger.warn(“帐户当前被禁止{}”,failedLogin);返回可选的.empty();}//执行其他登录验证}。这可能不是最好的例子,但这是我在一些遗留代码中看到的。@Eran:如果返回某个固定值是一种替代方案,则解决方案有效。但是,如果不返回,但继续执行下一个语句,则不会。不过,建议考虑重新设计,但不满足此要求。
Optional<User> optUser = getUserOptional();
if ( optUser.isPresent() ) {
    return optUser.get().isPermitted(getPermissionRequired());
}
getUserPresent().map(optUser -> optUser.isPermitted(getPermissionRequired()))
   .orElse(false);
getUserOptional().stream().collect(Collectors.toSet())