Reputation: 1457
Imagine that I have this list of integers
List<Integer> myList= Arrays.asList(1,2,3,4,4);
Now I want to sum this elements excluding the first max value:
int sumExcludeMax = myList.stream()
.filter(x -> x != Collections.max(list))
.mapToInt(Integer::intValue)
.sum();
In this way it's excluding all 4 in the list. How can I exclude just the first one using for instance .findFirst()
?
Upvotes: 1
Views: 1497
Reputation: 11959
You should not invoke max
each time: Collections.max(myList)
is evaluated for each item in myList
while the list is not mutating (I assumed that you computed the max of the same list and that Collection.max(list)
was a typo):
And for your question, if you want to sum all but the first max, then I think this works:
int sumExcludeMax = myList.stream().mapToInt(Integer::intValue).sum()
- Collections.max(myList);
Since you are computing a IntStream
, you can also summarize (I'm using Java 11 here, but it works with 8 apart from the var
stuff):
var ss = myList.stream().mapToInt(Integer::intValue).summaryStatistics();
long result = ss.sum() - ss.max();
Upvotes: 4
Reputation: 45319
You can sort
in reverse order, then skip one element:
int result = myList.stream()
.sorted(Comparator.reverseOrder())
.skip(1)
.mapToInt(Integer::valueOf)
.sum();
If you're on Java 12+, you can use Collectors.teeing
in a different approach, computing the max in the first downstream, the sum in the second, and then the difference to work out the result:
int result = myList.stream()
.collect(Collectors.teeing(
Collectors.maxBy(Integer::compare),
Collectors.summingInt(Integer::intValue),
(v1, v2) -> v2 - v1.orElse(0)));
Both of these options yield 10
.
Upvotes: 3
Reputation: 1650
If you use .distinct()
in the stream object then you only get the max once, but also every other number only once, if you need the other numbers as duplicates it gets a bit more complicated.
List<Integer> myList= Arrays.asList(1,2,3,4,4);
int sumExcludeMax = myList.stream().distinct()
.mapToInt(Integer::intValue)
.sum();
This works if you need the other dublicates:
List<Integer> myList= Arrays.asList(1,2,3,4,4);
int sumExcludeMax = myList.stream()
.filter(x -> x != Collections.max(myList))
.mapToInt(Integer::intValue)
.sum() + Collections.max(myList);
Upvotes: 1