More elegant multi-condition groupby. #9719
Remi Forax
forax at univ-mlv.fr
Mon Aug 8 22:24:16 UTC 2022
> From: "(11I10I24) 活 动 中 心" <1015770492 at qq.com>
> To: "core-libs-dev" <core-libs-dev at openjdk.org>
> Sent: Saturday, August 6, 2022 11:49:18 AM
> Subject: More elegant multi-condition groupby. #9719
> Hi, team
> I have two suggestions
> Firstly:
> If we can provide a new API for grouping ( java.util.stream.Collectors )
> such as:
> userList.stream().collect(Collectors.groupingBy(User::getName, User::getCity))
> userList.stream().collect(Collectors.groupingBy("-", User::getName,
> User::getCity, User::getId));// key is "name-city", value is List after being
> grouped
> It helps us to do grouping with less code. and It looks cooler for lambda.
> And I've provided a simple demo.
> demo:
> https://github.com/1015770492/CollectorsDemo/blob/master/src/main/java/com/example/demo/MultiGroupByDemo.java
> issue: https://github.com/openjdk/jdk/pull/9719
> Secondly:
> similarly, if we can provide new api for sort with stream.
> It can be:
> userList.stream().sorted(User::getAge)
> or userList.stream().sorted(User::getName)
> or userList.stream().sorted(User::getName, User::getAge)
> userList.stream().sorted(User::getAge) age is a Integer or int type ,it is
> Comparable, So if we can use the Function reference implements sort.
> String implements the Comparable Interface but we do not use the features.
> userList.stream().sorted(User::getCity, User::getName)
> multi-condition sort we can transfor to String sort.
Hi !
we usually add additional APIs because it's cooler :)
If i understand you correctly, you are saying that from a user POV dealing with composite keys for grouping or sorting could be improved.
I really do not like you first proposal because you are introducing a String where you could introduce a real object (the composite key), here string acting as a cheaper inferior object.
Using a record seems to be a better idea (technically what we want here is tuples but records is good enough)
record CompositeKey(String name, int age) { }
so you can write
list.stream().collect(groupingBy(user -> new CompositeKey(user.getName, user.getAge())))
and with a static method in CompositeKey
record CompositeKey(String name, int age) {
static CompositeKey fromUser(User user) { return new CompositeKey(user.getName, user.getAge()); }
}
it can be simplified to
list.stream().collect(groupingBy(CompositeKey::fromUser))
For sorting, it's a different, the API you propose has already have been proposed and rejected during the development of Java 8
Comparing using Integer instead of int is really slow, so we do not want users to be forced to box things.
The API you propose requires the return type of User::getCity and the return type User::getAge to be inferred as the same type variable, sadly it means boxing, so it's not a good API.
> best regards
> Yu, Jinhua
> 1015770492 at qq.com
regards,
Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20220809/0d9f0d75/attachment-0001.htm>
More information about the core-libs-dev
mailing list