I m using Java 8 for grouping by data. But results obtained are not in order formed.
Map<GroupingKey, List<Object>> groupedResult = null; if (!CollectionUtils.isEmpty(groupByColumns)) { Map<String, Object> mapArr[] = new LinkedHashMap[mapList.size()]; if (!CollectionUtils.isEmpty(mapList)) { int count = 0; for (LinkedHashMap<String, Object> map : mapList) { mapArr[count++] = map; } } Stream<Map<String, Object>> people = Stream.of(mapArr); groupedResult = people .collect(Collectors.groupingBy(p -> new GroupingKey(p, groupByColumns), Collectors.mapping((Map<String, Object> p) -> p, toList()))); public static class GroupingKey public GroupingKey(Map<String, Object> map, List<String> cols) { keys = new ArrayList<>(); for (String col : cols) { keys.add(map.get(col)); } } // Add appropriate isEqual() ... you IDE should generate this @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final GroupingKey other = (GroupingKey) obj; if (!Objects.equals(this.keys, other.keys)) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 37 * hash + Objects.hashCode(this.keys); return hash; } @Override public String toString() { return keys + ""; } public ArrayList<Object> getKeys() { return keys; } public void setKeys(ArrayList<Object> keys) { this.keys = keys; } }
Here i am using my class groupingKey by which i m dynamically passing from ux. How can get this groupByColumns in sorted form?
java - Stream doesn't preserve the order after grouping - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.
If you have an ordered stream and perform operations which guarantee to maintain the order, it doesn't matter whether the stream is processed in parallel or sequential; the implementation will maintain the order. The ordered property is distinct from parallel vs sequential.
A parallel stream is performed one or more elements at a time. Thus the map() would preserve the encounter of the stream order but not the original List's order.
Not maintaining the order is a property of the Map
that stores the result. If you need a specific Map
behavior, you need to request a particular Map
implementation. E.g. LinkedHashMap
maintains the insertion order:
groupedResult = people.collect(Collectors.groupingBy( p -> new GroupingKey(p, groupByColumns), LinkedHashMap::new, Collectors.mapping((Map<String, Object> p) -> p, toList())));
By the way, there is no reason to copy the contents of mapList
into an array before creating the Stream
. You may simply call mapList.stream()
to get an appropriate Stream
.
Further, Collectors.mapping((Map<String, Object> p) -> p, toList())
is obsolete. p->p
is an identity mapping, so there’s no reason to request mapping
at all:
groupedResult = mapList.stream().collect(Collectors.groupingBy( p -> new GroupingKey(p, groupByColumns), LinkedHashMap::new, toList()));
But even the GroupingKey
is obsolete. It basically wraps a List
of values, so you could just use a List
as key in the first place. List
s implement hashCode
and equals
appropriately (but you must not modify these key List
s afterwards).
Map<List<Object>, List<Object>> groupedResult= mapList.stream().collect(Collectors.groupingBy( p -> groupByColumns.stream().map(p::get).collect(toList()), LinkedHashMap::new, toList()));
Based on @Holger's great answer. I post this to help those who want to keep the order after grouping as well as changing the mapping.
Let's simplify and suppose we have a list of persons (int age, String name, String adresss...etc) and we want the names grouped by age while keeping ages in order:
final LinkedHashMap<Integer, List<String> map = myList .stream() .sorted(Comparator.comparing(p -> p.getAge())) //sort list by ages .collect(Collectors.groupingBy(p -> p.getAge()), LinkedHashMap::new, //keeps the order Collectors.mapping(p -> p.getName(), //map name Collectors.toList())));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With