You can write, given for instance a List<Boolean>:

if (!list.stream().allMatch(x -> x)) {
    // not every member is true
}

Or:

if (list.stream().anyMatch(x -> !x)) {
    // at least one member is false
}

If you have an array of booleans, then use Arrays.stream() to obtain a stream out of it instead.


More generally, for a Stream providing elements of (generic) type X, you have to provide a Predicate<? super X> to .{all,any}Match() (either a "full" predicate, or a lambda, or a method reference -- many things go). The return value of these methods are self explanatory -- I think.


Now, to count elements which obey a certain predicate, you have .count(), which you can combine with .filter() -- which also takes (whatever is) a Predicate as an argument. For instance checking if you have more than 2 elements in a List<String> whose length is greater than 5 you'd do:

if (list.stream().filter(s -> s.length() > 5).count() > 2L) {
    // Yup...
}
Answer from fge on Stack Overflow
Top answer
1 of 2
13

You can write, given for instance a List<Boolean>:

if (!list.stream().allMatch(x -> x)) {
    // not every member is true
}

Or:

if (list.stream().anyMatch(x -> !x)) {
    // at least one member is false
}

If you have an array of booleans, then use Arrays.stream() to obtain a stream out of it instead.


More generally, for a Stream providing elements of (generic) type X, you have to provide a Predicate<? super X> to .{all,any}Match() (either a "full" predicate, or a lambda, or a method reference -- many things go). The return value of these methods are self explanatory -- I think.


Now, to count elements which obey a certain predicate, you have .count(), which you can combine with .filter() -- which also takes (whatever is) a Predicate as an argument. For instance checking if you have more than 2 elements in a List<String> whose length is greater than 5 you'd do:

if (list.stream().filter(s -> s.length() > 5).count() > 2L) {
    // Yup...
}
2 of 2
4

Your problem

Your current problem is that you use directly a lambda expression. Lambdas are instances of functional interfaces. Your lambda does not have the boolean type, that's why your if does not accept it.

This special case's solution

You can use a stream from your collections of booleans here.

if (bools.stream().allMatch((Boolean b)->b)) {
    // do something
}

It is actually much more powerful than this, but this does the trick I believe.

General hint

Basically, since you want an if condition, you want a boolean result. Since your result depends on a collection, you can use Java 8 streams on collections.

Java 8 streams allow you to do many operations on a collection, and finish with a terminal operation. You can do whatever complicated stuff you want with Stream's non-terminal operations. In the end you need one of 2 things:

  • use a terminal operation that returns a boolean (such as allMatch, anyMatch...), and you're done
  • use any terminal operation, but use it in a boolean expression, such as myStream.filter(...).limit(...).count() > 2

You should have a look at your possibilities in this Stream documentation or this one.

