15

I understand how to collect to a List, but can't figure how I would return just one parameter of filtered object as a String.

fee = new BigDecimal(fees
            .stream()
            .filter(p -> p.getTodate().isAfter(LocalDateTime.now()))
            .filter(p -> p.getFromdate().isBefore(LocalDateTime.now()))
            .filter(p -> p.getId().equals(id))

    return fee;

I first check that the fee is up to date, as there might be upcoming fees and fees that are no longer valid. Then I match the id with remaining fees. But then there is code missing between last filter and return.

I just want to return String from Stream object (p.getFee) for BigDecimal constructor.

I know there is only one Stream object remaining after filters.

Eran
  • 387,369
  • 54
  • 702
  • 768
Clomez
  • 1,410
  • 3
  • 21
  • 41
  • If you expect a single element or 0 element in the collected stream you should explicit handle the case as you have more than 1 element from the collect. – davidxxx Nov 09 '18 at 08:41

2 Answers2

23

Use findFirst to return the first element of the Stream that passes your filters. It returns an Optional, so you can use orElse() to set a default value in case the Stream is empty.

fee = new BigDecimal(fees
            .stream()
            .filter(p -> p.getTodate().isAfter(LocalDateTime.now()))
            .filter(p -> p.getFromdate().isBefore(LocalDateTime.now()))
            .filter(p -> p.getId().equals(id))
            .map(p -> p.getFee())
            .findFirst()
            .orElse(/*some default value*/));
Eran
  • 387,369
  • 54
  • 702
  • 768
  • 1
    Or perhaps throw an exception, if it is an exceptional state. – Magnilex Nov 09 '18 at 09:01
  • do you happen to know why .filter(p -> p.getInstrumentid().equals(id)) part cant find match even tho i looked it up and data definitely contains fee object with given id? if i take the last filter out, everything else works.. – Clomez Nov 09 '18 at 10:15
  • @Clomez what's the type of id and the return type of getInstrumentId? – Eran Nov 09 '18 at 11:57
5

Maybe it would be a better approach:

fee = fees.stream()
        .filter(p -> p.getTodate().isAfter(LocalDateTime.now()))
        .filter(p -> p.getFromdate().isBefore(LocalDateTime.now()))
        .filter(p -> p.getId().equals(id))
        .map(p -> p.getFee())
        .findFirst()
        .map(BigDecimal::new)
        .orElse(/*some default value*/);