【发布时间】:2018-09-26 04:31:31
【问题描述】:
使用 Java 8,我有以下代码:
if(element.exist()){
// Do something
}
我想转换成 lambda 样式,
element.ifExist(el -> {
// Do something
});
使用这样的ifExist 方法:
public void ifExist(Consumer<Element> consumer) {
if (exist()) {
consumer.accept(this);
}
}
但现在我还有其他情况要调用:
element.ifExist(el -> {
// Do something
}).ifNotExist(el -> {
// Do something
});
我可以写一个类似的ifNotExist,并且我希望它们是互斥的(如果exist条件为真,则不需要检查ifNotExist,因为有时,exist()方法需要这么多工作量要检查),但我总是要检查两次。我怎样才能避免这种情况?
也许“存在”这个词会让人误解我的想法。你可以想象我还需要一些方法:
ifVisible()
ifEmpty()
ifHasAttribute()
很多人说这是个坏主意,但是:
在 Java 8 中,我们可以使用 lambda forEach 代替传统的 for 循环。在编程中for 和if 是两个基本的流控制。如果我们可以将 lambda 用于 for 循环,为什么将 lambda 用于 if 是个坏主意?
for (Element element : list) {
element.doSomething();
}
list.forEach(Element::doSomething);
在 Java 8 中,Optional 带有 ifPresent,类似于我对 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,我们可以避免这个错误!
【问题讨论】:
-
出于好奇,您希望通过用 lambda 替换 if-else 语句获得什么好处? (我能想到的唯一副作用是代码执行的额外开销,对于以后必须维护这种模式的可怜的 sap 来说是最可悲的)
-
仅供参考,如果我看到您在生产代码中这样做,我会与我们的主管/经理讨论您无法编写干净、简单的代码。在生产环境中使用
if/else。 -
@jpmc26 你听起来像一个梦想工作
-
@Michael 对不起,如果我对那些因为试图遵循某些原则或时尚而编写糟糕代码的人失去了耐心。大约 6 年以来,一直试图让这样的系统在轨道上运行,还有几个月的时间,当我离开时,有人将它 远远 开得离轨道更远。 (不是开玩笑,我们不得不重写在那段时间里完成的几乎所有事情,不管怎样,那些实际上已经成功的部分。)所以我尽量劝阻那些不是基于解决问题的想法,保存为尽可能多的心痛。
-
回应其他人所说的:如果您这样做是为了练习,那很好,但请不要在实际代码中这样做。包括您自己在内的开发人员在维护现有代码上花费的时间比编写新东西要多得多,因此编写代码使其尽可能易于阅读符合您和我们的最大利益。 if/else 语句是正常且良好的。
标签: java if-statement lambda java-8