0

I keep on getting 'java.util.NoSuchElementException: No value present' when executing filter findFirst. I can't change the code much as it will break other part of code and we dont want to write method logic inside filter. Code give is below.

--- I am getting below error when calling the method

Error :

java.util.NoSuchElementException: No value present
        at java.util.Optional.get(Optional.java:135)

The error is because the value is null for " .filter(x -> x > 5) .findFirst()"

public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
        int a = list.stream()
                   // .peek(num -> System.out.println("will filter " + num))
                .filter(x -> x== null)
                .map( t -> {
                    System.out.println("hello");
                    return 0;
                })
                    .filter(x -> x > 5)
                    .findFirst()
                    .get();
        System.out.println(a);

Here list.stream() will give stream which will be use by .filter(x -> x== null). Now in this scenario x is not null so when it come to .filter(x -> x > 5) it give null because stream is not there. Hence the exception.

I need help in some alternative for this.

Rahul
  • 95
  • 1
  • 3
  • 14
  • 1
    The `Optional` returned by `.findFirst()` can be empty. That means, no match has been found. That may happen when `source.getTrans()` returns an empty collection or `null` (as you map `null` to an empty set explicitly), or if the `filter` predicates did not accept anything. Mind that your stream only accepts elements for which `.getDType() == null` *and* `.getD() != null`. Generally, you should not call `get()` on an `Optional` without checking whether a value is present. When it is, your subsequent tests (besides mixing up the `trans` variable and the `EmployeeTransaction` type) are redundant – Holger Apr 04 '19 at 16:01
  • Yes, but in this case source.getTrans() has value – Rahul Apr 04 '19 at 16:23
  • Have you got a class **and** a variable both called `EmployeeTransaction`? – Klitos Kyriacou Apr 04 '19 at 16:59
  • you can use this example, – Rahul Apr 04 '19 at 16:59
  • You can use this example 2 from above please. I will edit the description. – Rahul Apr 04 '19 at 17:00
  • 1
    Are you asking for an alternative to the `get()` call because it's throwing an exception? Why not `orElse(...)`? – Klitos Kyriacou Apr 04 '19 at 17:04
  • No, when debug the code this value is null " .filter(x -> x > 5) .findFirst()" . Ideally it should not be. I need to figure out an alternate approach for this code so that error does not show up. – Rahul Apr 04 '19 at 17:16
  • You're filtering out every element with `.filter(x -> x== null)`, there's nothing left after that. Then you map every element to 0 and filter by `x > 5`, which would also filter out every element if there were any left. What are you expecting this code to do? – Sean Van Gorder Apr 04 '19 at 17:23
  • I am expecting this code to print 10. – Rahul Apr 04 '19 at 17:32
  • Why should it print ten? Your first `.filter(x -> x== null)` doesn’t let `10` pass. – Holger Apr 05 '19 at 07:30
  • Yes, so i am trying to fix it. The requirement is when list is not null it should print 10 from values and when it is null then map should be invoked. – Rahul Apr 05 '19 at 08:12

1 Answers1

0

This will print 10 as expected, or "Null" if the list is empty:

List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
Optional<Integer> a = list.stream()
        .filter(x -> x > 5)
        .findFirst();
System.out.println(a.isPresent() ? a.get() : "Null");

You don't want to use the map method here, that's used to apply an operation to each element and replace it with the result. For example, .map(x -> x + 3) would change [1, 10, 3, 7, 5] into [4, 13, 6, 10, 8]. You can't tell whether the stream is empty or not from an intermediate operation like map, you need to use a terminal operation like findFirst and look at the result.

Sean Van Gorder
  • 3,393
  • 26
  • 26