简体   繁体   中英

Using Java 8 stream methods to get a max value

I would like to get the max value out of a list using java 8 stream methods.

The structure is the following:

  • I read a csv file and store the data of every line in a separate object of type Round .
  • all these Round objects are stored in an ArrayList called arrRound
  • all Round objects have a field: List<Hit> hits
  • a Hit consists of 2 fields: int numberOfGames and int prizeAmount
public class Round{
    private List<Hits> hits; 
}
public class Hits{
    private int numberOfGames;
    private int prizeAmount;
}

What I would like to do is to iterate over all elements of arrRound , get their hits field's getPrizeAmount() method and get the max out of it. I started as the following but can't seem to do it:

public class Main(){
    public void main(String[]args){
        List<Round> arrRound = getRoundFromCSV();
        int maxPrize = arrRound.stream()
                               .forEach(round -> {
                                 round.getHits()
                                      .forEach(hit -> hit.getPrizeAmount());
                                });
    }
}

and I am not able to call max() on the end of the statement.

Thank you for your help in advance!

You can achieve it by this way :

  • iterate over the Round of the list
  • change from Round object to its List<Hit> hits ,
  • use flatMap to go from Stream<List<Hits>> to Stream<Hits>
  • change from Hits to its prizeAmount field
  • get the max if exists
  • if no max (like if list empty or else) return -1

So a solution using Method reference

int maxPrize = arrRoundarrRound.stream()                      // Stream<Round>
                               .map(Round::getHits)           // Stream<List<Hits>>
                               .flatMap(List::stream)         // Stream<Hits>
                               .mapToInt(Hit::getPrizeAmount) // IntStream
                               .max()                         // OptionalInt 
                               .orElse(-1);                   // int

With class lambda and map + flatMap in one :

int maxPrize = arrRoundarrRound.stream()    
                               .flatMap(round -> round.getHits().stream())
                               .mapToInt(hits -> hits.getPrizeAmount())
                               .max()                         
                               .orElse(-1); 

Use flatMap :

int maxPrize = arrRound.stream() // Stream<Round>
                       .flatMap(r -> r.getHits().stream()) // Stream<Hit>
                       .mapToInt(Hit::getPrizeAmount) // IntStream
                       .max()
                       .orElse(0);

using reduce

int max1 = arrRound.stream()
        .flatMap(r -> r.getHits().stream())
        .mapToInt(h -> h.getPrizeAmount())
        .reduce(Math::max) //returns OptionalInt
        .orElse(Integer.MIN_VALUE);

or

int max2 = arrRound.stream()
        .flatMap(r -> r.getHits().stream())
        .mapToInt(h -> h.getPrizeAmount())
        .reduce(Integer.MIN_VALUE, Math::max);

Because forEach is a terminal operation. And after you call the forEach on a stream the stream terminates and can't be used again.

using Comparator :

int max2 = arrRound.stream()
            .flatMap(round -> round.getHits().stream())
            .max(Comparator.comparing(Hits::getPrizeAmount))
            .map(Hits::getPrizeAmount)
            .orElse(-1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM