Second decoction: Try an If expression in Java

The second decoction of "Try If expression in Java".

What can be achieved

For example, you can write FizzBuzz as follows:

    public static void main(String... args) {
        for (int i = 1; i <= 100; ++i) {
            int count = i;
            String fizzBuzzed = 
                    If.<String>test(() -> count % 15 == 0).then(() -> "FizzBuzz")
                    .elif(() -> count % 3 == 0).then(() -> "Fizz")
                    .elif(() -> count % 5 == 0).then(() -> "Buzz")
                    .el(() -> Integer.toString(count));
            System.out.println(fizzBuzzed);
        }
    }

Preparation

Because it handles a nullable value as the value of the if expression Create the following generic class.

import java.util.function.Supplier;

/**
 *null can also be taken as a value{@link java.util.Optional}。
 * 
 *Methods not used this time are omitted.
 */
public class MayBe<T> {

    /**
     *Create an instance where the value exists.
     */
    public static <R> MayBe<R> of(R result) {
        return new MayBe<>(true, result);
    }

    /**
     *Create an instance that does not have a value.
     */
    public static <R> MayBe<R> empty() {
        return new MayBe<>(false, null);
    }

    private final boolean isPresent;
    private final T value;

    private MayBe(boolean isPresent, T value) {
        this.isPresent = isPresent;
        this.value = value;
    }

    /**
     *Returns whether the value exists.
     */
    public boolean isPresent() {
        return this.isPresent;
    }

    /**
     *If the value exists, it returns it, otherwise it returns the value obtained from the argument other.
     */
    public T orElseGet(Supplier<T> other) {
        return isPresent() ? this.value : other.get();
    }
}

Production

import java.util.function.BooleanSupplier;
import java.util.function.Supplier;

public class If<R> {

    public static <R> If<R> test(BooleanSupplier predicate) {
        return new If<>(predicate, null);
    }

    private final If<R> prev;
    private final BooleanSupplier predicate;

    private Then<R> then = null;

    /**
     * @param predicate A predicate for this if.
     * @param prev If this if is else if, the previous if.
     *Otherwise, null.
     */
    private If(BooleanSupplier predicate, If<R> prev) {
        this.prev = prev;
        this.predicate = predicate;
    }

    public Then<R> then(Supplier<R> valueSupplier) {
        if (this.then != null) {
            throw new IllegalStateException("`then`Has already been called.");
        }

        return this.then = new Then<>(this, valueSupplier);
    }

    /**
     *Evaluate up to this if.
     * 
     * @return The value of the evaluation result.
     */
    private MayBe<R> eval() {
        if (this.then == null) {
            throw new IllegalStateException("`then`Has not been called yet.");
        }

        if (this.prev != null) {
            MayBe<R> prevValue = this.prev.eval();
            if (prevValue.isPresent()) {
                return prevValue;
            }
        }

        return this.predicate.getAsBoolean()
                ? MayBe.of(this.then.getThenValue())
                : MayBe.empty();
    }

    /**
     * {@link If#then}The class of the object returned by.
     */
    public static class Then<R> {
        private final If<R> relatedIf;
        private final Supplier<R> thenValueSupplier;

        /**
         * @param relatedIf This then if.
         * @param valueSupplier The value to return if this then if is true.
         */
        Then(If<R> relatedIf, Supplier<R> valueSupplier) {
            this.relatedIf = relatedIf;
            this.thenValueSupplier = valueSupplier;
        }

        public If<R> elif(BooleanSupplier predicate) {
            return new If<>(predicate, this.relatedIf);
        }

        public R el(Supplier<R> valueSupplier) {
            return this.relatedIf.eval().orElseGet(valueSupplier);
        }

        /**
         *Returns the value if this then if is true.
         */
        R getThenValue() {
            return this.thenValueSupplier.get();
        }
    }
}

Features

--Only the necessary predicates of if are evaluated. --Only those that need to get the value are evaluated. --You can use else if (ʻelif`), so you don't have to nest deeply.

Impressions

It's easier to read if it's like an immediate function in JavaScript.

    public static void main(String... args) {
        for (int i = 1; i <= 100; ++i) {
            int count = i;
            String fizzBuzzed = ((Supplier<String>) () -> {
                if (count % 15 == 0) return "FizzBuzz";
                else if (count % 3 == 0) return "Fizz";
                else if (count % 5 == 0) return "Buzz";
                else return Integer.toString(count);
            }).get();
            System.out.println(fizzBuzzed);
        }
    }

/that's all

Recommended Posts

Second decoction: Try an If expression in Java
Try an If expression in Java
How to solve an Expression Problem in Java
Try using RocksDB in Java
Try calling JavaScript in Java
Try developing Spresense in Java (1)
Try functional type in Java! ①
I sent an email in Java
Try implementing Android Hilt in Java
Try implementing GraphQL server in Java
Try running Selenuim 3.141.59 in eclipse (java)
I made an annotation in Java.
Try running AWS X-Ray in Java
Try to implement Yubaba in Java
Run an external process in Java
Try to solve Project Euler in Java
Try to implement n-ary addition in Java
Try using the Stream API in Java
Map without using an array in java
Try using JSON format API in Java
Try calling the CORBA service in Java 11+
Try making a calculator app in Java
I want to ForEach an array with a Lambda expression in Java
Try adding text to an image in Scala using the Java standard library
I get an error when I try to use "^" or "$" in ruby ​​regular expression
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (Javassist second decoction)
Be careful if you find SHIFT-JIS in Java
I want to send an email in Java.
Try scraping about 30 lines in Java (CSV output)
Try using Sourcetrail (win version) in Java code
Try using GCP's Cloud Vision API in Java
Try using Sourcetrail (macOS version) in Java code
Try using the COTOHA API parsing in Java
Partization in Java
Try Java 8 Stream
Rock-paper-scissors in Java
[Java] Lambda expression
Pi in Java
Roughly try Java 9
Java lambda expression
FizzBuzz in Java
Omission of curly braces in if statement (Java silver)
I wrote about Java downcast in an easy-to-understand manner
It's late! Try implementing Android Notification in Java (Beginner)
Do not write if (isAdmin == true) code in Java
Try to make an addition program in several languages
Quickly implement a singleton with an enum in Java
Output true with if (a == 1 && a == 2 && a == 3) in Java (Invisible Identifier)
I tried using an extended for statement in Java
Try global hooking in Java using the JNativeHook library
Try to solve a restricted FizzBuzz problem in Java