- Get the maximum value using stream for Map
- 2 Answers 2
- Concise way to get both min and max value of Java 8 stream
- 7 Answers 7
- Using Java8 Stream to find the highest values from map
- 2 Answers 2
- Java Stream min() and max()
- 1. Stream.min()
- 2. Stream.max()
- 3. Min and Max for String and Integer
- 4. Min and Max for Object
- 5. Min and Max for Date
- 6. Using IntStream, LongStream and DoubleStream
Get the maximum value using stream for Map
However my question is How can I return the key of the maximum amount? Can I do it with one round using stream?
2 Answers 2
If I understood you correctly:
Entry entry = map.entrySet() .stream() .max(Map.Entry.comparingByValue(Comparator.comparingInt(Test::getNumber))) .get();
There is no reason to turn to an expensive .sorted(…) .findFirst() . You can still use max as in the OP’s code, the only trick is not to do the map step: map.entrySet() .stream() .max(Map.Entry.comparingByValue(Comparator.comparingInt(Test::getNumber))) .get()
Mind the removal of Comparator.reverseOrder() ; it was needed when you tried to use findFirst() to get the maximum, but isn’t needed when you use max in the first place. In my comment, I also used the opportunity to change it to comparingInt for the natural order.
If you want to find the key-value pair corresponding to the maximum ‘number’ value in the Test instances, you can use Collections.max() combined with a comparator that compares the entries with this criteria.
import static java.util.Comparator.comparingInt; . Map.Entry maxEntry = Collections.max(map.entrySet(), comparingInt(e -> e.getValue().getNumber()))
If you want to use the stream way, then remove the mapping (because you lost the key associated with the value), and provide the same comparator:
map.entrySet() .stream() .max(comparingInt(e -> e.getValue().getNumber())) .ifPresent(System.out::println);
Note that there is a small difference in both snippets, as the first one will throw a NoSuchElementException if the provided map is empty.
Concise way to get both min and max value of Java 8 stream
Is there a concise way to extract both the min and max value of a stream (based on some comparator) in one pass? There appear to be many ways to get the min and max values individually, or I can sort the stream into a temporary object, for example:
List sorted = Stream.of(. ).sorted().collect(Collectors.toList()); T min = sorted.get(0); T max = sorted.get(sorted.size() - 1);
But this isn’t concise and requires allocating a temporary object. I’d rather not allocate a temporary object or make two passes through the stream. Is there an alternative?
Have you considered a collector like IntSummaryStatistics? You may follow the pattern supposing this is not about numbers.
7 Answers 7
The summarizingInt collector works well if you have a Stream of Integers.
IntSummaryStatistics stats = Stream.of(2,4,3,2) .collect(Collectors.summarizingInt(Integer::intValue)); int min = stats.getMin(); int max = stats.getMax();
If you have doubles you can use the summarizingDouble collector.
DoubleSummaryStatistics stats2 = Stream.of(2.4, 4.3, 3.3, 2.5) .collect(Collectors.summarizingDouble((Double::doubleValue)));
If this is a frequently needed feature, we better make a Collector to do the job. We’ll need a Stats class to hold count, min, max , and factory methods to creat stats collector.
Stats stats = stringStream.collect(Stats.collector()) fooStream.collect(Stats.collector(fooComparator))
(Maybe a better convenience method would be Stats.collect(stream) )
I made an example Stats class —
public class Stats < int count; final Comparator super T>comparator; T min; T max; public Stats(Comparator super T>comparator) < this.comparator = comparator; >public int count() < return count; >public T min() < return min; >public T max() < return max; >public void accept(T val) < if(count==0) min = max = val; else if(comparator.compare(val, min)<0) min = val; else if(comparator.compare(val, max)>0) max = val; count++; > public Stats combine(Stats that) < if(this.count==0) return that; if(that.count==0) return this; this.count += that.count; if(comparator.compare(that.min, this.min)<0) this.min = that.min; if(comparator.compare(that.max, this.max)>0) this.max = that.max; return this; > public static Collector collector(Comparator super T>comparator) < return Collector.of( ()->new Stats<>(comparator), Stats::accept, Stats::combine, Collector.Characteristics.UNORDERED, Collector.Characteristics.IDENTITY_FINISH ); > public static > Collector collector() < return collector(Comparator.naturalOrder()); >>
Using Java8 Stream to find the highest values from map
I wrote following method to find the keys mapped to the highest values and trying to convert to java Stream s. Can you please help?
private List testStreamMap(Map mapGroup) < ListlistMax = new ArrayList(); Long frequency = 0L; for (Integer key : mapGroup.keySet()) < Long occurrence = mapGroup.get(key); if (occurrence >frequency) < listMax.clear(); listMax.add(key); frequency = occurrence; >else if (occurrence == frequency) < listMax.add(key); >> return listMax; >
Your question is not clear, the same parameter that you called occurance ( which is misspelled btw) is called in the second implementation tempValue . And the parameter that you named frequencey (which is also misspelled) in the first implementation is called occurrence in the second. Start by being consistent with your names and that might help you solve your confusion.
«Key with highest occurrence»?, I guess you are trying to find out the «value» with highest occurrence as you are calling mapGroup.get(key) . Correct?
2 Answers 2
You can get a single key via
Integer max=mapGroup.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey();
but unfortunately, there is no built-in function for getting all equivalent maximums.
The simplest, straight-forward solution is to find the maximum value first and retrieve all keys mapping to that value afterwards:
private List testStreamMap(Map mapGroup) < if(mapGroup.isEmpty()) return Collections.emptyList(); long max = mapGroup.values().stream().max(Comparator.naturalOrder()).get(); return mapGroup.entrySet().stream() .filter(e ->e.getValue() == max) .map(Map.Entry::getKey) .collect(Collectors.toList()); >
Solutions for getting all maximum values of a stream in a single pass, are discussed in “How to force max() to return ALL maximum values in a Java Stream?”. You will see that single-pass solutions are much more complicated and not worth the effort if your input is an ordinary Map (e.g. HashMap ), which can be iterated multiple times cheaply.
Java Stream min() and max()
This page will walk through Java Stream.min and Stream.max examples. The java.util.stream.Stream has been introduced in Java 8. Using Stream.min method we get the minimum element of this stream for the given comparator. Using Stream.max method we get the maximum element of this stream for the given comparator. The min and max method both are stream terminal operations.
Let us discuss min and max methods with examples.
Contents
1. Stream.min()
It returns the minimum element of this stream according to the provided Comparator . It is the special case of reduction, for example using Stream.reduce method.
Find the min method declaration from Java doc.
Optional min(Comparator comparator)
Parameters: Pass a comparator to compare elements.
Returns: The method returns Optional containing minimum element or empty.
Throws: The method throws NullPointerException if minimum element is null.
2. Stream.max()
It returns the maximum element of this stream according to the provided Comparator . It is the special case of reduction, for example using Stream.reduce method.
Find the max method declaration from Java doc.
Optional max(Comparator comparator)
Parameters: Pass a comparator to compare elements.
Returns: The method returns Optional containing maximum element or empty.
Throws: The method throws NullPointerException if maximum element is null.
3. Min and Max for String and Integer
package com.concretepage; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Optional; public class MinMaxDemo1 < public static void main(String[] args) < System.out.println("---Min and Max for Integer---"); ListnumList = Arrays.asList(42, 44, 43, 41); Comparator comparator = Comparator.comparing(Integer::intValue); Optional minOptional = numList.stream().min(comparator); minOptional.ifPresent(e -> System.out.println("Min: " + e)); Optional maxOptional = numList.stream().max(comparator); maxOptional.ifPresent(e -> System.out.println("Max: " + e)); System.out.println("---Min and Max for String---"); List list = Arrays.asList("Mohit", "Nilesh", "Shankar", "Brajesh"); list.stream().min(Comparator.comparing(String::valueOf)) .ifPresent(e -> System.out.println("Min: " + e)); list.stream().max(Comparator.comparing(String::valueOf)) .ifPresent(e -> System.out.println("Max: " + e)); > >
---Min and Max for Integer--- Min: 41 Max: 44 ---Min and Max for String--- Min: Brajesh Max: Shankar
We know that min and max is the special case of stream reduction. Let us achieve the same using Stream.reduce method.
MinMaxDemoWithReduce.java
package com.concretepage; import java.util.Arrays; import java.util.List; public class MinMaxDemoWithReduce < public static void main(String[] args) < System.out.println("---Min and Max for Integer---"); ListnumList = Arrays.asList(42, 44, 43, 41); //For min numList.stream().reduce(Integer::min).ifPresent(s -> System.out.println(s)); //41 //For max numList.stream().reduce(Integer::max).ifPresent(s -> System.out.println(s)); //44 System.out.println("---Min and Max for String---"); List list = Arrays.asList("Mohit", "Nilesh", "Shankar", "Brajesh"); //For min list.stream().reduce((s1, s2) -> < if (s1.compareTo(s2) return s2; >).ifPresent(s -> System.out.println(s)); //Brajesh //For max list.stream().reduce((s1, s2) -> < if (s1.compareTo(s2) >= 0) < return s1; >return s2; >).ifPresent(s -> System.out.println(s)); //Shankar > >
4. Min and Max for Object
package com.concretepage; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class MinMaxDemo2 < public static void main(String[] args) < Listusers = Arrays.asList( new User("Mahesh", 30), new User("Krishna", 29), new User("Virat", 28) ); System.out.println("---Min and Max on the basis of user name---"); users.stream() .min(Comparator.comparing(u -> u.getUserName())) .ifPresent(e -> System.out.println("Min: " + e.getUserName())); users.stream() .max(Comparator.comparing(u -> u.getUserName())) .ifPresent(e -> System.out.println("Max: " + e.getUserName())); System.out.println("---Min and Max on the basis of age---"); users.stream() .min(Comparator.comparing(User::getAge)) .ifPresent(e -> System.out.println("Min: " + e.getUserName())); users.stream() .max(Comparator.comparing(User::getAge)) .ifPresent(e -> System.out.println("Max: " + e.getUserName())); > > class User < private String userName; private int age; public User(String userName, int age) < this.userName = userName; this.age = age; >//Sets and Gets >
---Min and Max on the basis of user name--- Min: Krishna Max: Virat ---Min and Max on the basis of age--- Min: Virat Max: Mahesh
5. Min and Max for Date
package com.concretepage; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class MinMaxDemo3 < public static void main(String[] args) < LocalDate ld = LocalDate.parse("2020-05-15"); ListldList = Arrays.asList( ld.minus(10, ChronoUnit.DAYS), //2020-05-05 ld, //2020-05-15 ld.plus(15, ChronoUnit.DAYS) //2020-05-30 ); ldList.stream() .min(Comparator.comparing(LocalDate::toEpochDay)) .ifPresent(e -> System.out.println("Min: " + e)); ldList.stream() .max(Comparator.comparing(LocalDate::toEpochDay)) .ifPresent(e -> System.out.println("Max: " + e)); > >
Min: 2020-05-05 Max: 2020-05-30
6. Using IntStream, LongStream and DoubleStream
Find the Java doc for min and max methods of IntStream , LongStream and DoubleStream .
For IntStream .
OptionalInt min() OptionalInt max()
OptionalLong min() OptionalLong max()
OptionalDouble min() OptionalDouble max()
We can see that we need not to pass comparator in the above methods. Now find the examples.
MinMaxDemo4.java
package com.concretepage; import java.util.stream.DoubleStream; import java.util.stream.IntStream; import java.util.stream.LongStream; public class MinMaxDemo4 < public static void main(String[] args) < System.out.println("--- Min and Max for IntStream ---"); IntStream.of(12, 20, 35, 48).min() .ifPresent(i ->System.out.println(i)); IntStream.of(12, 20, 35, 48).max() .ifPresent(i -> System.out.println(i)); System.out.println("--- Min and Max for LongStream ---"); LongStream.of(200, 300, 400).min() .ifPresent(l -> System.out.println(l)); LongStream.of(200, 300, 400).max() .ifPresent(l -> System.out.println(l)); System.out.println("--- Min and Max for DoubleStream ---"); DoubleStream.of(110.54, 230.57, 360.65).min() .ifPresent(l -> System.out.println(l)); DoubleStream.of(110.54, 230.57, 360.65).max() .ifPresent(l -> System.out.println(l)); > >
--- Min and Max for IntStream --- 12 48 --- Min and Max for LongStream --- 200 400 --- Min and Max for DoubleStream --- 110.54 360.65