If, ElseIf and Else with Java 8

I would like to build a method using Java 8, replacing the IF, ELSE-IF and ELSE conditionals. For this, I built a code sequence, I do not know if it is the ideal one and I would like to hear opinions or better solutions.

public static void main(String[] args) {
    String a = " A ";
    String b = " B ";
    String c = " C ";
    String d = null;


    String teste = Optional.ofNullable(d)
            .map(String::trim)
            .orElseGet(() -> Optional.ofNullable(a)
                    .map(String::trim)
                    .orElseGet(() -> Optional.ofNullable(b)
                            .map(String::trim)
                            .orElseGet(() -> Optional.ofNullable(c)
                                    .map(String::trim)
                                    .orElse(""))));

    System.out.println(teste);
}

For didactic purposes, I used Strings as examples, but what if for example we had the following case: let's use a "private String returnsearch(string regex)"method. If the regex finds something, it returns the String. If she returns NULL, I call the method again with another regex. And so it goes until the regex runs out and returns by default the empty value ( "" )

Follows example:

public static void main(String[] args) {
    String regexA = "A";
    String regexB = "B";
    String regexC = "C";

    Pattern patternA = Pattern.compile(regexA);
    Pattern patternB = Pattern.compile(regexB);
    Pattern patternC = Pattern.compile(regexC);

    String valor = " C ";


    String teste = Optional.ofNullable(valor)
            .map(str -> retornaBusca(str, patternA))
            .orElseGet(() -> Optional.ofNullable(valor)
                    .map(str -> retornaBusca(str, patternB))
                    .orElseGet(() -> Optional.ofNullable(valor)
                            .map(str -> retornaBusca(str, patternC))
                            .orElse("")));

    System.out.println(teste);
}

private static String retornaBusca(String str, Pattern regex) {
    return Optional.ofNullable(str)
            .map(regex::matcher)
            .filter(Matcher::find)
            .map(Matcher::group)
            .map(String::trim)
            .orElse(null);
}
Author: Gustavo, 2019-04-10

2 answers

The problem is that you're not using Stream s, just a bunch of Optional s.the way you did, the code is tied to having exactly four variables, not just any number.

Try This:

import java.util.Arrays;
import java.util.Optional;

public class TesteOptional {
    public static void main(String[] args) {
        String a = " A ";
        String b = " B ";
        String c = " C ";
        String d = null;

        String teste = Arrays.asList(a, b, c, d)
                .stream()
                .map(Optional::ofNullable)
                .filter(Optional::isPresent)
                .map(Optional::orElseThrow)
                .map(String::trim)
                .findFirst()
                .orElse("");

        System.out.println(teste);
    }
}

Or if you prefer something simpler and faster, but less purist:

import java.util.Arrays;
import java.util.Optional;

public class TesteOptional {
    public static void main(String[] args) {
        String a = " A ";
        String b = " B ";
        String c = " C ";
        String d = null;

        String teste = Arrays.asList(a, b, c, d)
                .stream()
                .filter(x -> x != null)
                .map(String::trim)
                .findFirst()
                .orElse("");

        System.out.println(teste);
    }
}

Considering the editing of the question, I came to this:

import java.util.Arrays;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TesteOptional2 {
    public static void main(String[] args) {
        Pattern a = Pattern.compile(" A ");
        Pattern b = Pattern.compile(" B ");
        Pattern c = Pattern.compile(" C ");

        String valor = " C ";

        String teste = Arrays.asList(a, b, c)
                .stream()
                .map(p -> retornaBusca(valor, p))
                .filter(Optional::isPresent)
                .map(Optional::orElseThrow)
                .findFirst()
                .orElse("");

        System.out.println(teste);
    }

    private static Optional<String> retornaBusca(String str, Pattern regex) {
        return Optional
                .ofNullable(str)
                .map(regex::matcher)
                .filter(Matcher::find)
                .map(Matcher::group)
                .map(String::trim);
    }
}

Note that in the example above, the regex parameter of retornaBusca cannot be null. I don't know if I understood right what you want, but I think that's it.

 8
Author: Victor Stafusa, 2019-04-12 14:23:31

A simple for solves your problem:

class Main {

  public static void main(String[] args) {
    String result = findMatchingRegex(Arrays.asList(
        () -> testRegex(null),
        () -> testRegex(" A "),
        () -> testRegex(" B "),
        () -> testRegex(" C ")
    ));

    System.out.println(result);
  }

  public static String findMatchingRegex(List<Supplier<String>> suppliers) {
    for (Supplier<String> supplier : suppliers) {
      String value = supplier.get();
      if(value != null) {
        return value.trim();
      }
    }
    return "";
  }

  public static String testRegex(String input) {
    return input;
  }
}

But if you want to work with streams (borrowing from @ Victor Stafusa):

public static String findMatchingRegex(List<Supplier<String>> suppliers) {
  return suppliers.stream()
      .map(Supplier::get)
      .filter(Objects::nonNull)
      .findFirst()
      .map(String::trim)
      .orElse("");
}
 3
Author: Leonardo Lima, 2019-04-11 13:14:52