Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java streams .orElseThrow

I want convert a piece of code from a Connection Pool project i have been working on to use streams

the original code is

for (Map.Entry<JdbConnection,Instant> entry : borrowed.entrySet()) {
  Instant leaseTime = entry.getValue();
  JdbConnection jdbConnection = entry.getKey();
  Duration timeElapsed = Duration.between(leaseTime, Instant.now());
  if (timeElapsed.toMillis() > leaseTimeInMillis) {
    //expired, let's close it and remove it from the map
    jdbConnection.close();
    borrowed.remove(jdbConnection);

    //create a new one, mark it as borrowed and give it to the client
    JdbConnection newJdbConnection = factory.create();
    borrowed.put(newJdbConnection,Instant.now());
    return newJdbConnection;
  }
}

throw new ConnectionPoolException("No connections available");

I have got to the point of this

borrowed.entrySet().stream()
                   .filter(entry -> Duration.between(entry.getValue(), Instant.now()).toMillis() > leaseTimeInMillis)
                   .findFirst()
                   .ifPresent(entry -> {
                     entry.getKey().close();
                     borrowed.remove(entry.getKey());
                   });


JdbConnection newJdbConnection = factory.create();
borrowed.put(newJdbConnection,Instant.now());
return newJdbConnection;

The above can compile but the moment i add orElseThrow after IfPresent i am getting the following

/home/prakashs/connection_pool/src/main/java/com/spakai/ConnectionPool.java:83: error: void cannot be dereferenced
                       .orElseThrow(ConnectionPoolException::new);
like image 970
spakai Avatar asked Dec 18 '15 05:12

spakai


People also ask

What is orElseThrow Java?

The orElseThrow method will return the value present in the Optional object. If the value is not present, then the supplier function passed as an argument is executed and an exception created on the function is thrown.

How do I use orElseThrow in Java 8?

orElseThrow. Simply put, if the value is present, then isPresent() would return true, and calling get() will return this value. Otherwise, it throws NoSuchElementException.

How do you throw an exception if optional is empty?

The orElseThrow() method of java. util. Optional class in Java is used to get the value of this Optional instance if present. If there is no value present in this Optional instance, then this method throws the exception generated from the specified supplier.

What does orElseThrow return?

orElseThrow. Return the contained value, if present, otherwise throw an exception to be created by the provided supplier.


2 Answers

That's because ifPresent returns void. It can't be chained. You could do something like:

Entry<JdbConnection, Instant> entry =
    borrowed.entrySet().stream()
        .filter(entry -> Duration.between(entry.getValue(), Instant.now())
                            .toMillis() > leaseTimeInMillis)
        .findFirst()
        .orElseThrow(ConnectionPoolException::new));
entry.getKey().close();
borrowed.remove(entry.getKey());

What you were looking for would read well:

.findFirst().ifPresent(value -> use(value)).orElseThrow(Exception::new);

But for it to work, ifPresent would have to return the Optional, which would be a little odd. It would mean you could chain one ifPresent after another, doing multiple operations on the value. That might have been a good design, but it isn't the one the creators of Optional went with.

like image 159
David Conrad Avatar answered Oct 16 '22 11:10

David Conrad


Use map instead of isPresent, and return with an Optional instead of an exception.

borrowed.entrySet().stream()
               .filter(entry -> Duration.between(entry.getValue(), Instant.now()).toMillis() > leaseTimeInMillis)
               .findFirst()
               .map(entry -> {
                 entry.getKey().close();
                 borrowed.remove(entry.getKey());
                 JdbConnection newJdbConnection = factory.create();
                 borrowed.put(newJdbConnection,Instant.now());
                 return newJdbConnection;
               })
like image 41
ZoltanTheHun Avatar answered Oct 16 '22 10:10

ZoltanTheHun