当前位置: 首页 > 知识库问答 >
问题:

使用Java lambda而不是“if-else”

白智
2023-03-14

对于Java 8,我有以下代码:

if(element.exist()){
    // Do something
}

我想转换成lambda风格,

element.ifExist(el -> {
    // Do something
});

使用像这样的< code>ifExist方法:

public void ifExist(Consumer<Element> consumer) {
    if (exist()) {
        consumer.accept(this);
    }
}

但现在我还有其他案例可以调用:

element.ifExist(el -> {
    // Do something
}).ifNotExist(el -> {
    // Do something
});

我可以写一个类似的< code>ifNotExist,我希望它们是互斥的(如果< code>Exist条件为真,就不需要检查< code>ifNotExist,因为有时候,exist()方法检查起来工作量太大),但是我总是要检查两次。我该如何避免呢?

也许“存在”这个词让人误解了我的想法。你可以想象我也需要一些方法:

ifVisible()
ifEmpty()
ifHasAttribute()

很多人说这是个坏主意,但是:

在Java8中,我们可以使用lambda foreach而不是传统的for循环。在编程forif是两个基本的流控制。如果我们可以将lambda用于for循环,为什么将lambda用于if是个坏主意?

for (Element element : list) {
    element.doSomething();
}

list.forEach(Element::doSomething);

在Java 8中,ifPresent有< code>Optional,类似于我对ifExist的想法:

Optional<Elem> element = ...
element.ifPresent(el -> System.out.println("Present " + el);

关于代码维护和易读性,如果我有以下代码,其中有许多重复的简单if子句,你会怎么想?

if (e0.exist()) {
    e0.actionA();
} else {
    e0.actionB();
}

if (e1.exist()) {
    e0.actionC();
}

if (e2.exist()) {
    e2.actionD();
}

if (e3.exist()) {
    e3.actionB();
}

比较:

e0.ifExist(Element::actionA).ifNotExist(Element::actionB);
e1.ifExist(Element::actionC);
e2.ifExist(Element::actionD);
e3.ifExist(Element::actionB);

哪个更好?还有,哎呀,你注意到在传统的if子句代码中,有一个错误:

if (e1.exist()) {
    e0.actionC(); // Actually e1
}

我认为如果我们使用lambda,我们可以避免这个错误!

共有3个答案

狄望
2023-03-14

您可以使用采用两个使用者的单个方法:

public void ifExistOrElse(Consumer<Element> ifExist, Consumer<Element> orElse) {
    if (exist()) {
        ifExist.accept(this);
    } else {
        orElse.accept(this);
    }
}

然后用以下方式调用:

element.ifExistOrElse(
  el -> {
    // Do something
  },
  el -> {
    // Do something else
  });
谭飞掣
2023-03-14

它被称为“流畅的界面”。只需更改返回类型并返回此值;以允许您链接这些方法:

public MyClass ifExist(Consumer<Element> consumer) {
    if (exist()) {
        consumer.accept(this);
    }
    return this;
}

public MyClass ifNotExist(Consumer<Element> consumer) {
    if (!exist()) {
        consumer.accept(this);
    }
    return this;
}

您可以得到一个更高级的,并返回一个中间类型:

interface Else<T>
{
    public void otherwise(Consumer<T> consumer); // 'else' is a keyword
}

class DefaultElse<T> implements Else<T>
{
    private final T item;

    DefaultElse(final T item) { this.item = item; }

    public void otherwise(Consumer<T> consumer)
    {
        consumer.accept(item);
    }
}

class NoopElse<T> implements Else<T>
{
    public void otherwise(Consumer<T> consumer) { }
}

public Else<MyClass> ifExist(Consumer<Element> consumer) {
    if (exist()) {
        consumer.accept(this);
        return new NoopElse<>();
    }
    return new DefaultElse<>(this);
}

样品用法:

element.ifExist(el -> {
    //do something
})
.otherwise(el -> {
    //do something else
});
蒋星雨
2023-03-14

由于它几乎但并不完全匹配可选,也许您可能会重新考虑逻辑:

Java 8的表达能力有限:

Optional<Elem> element = ...
element.ifPresent(el -> System.out.println("Present " + el);
System.out.println(element.orElse(DEFAULT_ELEM));

在这里,地图可能会限制元素上的视图:

element.map(el -> el.mySpecialView()).ifPresent(System.out::println);

Java9:

element.ifPresentOrElse(el -> System.out.println("Present " + el,
                        () -> System.out.println("Not present"));

一般来说,这两个分支是不对称的。

 类似资料:
  • 请尝试使用一个开关,而不是太多的if语句。只是为了让我的代码更易读。因为switch只计算一个变量,我能在我的代码中使用switch吗,因为它看起来有点复杂。一个建议,请,因为所有有不同的元素选择使用css选择器。 提前谢谢。

  • 我有可选的问题,我不知道如何处理它。 如何将此if更改为可选?

  • 问题内容: 我一直习惯使用if,else-if语句,而不是多个if语句。 例: 与示例2相比如何? 我知道功能上它们是相同的。但是,如果不是,则是否是最佳做法?当我指出他可以不同地构造代码库以使其更整洁时,它是由我的一位朋友提出的。对我来说这已经是一种习惯,但是我从来没有问过为什么。 问题答案: 一旦找到正确的语句,它们就会停止进行比较。做每个比较。第一个是更有效的。 编辑: 在注释中已指出您在每

  • 我正在学习亚当·简斯的合唱团教程。 数据是用这个代码块加载的 而准备就绪被定义为 我把这个序列理解为 首先-创建一个名为promises的数组,其中第一项是来自此链接的已解析json,第二项是来自该文件的id/值对的映射 第二,获取promise变量中的所有promise,如果成功,则触发函数ready,如果失败,则不执行任何操作 如果这是对的,那么相对于这样的东西有什么优势呢?我用伪代码写这个因

  • 问题内容: Javascript 1.9.3 / ECMAScript5引入了DouglasCrockford等人提倡很长时间的技术。如何在下面的代码中替换为? (假设存在)。 我能想到的最好的是: 似乎没有任何优势,所以我想我没有。我可能太新古典了。我应该如何使用来创建用户“ bob”? 问题答案: 仅具有一个继承级别,您的示例可能无法让您看到的真正好处。 通过此方法,您可以轻松实现 差异继承

  • 问题内容: 每当我读到关于使用Scala的作者通常提的是演员,而应使用(此举例)。虽然我大致了解了Actor的工作原理,但我真的很想看到一个Actor的示例,该示例被用来在一段代码中替换Java的方法修饰符(这意味着它的Scala等效项- 块)。例如,修改数据结构的内部将很高兴。 这是对Actor的很好利用,还是我被误导了? 问题答案: Actor保证一次只处理一条消息,这样就不会有两个线程访问任