Java 8的Optional.ifPresent和if-not-Present的函数风格? [英] Functional style of Java 8's Optional.ifPresent and if-not-Present?

查看:2693
本文介绍了Java 8的Optional.ifPresent和if-not-Present的函数风格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java 8中,如果它存在,我想对可选对象执行一些操作,如果它不存在,请执行另一件事。

  if(opt.isPresent()){
System.out.println(found);
} else {
System.out.println(Not found);
}

虽然这不是'功能风格'。 b
$ b

可选有一个 ifPresent()方法,但我无法链接 orElse()方法。



因此,我不能写:

  opt.ifPresent(x  - > System.out.println(found+ x))
.orElse(System.out.println(NOT FOUND));

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

  opt.map(o  - > {
System.out.println(while opt is present ...);
o.setProperty(xxx);
dao.update(o);
返回null; $ b $ () - > {
System.out.println(create new obj);
dao.save(new obj);
return null;
});

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



注意两个lambda表达式我必须返回 null



但是当 opt 是存在的,两个lambda将被执行。 obj 将被更新,并且一个新的对象将被保存到数据库中。这是因为第一个lambda中的 return null 。并且 orElseGet()将继续执行。 @Dane White的回答是可以的,首先我不喜欢使用Runnable,但是我找不到任何替代品,这里我另一个实现是我更喜欢的

  public class OptionalConsumer< T> {
private可选< T>可选的;

private OptionalConsumer(可选< T>可选){
this.optional =可选;
}

public static< T> OptionalConsumer< T> (可选< T>可选){
return new OptionalConsumer<>(可选);
}

public OptionalConsumer< T> ifPresent(Consumer< T> c){
optional.ifPresent(c);
返回此;
}

public OptionalConsumer< T> ifNotPresent(Runnable r){
if(!optional.isPresent())
r.run();
返回此;


$ / code>

然后:

 可选< Any> o =可选。(...); 
OptionalConsumer.of(o).ifPresent(s - > System.out.println(isPresent+ s))
.ifNotPresent(() - > System.out.println(!存在));

更新1:



以上解决方案适用于传统开发方式,如果您有价值并想要处理它,但如果我想定义功能和执行,那么请检查下面的增强功能;

  public class OptionalConsumer< T>实现Consumer< Optional< T>> {
私人最终消费者< T> C;
private final Runnable r;

public OptionalConsumer(Consumer< T> c,Runnable r){
super();
this.c = c;
this.r = r;
}

public static< T> OptionalConsumer< T> of(Consumer< T> c,Runnable r){
return new OptionalConsumer(c,r);
}

@Override
public void accept(可选< T>){
if(t.isPresent())
c.accept t.get());
else
r.run();


然后可以用作:

 消费者<可选<整数>> c = OptionalConsumer.of(System.out :: println,() - > {System.out.println(Not fit);}); 
IntStream.range(0,100).boxed()。map(i-> Optional.of(i).filter(j-> j%2 == 0))。forEach(c);

在这个新代码中,您有三件事:


  1. 可以在对象容易存在之前定义功能。
  2. 不为每个可选的对象创建对象引用,只有一个可选,您的内存少,GC少。

  3. 它正在实现消费者,以便更好地与其他组件一起使用。

名称更具描述性,它实际上是消费者>


In Java 8, I want to do something to an Optional object if it is present, and do another thing if it is not present.

if (opt.isPresent()) {
  System.out.println("found");
} else {
  System.out.println("Not found");
}

This is not a 'functional style', though.

Optional has an ifPresent() method, but I am unable to chain an orElse() method.

Thus, I cannot write:

opt.ifPresent( x -> System.out.println("found " + x))
   .orElse( System.out.println("NOT FOUND"));

In reply to @assylias, I don't think Optional.map() works for the following case:

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;
});

In this case, when opt is present, I update its property and save to the database. When it is not available, I create a new obj and save to the database.

Note in the two lambdas I have to return null.

But when opt is present, both lambdas will be executed. obj will be updated, and a new object will be saved to the database . This is because of the return null in the first lambda. And orElseGet() will continue to execute.

解决方案

For me the answer of @Dane White is OK, first I did not like using Runnable but I could not find any alternatives, here another implementation I preferred more

public class OptionalConsumer<T> {
    private Optional<T> optional;

    private OptionalConsumer(Optional<T> optional) {
        this.optional = optional;
    }

    public static <T> OptionalConsumer<T> of(Optional<T> optional) {
        return new OptionalConsumer<>(optional);
    }

    public OptionalConsumer<T> ifPresent(Consumer<T> c) {
        optional.ifPresent(c);
        return this;
    }

    public OptionalConsumer<T> ifNotPresent(Runnable r) {
        if (!optional.isPresent())
            r.run();
        return this;
    }
}

Then :

Optional<Any> o = Optional.of(...);
OptionalConsumer.of(o).ifPresent(s ->System.out.println("isPresent "+s))
            .ifNotPresent(() -> System.out.println("! isPresent"));

Update 1:

the above solution for traditional way of development when you have the value and want to process it but what if I want to define the functionality and the execution will be then, check below enhancement;

public class OptionalConsumer<T> implements Consumer<Optional<T>> {
private final Consumer<T> c;
private final Runnable r;

public OptionalConsumer(Consumer<T> c, Runnable r) {
    super();
    this.c = c;
    this.r = r;
}

public static <T> OptionalConsumer<T> of(Consumer<T> c, Runnable r) {
    return new OptionalConsumer(c, r);
}

@Override
public void accept(Optional<T> t) {
    if (t.isPresent())
        c.accept(t.get());
    else
        r.run();
}
}

Then could be used as:

    Consumer<Optional<Integer>> c=OptionalConsumer.of(System.out::println, ()->{System.out.println("Not fit");});
    IntStream.range(0, 100).boxed().map(i->Optional.of(i).filter(j->j%2==0)).forEach(c);

In this new code you have 3 things:

  1. can define functionality before existing of object easy.
  2. not creating object refrence for each Optional, only one,you have so less memory then less GC.
  3. it is implementing consumer for better usage with other components.

by the way now its name is more descriptive it is actually Consumer>

这篇关于Java 8的Optional.ifPresent和if-not-Present的函数风格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