🌐
TutorialsPoint
tutorialspoint.com › how-to-write-a-conditional-expression-in-lambda-expression-in-java
How to write a conditional expression in lambda expression in Java?
interface Algebra { int substraction(int a, int b); } public class ConditionalExpressionLambdaTest { public static void main(String args[]) { System.out.println("The value is: " + getAlgebra(false).substraction(20, 40)); System.out.println("The value is: " + getAlgebra(true).substraction(40, 10)); } static Algebra getAlgebra(boolean reverse) { Algebra alg = reverse ? (a, b) -> a - b : (a, b) -> b - a; // conditional expression return alg; } }
Discussions

How to perform nested 'if' statements using Java 8/lambda? - Stack Overflow
I have the following code and would like to implement it using lambda functions just for fun. Can it be done using the basic aggregate operations? List result = new ArrayList More on stackoverflow.com
🌐 stackoverflow.com
if statement - Use Java lambda instead of 'if else' - Stack Overflow
I can write a similar ifNotExist, ... exist condition is true, there is no need to check ifNotExist, because sometimes, the exist() method takes so much workload to check), but I always have to check two times. How can I avoid that? Maybe the "exist" word make someone misunderstand my idea. You can imagine that I also need some methods: ... In Java 8 we can use lambda forEach instead ... More on stackoverflow.com
🌐 stackoverflow.com
use if-else statement in java-8 lambda expression - Stack Overflow
You can rewrite the code using filter() expressions, but it'll require a bigger re-working of the logic in the conditionals, which introduces the risk you might break something if this isn't tested well. The logic changes are exactly what @Holger and @Ole V.V. reference in their comments to the original question. Whether you use forEach() or the filters, lambdas ... More on stackoverflow.com
🌐 stackoverflow.com
How do you use conditions in lambda expression in java 8? - Stack Overflow
But if 5 is input, expected output is 3. If 4 is input, output should be 2... This doesn't match the function in the question 2017-05-07T18:34:32.653Z+00:00 ... @cricket_007 "my question is how can i write a lambda expression that covers this function" Explain how. More on stackoverflow.com
🌐 stackoverflow.com
🌐
Code with Mosh
forum.codewithmosh.com › t › using-lambda-expressions-for-if-statements › 13119
Using lambda expressions for if statements - Code with Mosh Forum
June 16, 2022 - Hello all! First post here haha, I’ll get right to it :slight_smile: I was recently asked as a challenge to represent a validation method as a lambda expression and the implication was that this was somehow more effic…
🌐
W3Schools
w3schools.com › java › java_lambda.asp
Java Lambda Expressions
The simplest lambda expression contains a single parameter and an expression: ... Simple expressions must return a value immediately. They cannot contain multiple statements, such as loops or if conditions...
Top answer
1 of 5
39

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.

2 of 5
21

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
});
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › using ‘if-else’ conditions with java streams
Using 'if-else' Conditions with Java Streams - HowToDoInJava
March 3, 2022 - We can also write the pass the Consumer implementation as an inline lambda expression to the forEach() function. Arrays.asList(-1, 1, -2, 3, 4, -5, 6, 0).stream() .forEach( i -> { if (i == 0) { System.out.println("Number is 0"); } else if (i > 0) { System.out.println("Positive Number"); } else { System.out.println("Negative Number"); } } ); If we intend to apply only 'if' logic then we can pass the condition directly do the filter() function as a Predicate.
Find elsewhere
🌐
Javatpoint
javatpoint.com › if-condition-in-lambda-expression-java
if Condition in Lambda Expression Java - Javatpoint
if Condition in Lambda Expression Java with java tutorial, features, history, variables, programs, operators, oops concept, array, string, map, math, methods, examples etc.
🌐
GeeksforGeeks
geeksforgeeks.org › java › lambda-expressions-java-8
Java Lambda Expressions - GeeksforGeeks
This is a zero-parameter lambda expression! ... It is not mandatory to use parentheses if the type of that variable can be inferred from the context. Parentheses are optional if the compiler can infer the parameter type from the functional interface. ... import java.util.ArrayList; public class GFG{ public static void main(String[] args){ ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); System.out.println("All elements:"); list.forEach(n -> System.out.println(n)); System.out.println("Even elements:"); list.forEach(n -> { if (n % 2 == 0) System.out.println(n); }); } }
Published   3 weeks ago
🌐
Oracle
docs.oracle.com › javase › tutorial › java › javaOO › lambdaexpressions.html
Lambda Expressions (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
If the Person instance does satisfy the criteria specified by tester, the method printPerson is invoked on the Person instance. Instead of invoking the method printPerson, you can specify a different action to perform on those Person instances that satisfy the criteria specified by tester. You can specify this action with a lambda expression.
Top answer
1 of 3
6

As a stream call chain is complex make two streams - avoiding the conditional branches.

String ncourseIds = equivalentCourses.stream()
   .filter(equivalentCourse -> equivalentCourse.getNcourse() != null)
   .map(EquivalentCourse::getNcourse)
   .map(x -> String.valueOf(x.getId()))
   .collect(Collectors.joining(", "));

String pastCourseIds = equivalentCourses.stream()
   .filter(equivalentCourse -> equivalentCourse.getNcourse() == null
          && equivalentCourse.getPastCourse() != null)
   .map(EquivalentCourse::getPastCourse)
   .map(x -> String.valueOf(x.getId()))
   .collect(Collectors.joining(", "));

This also is code focusing on the resulting two strings, with an efficient joining.

By the way, if this is for an SQL string, you may use a PreparedStatement with an Array.


Embellishment as commented by @Holger:

String ncourseIds = equivalentCourses.stream()
   .map(EquivalentCourse::getNcourse)
   .filter(Objects::nonNull)
   .map(NCourse::getId)
   .map(String::valueOf)
   .collect(Collectors.joining(", "));

String pastCourseIds = equivalentCourses.stream()
   .filter(equivalentCourse -> equivalentCourse.getNcourse() == null)
   .map(EquivalentCourse::getPastCourse)
   .filter(Objects::nonNull)
   .map(EquivalentCourse::getPastCourse)
   .map(PastCourse::getId)
   .map(String::valueOf)
   .collect(Collectors.joining(", "));
2 of 3
1

You could group by condition and then remap:

public void booleanGrouping() throws Exception {
    List<String> strings = new ArrayList<>();
    strings.add("ala");
    strings.add("ela");
    strings.add("jan");

    strings.stream()
            .collect(
                    Collectors.groupingBy(s -> s.endsWith("a")) // using function Obj -> Bool not predicate
            ).entrySet()
            .stream()
            .collect(
                    Collectors.toMap(
                            e -> e.getKey() ? "Present" : "Past",
                            e -> e.getValue().stream().collect(Collectors.joining(""))
                    )
            );
}

First stream group by condition, you should use equivalentCourse.getNcourse() != null second remap collections from value to string. You could introduce:

enum PresentPast{
    Present, Past
    PresentPast is(boolean v){
         return v ? Present : Past
    }
}

and change e -> e.getKey() ? "Present" : "Past" to enum based solution.

Edit:

Solution for else if:

public Map<Classifier, String> booleanGrouping() throws Exception {
    List<String> strings = new ArrayList<>();
    strings.add("ala");
    strings.add("ela");
    strings.add("jan");
    // our ifs:
    /*
        if(!string.endsWith("n")){
        }else if(string.startsWith("e")){}

        final map should contains two elements
        endsWithN -> ["jan"]
        startsWithE -> ["ela"]
        NOT_MATCH -> ["ala"]

     */
    return strings.stream()
            .collect(
                    Collectors.groupingBy(Classifier::apply) // using function Obj -> Bool not predicate
            ).entrySet()
            .stream()
            .collect(
                    Collectors.toMap(
                            e -> e.getKey(),
                            e -> e.getValue().stream().collect(Collectors.joining(""))
                    )
            );
}

enum Classifier implements Predicate<String> {
    ENDS_WITH_N {
        @Override
        public boolean test(String s) {
            return s.endsWith("n");
        }
    },
    STARTS_WITH_E {
        @Override
        public boolean test(String s) {
            return s.startsWith("e");
        }
    }, NOT_MATCH {
        @Override
        public boolean test(String s) {
            return false;
        }
    };

    public static Classifier apply(String s) {
        return Arrays.stream(Classifier.values())
                .filter(c -> c.test(s))
                .findFirst().orElse(NOT_MATCH);
    }
}
🌐
Stack Overflow
stackoverflow.com › questions › 45006435 › how-to-make-lambda-expression-as-a-condition-in-if-then-statement
java - How to make lambda expression as a condition in if-then statement - Stack Overflow
Is it either of these you mean? public static void main(String[] args) { boolean ifResult = lambdaIf( (pInt) -> { //Call lambdaIf with a function if(pInt == 0) { //Our lambda has an if-case for its input return true; } else { return false; } } ); ...
🌐
Tpoint Tech
tpointtech.com › if-condition-in-lambda-expression-java
if Condition in Lambda Expression Java - Tpoint Tech
How to Return Value from Lambda Expression Java · if Condition in Lambda Expression Java · Chained Exceptions in Java · Final static variable in Java · Java File Watcher · Various Operations on HashSet in Java · Word Ladder Problem in Java · Various Operations on Queue in Java ·
🌐
Medium
medium.com › @marcelogdomingues › java-lambda-expressions-techniques-for-advanced-developersava-lambda-expressions-techniques-for-c1d71c30bb1f
Java Lambda Expressions: Techniques for Advanced Developersava Lambda Expressions: Techniques for…
June 21, 2024 - When a lambda expression merely calls an existing method, use a method reference instead. ... Handle exceptions within lambda expressions appropriately. If a lambda expression throws a checked exception, it must be handled within the lambda expression. import java.util.Arrays; import java.util.List; public class LambdaExample { public static void main(String[] args) { List<String> names = Arrays.asList("John", "Jane", "Jack", "Jill"); names.forEach(name -> { try { System.out.println(name); } catch (Exception e) { e.printStackTrace(); } }); } }
Top answer
1 of 2
2

If/else or even switch are not the "good OO design" answer. Neither are lambdas. Retrieving the status from somewhere, to make then a decision based on that - that is procedural programming; not OO.

You see, what you actually have in front of you - is a state machine. You have different states; and the point is: if your "thing" is in state A; then you want to do something ( invoke handleA() ). If your are in state B; you want to do something too ( like invoke handleB() ).

So, what you actually have is:

abstract class State {
  abstract void doIt();
...

StateA extends State {
  @Override
  void doIt() { handleA(); }

So, from the client side, you just call doIt() on same object of class State.

Thus: if you are really interested in improving your code base, learn how to use polymorphism to get rid of your if/else/switch statements.

You can watch this video to get an idea what I am talking about.

2 of 2
0

Maybe I hadn't fully explained my problem, but my colleague proposed another solution that I really like. He suggested I make the if-else block a java.util.Supplier, and invoke it in the Entity class where I need it.

So my code went from this block of logic sprinkled everywhere:

public class ServiceImpl {
  ...
  if (entity.getStatus) == 'A' then
    finalStatus = handleA();
  else if (entity.getStatus() == 'B') then
    finalStatus = handleB();
  else
    finalStatus = handleEverythingElse();
  ...
}

To this nicely compacted form:

public class ServiceImpl {
  finalStatus = entity.getFinalStatus(this::handleStatus);

  public int handleStatus() {
    return dao.getStatus();
  }
}

With the implementation in my Entity class:

public class Entity {
  public int handleStatus(Supplier<Integer> s) {
    int finalStatus;
    if (status) == 'A' then
      finalStatus = handleA();
    else if (status() == 'B') then
      finalStatus = handleB();
    else
      finalStatus = supplier.get();
    return status;
  }
}

I hope this make sense...

🌐
Baeldung
baeldung.com › home › java › java streams › how to use if/else logic in java streams
How to Use if/else Logic in Java Streams | Baeldung
May 28, 2024 - Our forEach method contains if/else logic that verifies whether the Integer is an odd or even number using the Java modulus operator.
🌐
Stack Overflow
stackoverflow.com › questions › 33249601 › java-if-else-in-a-lambda-expression
if statement - Java if else in a lambda expression - Stack Overflow
October 21, 2015 - Note that this would not compile if permissions is a Map, because the signature of Map.put is not compliant. Another simplification (beyond those already mentioned by others): public void addPermission(String permission, String resource){ permissions.put(new Permission(permission, ()-> permission.charAt(permissions.size() - 1) == '*')); } The type of the given lambda should be a FunctionalInterface with no argument and result Boolean, e.g.
🌐
Looks OK!
looksok.wordpress.com › 2014 › 03 › 29 › java-8-lambda-expression-example
Java 8: Lambda expression example – Looks OK!
July 5, 2022 - The shortest Lambda you can write If you want your test condition to always evaluate to true (return true), the lambda expression would look like this: ... But then why would you need the PersonInfo in this statement? If you refactor your interface method not to take any arguments like this: ... The lambda would not need the PersonInfo param. Guess how it would look like? Well… exactly like that: ... Using built-in Java functional interfaces: Predicate Here I used my own functional interface to provide test method.