83

Let's say I want to see if an object exists in a stream and if it is not present, throw an Exception. One way I could do that would be using the orElseThrow method:

List<String> values = new ArrayList<>();
values.add("one");
//values.add("two");  // exception thrown
values.add("three");
String two = values.stream()
        .filter(s -> s.equals("two"))
        .findAny()
        .orElseThrow(() -> new RuntimeException("not found"));

What about in the reverse? If I want to throw an exception if any match is found:

String two = values.stream()
        .filter(s -> s.equals("two"))
        .findAny()
        .ifPresentThrow(() -> new RuntimeException("not found"));

I could just store the Optional, and do the isPresent check after:

Optional<String> two = values.stream()
        .filter(s -> s.equals("two"))
        .findAny();
if (two.isPresent()) {
    throw new RuntimeException("not found");
}

Is there any way to achieve this ifPresentThrow sort of behavior? Is trying to do throw in this way a bad practice?

mkobit
  • 43,979
  • 12
  • 156
  • 150
  • 3
    The point of `orElseThrow` is to convert the value to a non-optional with error handling if the value does not exist. As all you are interested in is if the value exists, why not use the method designed for this purpose: `isPresent`? – Adrian Leonhard Feb 19 '15 at 00:54

3 Answers3

102

You could use the ifPresent() call to throw an exception if your filter finds anything:

    values.stream()
            .filter("two"::equals)
            .findAny()
            .ifPresent(s -> {
                throw new RuntimeException("found");
            });
catch23
  • 17,519
  • 42
  • 144
  • 217
beresfordt
  • 5,088
  • 10
  • 35
  • 43
48

Since you only care if a match was found, not what was actually found, you can use anyMatch for this, and you don't need to use Optional at all:

if (values.stream().anyMatch(s -> s.equals("two"))) {
    throw new RuntimeException("two was found");
}
Stuart Marks
  • 127,867
  • 37
  • 205
  • 259
  • 27
    or `.anyMatch("two"::equals)` – Misha Feb 19 '15 at 01:39
  • 9
    @Misha: this is one of the rare cases where the lambda expression is more efficient because it doesn’t capture any values (as `"two"` is a compile-time constant). In contrast, the method reference will always capture the instance on which the method is to be invoked. – Holger Feb 19 '15 at 08:27
  • 2
    I know @Holger is right, but I've got to admit that @Misha's `"two"::equals` is a very nice syntax. It's hard to say no to that to gain a few nonosecs of performance :-) – Edwin Dalorzo Feb 21 '15 at 13:26
  • 1
    @Edwin Dalorzo: I didn’t discourage from using the alternative syntax. I just wanted to emphasize that while sometimes people tend do favor method references for the slightly higher efficiency, this doesn’t apply here. So if you think the method reference is the nicer syntax and have no problems with the different semantics regarding `null` values, you may ignore the small efficiency differences. – Holger Feb 23 '15 at 09:07
  • 1
    @Holger Are the lambdas really more efficient than the method reference? The lambdas have to call through a synthetic method that contains the lambda body, which then calls `equals`. The method reference captures the receiver instance, but then it calls `equals` directly. Not obvious to me which is more efficient. (I haven't benchmarked this.) – Stuart Marks Feb 24 '15 at 02:20
  • 1
    @Stuart Marks: I don’t think that this one level of indirectness makes a significant difference. But even if it does, in this special case the difference between capturing and non-capturing outperforms it as it implies that for the capturing method reference, a new lambda instance will be created each time, while the non-capturing lambda expression will be a singleton. Of course, this all applies to the *current implementation* and HotSpot may optimize both, temporary instance creation and indirect calls to code that performs equally… – Holger Feb 24 '15 at 08:29
  • 2
    @Holger First, good point about the capturing. Even if one already knows that `str::equals` has capture cost, it's surprising to me (and likely others) that `"two":equals` has a capture cost even though `"two"` is a compile-time constant. But I think it's an overstatement to say that in this case the lambda is more efficient than the method reference; there are some tradeoffs. There's the indirection through the synthetic method, and there's also the static footprint of the method and the constant pool entries to support it. – Stuart Marks Feb 24 '15 at 22:13
  • 1
    @Holger Also, different environments have different considerations. For example, in embedded environments, the cost of a method call can be much higher (no JIT or different JIT, not Hotspot). The embedded folks are also quite concerned about static footprint. But I agree these differences are all really small, and are also mostly implementation-specific. I just wanted to point out the tradeoffs. – Stuart Marks Feb 24 '15 at 22:17
8
userOptional.ifPresent(user1 -> {throw new AlreadyExistsException("Email already exist");});

Here middle bracket is compulsory, else it is showing compile time exception

{throw new AlreadyExistsException("Email already exist");}

public class AlreadyExistsException extends RuntimeException

and exception class must extends runtime exception

asifaftab87
  • 1,315
  • 24
  • 28