13

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
  • 374,785
  • 51
  • 663
  • 734
Clomez
  • 1,163
  • 2
  • 16
  • 35
  • 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

20

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
  • 374,785
  • 51
  • 663
  • 734
  • 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
4

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*/);