Write a third If statement that is neither an if statement nor a ternary operator

I don't know what you're talking about, but I'll explain it properly.

When I have to write this kind of code, I get wrinkles between my eyebrows.

python


String s = null;
if (testSomeCond()) {
    s = "is true";
} else {
    s = "is false";
}
doSomething(s);

The ternary operator is useful in such cases.

python


String s = testSomeCond() ? "is true" : "is false";
doSomething(s);

You can write like this.

This ternary operator is often controversial about its readability and poor readability, and it is cut off completely in the Go language. Personally, I like ternary operators, but I find it difficult to read when conditions and return values are long.

So how about writing like this?

python


String s = If.correct(testSomeCond()).then("is true").orElse("is false");
doSomething(s);

Don't you think that this "If statement" can understand the process as if you were reading English normally? In addition, readability is not impaired so much even if the condition and return value part become a little long.

python


String s = If.correct(testSooooooooooooooooooooooooooooooooomething())
        .then("is trueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
        .orElse("is falseeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
doSomething(s);

Of course, the above will cause a compile error, so please add the following 3 classes when using it. (Only Java 8 and above are supported)

python


public class If {
    public static BoolSaver correct(Boolean b) {
        return () -> b;
    }
}

@FunctionalInterface
public interface BoolSaver {
    Boolean get();

    default <A> Else<A> then(A a1) {
        return (A a2) -> get() ? a1 : a2;
    }
}

@FunctionalInterface
public interface Else<A> {
    A orElse(A a2);
}

I have uploaded a sample or github, so please take a look if you are interested. https://github.com/mt-village/nagare


Below, postscript

python


int[] a = {1,2};
int i = 3;
int result = If.correct(i < a.length).then(a[i]).orElse(-1);

I made some modifications to solve the problem that an exception (ArrayIndexOutOfBoundsException) occurs even though a [i] is not actually used in a pattern like this.

python


int[] a = {1,2};
int i = 3;
//Normal writing
int a = If.correct(i < a.length).then(a.length).orElse(i);
//How to write when one of the return values can raise an exception
int b = If.correct(i < a.length)
    .then(() -> a[i])
    .orElse(() -> -1);

Enabled to take Supplier as an argument. From a safety point of view, I think it's better to use only the Supplier, but from the point of view of improving readability, which is the original purpose, I made it possible to do both.

To enable the above writing, you need to add 1 class and add 4 classes.

python


public class If {
    public static BoolSaver correct(Boolean b) {
        return () -> b;
    }
}

@FunctionalInterface
public interface BoolSaver {
    Boolean get();

    default <A> Else<A> then(A a1) {
        return (A a2) -> get() ?  a1 : a2;
    }

    default <A> ElseSaver<A> then(Supplier<A> a1) {
        return (Supplier<A> a2) -> get() ? a1.get() : a2.get();
    }
}

@FunctionalInterface
public interface Else<A> {
    A orElse(A a2);
}

@FunctionalInterface
public interface ElseSaver<A> {
    A orElse(Supplier<A> a2);
}

Thank you for pointing out @ saka1029!

Recommended Posts

Write a third If statement that is neither an if statement nor a ternary operator
[Java] Conditional branching is an if statement, but there is also a conditional operator.
How to write a ternary operator
How to write an if statement to improve readability-java
What is an operator?
Is the ternary operator evil?
Let's write a code that is easy to maintain (Part 2) Name