1

I have a problem with Java 8 if statements. Can someone show me a way to write this code without if's using only Java 8 lambdas? The solution shouldn't have if's, while's or for's. Is it even possible?

if (first_number == second_number) {
  return "PERFECT";
} else if (first_number > second_number) {
  return "ABUNDANT";
} else {
  return "DEFICIENT";
}
0

2 Answers 2

7

No "if's, while's or for's", but no lambdas either:

return (first_number == second_number ? "PERFECT" :
        first_number > second_number ? "ABUNDANT" : "DEFICIENT");

The ? : is called the conditional operator in the Java Language Specification (see 15.25. Conditional Operator ? :), but is commonly known as the ternary operator, since it is the only operator in Java with 3 parts.

Sign up to request clarification or add additional context in comments.

Comments

0

How about this solution with lambdas? I'm assuming integer values, but shouldn't be too hard to switch to float or double.

    int first_number = 10;
    int second_number = 20;
    IntBinaryOperator subtract = (n1, n2) -> n1 - n2; // Subtract second from first value
    IntUnaryOperator determineSign = n -> Integer.signum(n); // Determine the sign of the subtraction
    IntFunction<String> message = key -> { // Sign of 0 means value has been 0 (first_number == second_number). Sign of 1 = positive value, hence equals first_number > second_number, otherwise return the default.
        Map<Integer, String> messages = new HashMap<>();
        messages.put(0, "PERFECT");
        messages.put(1, "ABUNDANT");
        return messages.getOrDefault(key, "DEFICIENT");
    };

     return message.apply(determineSign.applyAsInt(subtract.applyAsInt(first_number, second_number)));

Edit: Andreas mentioned valid concerns, I agree you wouldn't do it like that. But I think its more about proving that it is possible using lambdas. :) Another method (ab)using Optional:

    int first_number = 20;
    int second_number = 20;

    Optional<Integer> dummy = Optional.of(0); // Dummy allowing to call filter on the Optional
    Predicate<Integer>isAbundant = i -> first_number > second_number; // Check if input is abundant
    Predicate<Integer> isPerfect = i -> first_number == second_number; // Check if input is perfect
    Supplier<String> other = () -> dummy.filter(isAbundant).map(i -> "ABUNDANT").orElse("DEFICIENT"); // Fallback, if input is not perfect. Check for abundant or return default
    Supplier<String> validate = () -> dummy.filter(isPerfect).map(i -> "PERFECT").orElse(other.get()); // Check if input is perfect or use fallback

    return validate.get();

5 Comments

Warning: n1 - n2 may overflow and produce incorrect result.
Creating a Map and boxing a signum value just to pick one of 3 strings is very inefficient, both space- and performance-wise.
@Andreas plus all that noise by unnecessarily creating all these functions. If we really want to go into the direction of providing the constants as collection, it would be as simple as return List.of("DEFICIENT", "PERFECT", "ABUNDANT") .get(1 + Integer.signum(Integer.compare(first_number, second_number)));
@Holger: It requires Java 9 though and the question stated Java 8. Nevertheless I like the Java 9 way. :)
There is no problem replacing List.of with Arrays.asList

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.