I have an ArrayList of HashMap and the hashmap looks like:
{"Start":"A", "End":"B","Length":5}
I want to find the one that has the longest length, or maybe more than one they all have the same length equal to the max length.
Trying to use stream, how should I do it?
ArrayList<HashMap<String, Object>> resultslist = new ArrayList<HashMap<String, Object>>();
ArrayList<HashMap<String, Object>> finalresult = resultslist.stream().max()
CodePudding user response:
Use the Power of Objects
hashmap looks like
{"Start":"A", "End":"B","Length":5}
You are misusing Maps, it definitely should be a custom object, with attributes having proper types instead of storing them as java.lang.Object
in the map.
For example, that how it might loop like, if we implemented as a Java 14 record:
public record Foo(String start, String end,int length) {}
Now things would be simple, instead of a nested collection you would have a list of Foo
.
To find a Foo
with maximum length
you can use either Stream.max()
or Collections.max()
, both expect an instance of Comparator
as an argument.
List<Foo> foos = // intializing the list
// with Stream API
Foo max = foos.stream()
.max(Comparator.comparingInt(Foo::length)) // produces Optional<Foo>
.orElseThrow();
// using Collections.max()
Foo max = Collections.max(foos, Comparator.comparingInt(Foo::length));
Sidenote: you might also want to learn What does it mean to "program to an interface"?
CodePudding user response:
In one shot, you can use Collectors.groupingBy
like so:
List<HashMap<String, Object>> response = resultslist.stream()
.collect(Collectors.groupingBy(HashMap::size))
.entrySet().stream()
.max(Map.Entry.comparingByKey())
.map(Map.Entry::getValue)
.orElseGet(Collections::emptyList);
The idea is, to group by size (This step returns a Map of Integer and List of Map), then get the max of this map.