问题
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 anArrayList
calledarrRound
- all
Round
objects have a field:List<Hit> hits
- a
Hit
consists of 2 fields:int numberOfGames
andint 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!
回答1:
You can achieve it by this way :
- iterate over the
Round
of thelist
- change from
Round
object to itsList<Hit> hits
, - use
flatMap
to go fromStream<List<Hits>>
toStream<Hits>
- change from
Hits
to itsprizeAmount
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);
回答2:
Use flatMap
:
int maxPrize = arrRound.stream() // Stream<Round>
.flatMap(r -> r.getHits().stream()) // Stream<Hit>
.mapToInt(Hit::getPrizeAmount) // IntStream
.max()
.orElse(0);
回答3:
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);
回答4:
Because forEach
is a terminal operation.
And after you call the forEach
on a stream the stream terminates and can't be used again.
回答5:
using Comparator
:
int max2 = arrRound.stream()
.flatMap(round -> round.getHits().stream())
.max(Comparator.comparing(Hits::getPrizeAmount))
.map(Hits::getPrizeAmount)
.orElse(-1);
来源:https://stackoverflow.com/questions/48608983/using-java-8-stream-methods-to-get-a-max-value