Java 如果不存在,如何在可选设备上执行逻辑?

Java 如果不存在,如何在可选设备上执行逻辑?,java,java-8,optional,Java,Java 8,Optional,我想使用java8Optional替换以下代码: public Obj getObjectFromDB() { Obj obj = dao.find(); if (obj != null) { obj.setAvailable(true); } else { logger.fatal("Object not available"); } return obj; } 以下伪代码不起作用,因为没有orElseRun方法,但无

我想使用java8
Optional
替换以下代码:

public Obj getObjectFromDB() {
    Obj obj = dao.find();
    if (obj != null) {
        obj.setAvailable(true);
    } else {
        logger.fatal("Object not available");
    }

    return obj;
}
以下伪代码不起作用,因为没有
orElseRun
方法,但无论如何它说明了我的目的:

public Optional<Obj> getObjectFromDB() {
    Optional<Obj> obj = dao.find();
    return obj.ifPresent(obj.setAvailable(true)).orElseRun(logger.fatal("Object not available"));
}
public可选getObjectFromDB(){
可选obj=dao.find();
返回obj.ifPresent(obj.setAvailable(true)).orElseRun(logger.fatal(“对象不可用”));
}

我认为你不可能一句话就能做到。最好是:

if (!obj.isPresent()) {
    logger.fatal(...);   
} else {
    obj.get().setAvailable(true);
}
return obj;
你需要和。你的片段赢了;不工作,因为如果不存在,它不会返回任何内容


可选的一点是从方法返回它。

您必须将其拆分为多个语句。有一种方法可以做到这一点:

if (!obj.isPresent()) {
  logger.fatal("Object not available");
}

obj.ifPresent(o -> o.setAvailable(true));
return obj;
另一种方法(可能过度设计)是使用
map

if (!obj.isPresent()) {
  logger.fatal("Object not available");
}

return obj.map(o -> {o.setAvailable(true); return o;});
如果
obj.setAvailable
方便地返回
obj
,则您可以简单地将第二个示例用于:

if (!obj.isPresent()) {
  logger.fatal("Object not available");
}

return obj.map(o -> o.setAvailable(true));

我想您无法更改
dao.find()
方法来返回
Optional
的实例,因此您必须自己创建相应的实例

下面的代码应该可以帮助您。我已经创建了类
OptionalAction
, 它为您提供了if-else机制

public class OptionalTest
{
  public static Optional<DbObject> getObjectFromDb()
  {
    // doa.find()
    DbObject v = find();

    // create appropriate Optional
    Optional<DbObject> object = Optional.ofNullable(v);

    // @formatter:off
    OptionalAction.
    ifPresent(object)
    .then(o -> o.setAvailable(true))
    .elseDo(o -> System.out.println("Fatal! Object not available!"));
    // @formatter:on
    return object;
  }

  public static void main(String[] args)
  {
    Optional<DbObject> object = getObjectFromDb();
    if (object.isPresent())
      System.out.println(object.get());
    else
      System.out.println("There is no object!");
  }

  // find may return null
  public static DbObject find()
  {
    return (Math.random() > 0.5) ? null : new DbObject();
  }

  static class DbObject
  {
    private boolean available = false;

    public boolean isAvailable()
    {
      return available;
    }

    public void setAvailable(boolean available)
    {
      this.available = available;
    }

    @Override
    public String toString()
    {
      return "DbObject [available=" + available + "]";
    }
  }

  static class OptionalAction
  {
    public static <T> IfAction<T> ifPresent(Optional<T> optional)
    {
      return new IfAction<>(optional);
    }

    private static class IfAction<T>
    {
      private final Optional<T> optional;

      public IfAction(Optional<T> optional)
      {
        this.optional = optional;
      }

      public ElseAction<T> then(Consumer<? super T> consumer)
      {
        if (optional.isPresent())
          consumer.accept(optional.get());
        return new ElseAction<>(optional);
      }
    }

    private static class ElseAction<T>
    {
      private final Optional<T> optional;

      public ElseAction(Optional<T> optional)
      {
        this.optional = optional;
      }

