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);
}
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.
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("");
}