We Are Going To Discuss About Use Java lambda instead of ‘if else’. So lets Start this Java Article.
Use Java lambda instead of ‘if else’
- Use Java lambda instead of 'if else'
As it almost but not really matches Optional, maybe you might reconsider the logic:
Java 8 has a limited expressiveness:Optional<Elem> element = ... element.ifPresent(el -> System.out.println("Present " + el); System.out.println(element.orElse(DEFAULT_ELEM));
- Use Java lambda instead of 'if else'
As it almost but not really matches Optional, maybe you might reconsider the logic:
Java 8 has a limited expressiveness:Optional<Elem> element = ... element.ifPresent(el -> System.out.println("Present " + el); System.out.println(element.orElse(DEFAULT_ELEM));
Solution 1
As it almost but not really matches Optional, maybe you might reconsider the logic:
Java 8 has a limited expressiveness:
Optional<Elem> element = ...
element.ifPresent(el -> System.out.println("Present " + el);
System.out.println(element.orElse(DEFAULT_ELEM));
Here the map
might restrict the view on the element:
element.map(el -> el.mySpecialView()).ifPresent(System.out::println);
Java 9:
element.ifPresentOrElse(el -> System.out.println("Present " + el,
() -> System.out.println("Not present"));
In general the two branches are asymmetric.
Original Author Joop Eggen Of This Content
Solution 2
It’s called a ‘fluent interface’. Simply change the return type and return this;
to allow you to chain the methods:
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;
}
You could get a bit fancier and return an intermediate type:
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);
}
Sample usage:
element.ifExist(el -> {
//do something
})
.otherwise(el -> {
//do something else
});
Original Author Michael Of This Content
Solution 3
You can use a single method that takes two consumers:
public void ifExistOrElse(Consumer<Element> ifExist, Consumer<Element> orElse) {
if (exist()) {
ifExist.accept(this);
} else {
orElse.accept(this);
}
}
Then call it with:
element.ifExistOrElse(
el -> {
// Do something
},
el -> {
// Do something else
});
Original Author Eran Of This Content
Solution 4
The problem
(1) You seem to mix up different aspects – control flow and domain logic.
element.ifExist(() -> { ... }).otherElementMethod();
^ ^
control flow method business logic method
(2) It is unclear how methods after a control flow method (like ifExist
, ifNotExist
) should behave. Should they be always executed or be called only under the condition (similar to ifExist
)?
(3) The name ifExist
implies a terminal operation, so there is nothing to return – void
. A good example is void ifPresent(Consumer)
from Optional
.
The solution
I would write a fully separated class that would be independent of any concrete class and any specific condition.
The interface is simple, and consists of two contextless control flow methods – ifTrue
and ifFalse
.
There can be a few ways to create a Condition
object. I wrote a static factory method for your instance (e.g. element
) and condition (e.g. Element::exist
).
public class Condition<E> {
private final Predicate<E> condition;
private final E operand;
private Boolean result;
private Condition(E operand, Predicate<E> condition) {
this.condition = condition;
this.operand = operand;
}
public static <E> Condition<E> of(E element, Predicate<E> condition) {
return new Condition<>(element, condition);
}
public Condition<E> ifTrue(Consumer<E> consumer) {
if (result == null)
result = condition.test(operand);
if (result)
consumer.accept(operand);
return this;
}
public Condition<E> ifFalse(Consumer<E> consumer) {
if (result == null)
result = condition.test(operand);
if (!result)
consumer.accept(operand);
return this;
}
public E getOperand() {
return operand;
}
}
Moreover, we can integrate Condition
into Element
:
class Element {
...
public Condition<Element> formCondition(Predicate<Element> condition) {
return Condition.of(this, condition);
}
}
The pattern I am promoting is:
- work with an
Element
; - obtain a
Condition
; - control the flow by the
Condition
; - switch back to the
Element
; - continue working with the
Element
.
The result
Obtaining a Condition
by Condition.of
:
Element element = new Element();
Condition.of(element, Element::exist)
.ifTrue(e -> { ... })
.ifFalse(e -> { ... })
.getOperand()
.otherElementMethod();
Obtaining a Condition
by Element#formCondition
:
Element element = new Element();
element.formCondition(Element::exist)
.ifTrue(e -> { ... })
.ifFalse(e -> { ... })
.getOperand()
.otherElementMethod();
Update 1:
For other test methods, the idea remains the same.
Element element = new Element();
element.formCondition(Element::isVisible);
element.formCondition(Element::isEmpty);
element.formCondition(e -> e.hasAttribute(ATTRIBUTE));
Update 2:
It is a good reason to rethink the code design. Neither of 2 snippets is great.
Imagine you need actionC
within e0.exist()
. How would the method reference Element::actionA
be changed?
It would be turned back into a lambda:
e0.ifExist(e -> { e.actionA(); e.actionC(); });
unless you wrap actionA
and actionC
in a single method (which sounds awful):
e0.ifExist(Element::actionAAndC);
The lambda now is even less ‘readable’ then the if
was.
e0.ifExist(e -> {
e0.actionA();
e0.actionC();
});
But how much effort would we make to do that? And how much effort will we put into maintaining it all?
if(e0.exist()) {
e0.actionA();
e0.actionC();
}
Original Author Andrew Tobilko Of This Content
Conclusion
So This is all About This Tutorial. Hope This Tutorial Helped You. Thank You.