      public void elseDo(Consumer<? super T> consumer)
      {
        if (!optional.isPresent())
          consumer.accept(null);
      }
    }
  }
}
公共类选项测试
{
公共静态可选getObjectFromDb()
{
//doa.find()
DbObject v=find();
//创建适当的可选文件
可选对象=可选的可用对象(v);
//@formatter:off
选择性作用。
如果存在(对象)
。然后(o->o.setAvailable(true))
.elseDo(o->System.out.println(“致命!对象不可用!”);
//@formatter:on
返回对象;
}
公共静态void main(字符串[]args)
{
可选对象=getObjectFromDb();
if(object.isPresent())
System.out.println(object.get());
其他的
System.out.println(“没有对象!”);
}
//find可能返回null
公共静态DbObject find()
{
返回值(Math.random()>0.5)?null:newdbobject();
}
静态类DbObject
{
private boolean available=false;
公共布尔值isAvailable()
{
返回可用;
}
public void setAvailable(布尔值可用)
{
this.available=可用;
}
@凌驾
公共字符串toString()
{
返回“DbObject[available=“+available+”]”;
}
}
静态类选择作用
{
公共静态iAction ifPresent(可选)
{
返回新的iAction(可选);
}
私有静态类iAction
{
私人最终选择;
公共iAction(可选)
{
this.optional=可选;
}

公众反应(消费者我想出了两个“一线”解决方案,例如:

    obj.map(o -> (Runnable) () -> o.setAvailable(true))
       .orElse(() -> logger.fatal("Object not available"))
       .run();

obj.map(o->(消费者)c->o.setAvailable(true))
.orElse(o->logger.fatal(“对象不可用”))
.接受(空);

obj.map(o->(供应商)(->{
o、 setAvailable(true);
返回null;
}).orElse(()->{
logger.fatal(“对象不可用”)
返回null;
}).get();

它看起来不太好,像
orElseRun
这样的方法会更好,但是我认为如果您真的想要一行解决方案,那么带有Runnable的选项是可以接受的。

那里有一个
.orElseRun
方法,但它被称为
.orElseGet

伪代码的主要问题是,
.isPresent
不返回
可选的
。但是
.map
返回一个
可选的
,该方法具有
或elserun
方法

如果您真的想在一个语句中实现这一点,则可以:

public Optional<Obj> getObjectFromDB() {
    return dao.find()
        .map( obj -> { 
            obj.setAvailable(true);
            return Optional.of(obj); 
         })
        .orElseGet( () -> {
            logger.fatal("Object not available"); 
            return Optional.empty();
    });
}
public可选getObjectFromDB(){
return dao.find()
.map(obj->{
对象设置可用(真);
返回可选。of(obj);
})
.orElseGet(()->{
记录器。致命(“对象不可用”);
返回可选的.empty();
});
}

但是这比以前的更为笨拙。

首先,您的
dao.find()
应该返回一个
可选的
,或者您必须创建一个

e、 g

这是您正在寻找的一行代码:)

使用Java 9或更高版本,很可能就是您想要的:

可选opt=dao.find();
选择IfPresentOverlese(对象->对象设置可用(真),
()->logger.error(“…”);
使用或类似的方法可能会得到更整洁的代码,但我还没有尝试过。

对于Java 8,Spring提供了“使用可选项的实用方法”来实现您想要的。 例如:

import static org.springframework.data.util.Optionals.ifPresentOrElse;    

ifPresentOrElse(dao.find(), obj -> obj.setAvailable(true), () -> logger.fatal("Object not available"));

使用Java 8
可选
可以通过以下方式完成:

    Optional<Obj> obj = dao.find();

    obj.map(obj.setAvailable(true)).orElseGet(() -> {
        logger.fatal("Object not available");
        return null;
    });
可选obj=dao.find();
obj.map(obj.setAvailable(true)).orElseGet(()->{
记录器。致命(“对象不可用”);
返回null;
});

适用于那些只想在没有可选选项的情况下执行副作用的人

i、 e.相当于
ifAbsent()
ifNotPresent()
这里是对已经提供的伟大答案的轻微修改

myOptional.ifPresentOrElse(x -> {}, () -> {
  // logic goes here
})

ifpresentorese也可以处理空指针的情况。方法简单

   Optional.ofNullable(null)
            .ifPresentOrElse(name -> System.out.println("my name is "+ name),
                    ()->System.out.println("no name or was a null pointer"));

如果没有对象存在,您希望从方法返回什么?我希望始终按照方法返回参数返回
可选
。如果您投反对票,请留下评论。这有助于我改进答案。我同意downvoter应该在此处进行评论。我假设这是因为我希望将java7重构为java8代码,而旧代码由8行组成。如果我用你的建议替换它,那对任何人都没有帮助,只会让事情变得更糟。我不明白你的意思。我确实将java 7重构为8,不是吗?在多大程度上会让事情变得更糟?我看不出这个解决方案有任何缺陷。一位同事
public Obj getObjectFromDB() {
   return Optional.ofNullable(dao.find()).flatMap(ob -> {
            ob.setAvailable(true);
            return Optional.of(ob);    
        }).orElseGet(() -> {
            logger.fatal("Object not available");
            return null;
        });
    }
import static org.springframework.data.util.Optionals.ifPresentOrElse;    

ifPresentOrElse(dao.find(), obj -> obj.setAvailable(true), () -> logger.fatal("Object not available"));
    Optional<Obj> obj = dao.find();

    obj.map(obj.setAvailable(true)).orElseGet(() -> {
        logger.fatal("Object not available");
        return null;
    });
myOptional.ifPresentOrElse(x -> {}, () -> {
  // logic goes here
})
   Optional.ofNullable(null)
            .ifPresentOrElse(name -> System.out.println("my name is "+ name),
                    ()->System.out.println("no name or was a null pointer"));