Java8流API中的分组方式
我不熟悉java流API,有一个使用它来解决问题的用例Java8流API中的分组方式,java,java-8,java-stream,Java,Java 8,Java Stream,我不熟悉java流API,有一个使用它来解决问题的用例 Map<Object, ? extends Object> map = list.stream().collect(Collectors.groupingBy(p->p.getX() ,Collectors.groupingBy(p->p.getY()
Map<Object, ? extends Object> map = list.stream().collect(Collectors.groupingBy(p->p.getX()
,Collectors.groupingBy(p->p.getY()
,Collectors.groupingBy(p->p.getZ()))));
Map Map=list.stream().collect(收集器.groupingBy(p->p.getX())
,Collectors.groupingBy(p->p.getY()
,Collectors.groupingBy(p->p.getZ());
假设x、y和z是给定类的属性。如果我们有预定义的分组顺序(第一个,第二个等等,等等),这很好。p>
(在给定的代码段中,属性x被认为是第一,y是第二,z是第三)
现在,在我的例子中,分组顺序不是预定义的,在运行时可能会改变。所以,在编译时,我不知道在collect方法中传递什么。
我正在寻找一种解决方案,通过它我可以在运行时读取配置字符串并更改分组。假设
p
属于p
类,您可以这样定义顺序:
Function<P, Object> g1 = P::getX;
Function<P, Object> g2 = P::getX;
Function<P, Object> g3 = P::getX;
g1、g2、g3也可以使用反射来定义,以便在运行时根据字段/方法的名称访问方法/字段。您可以创建一个帮助器方法,该方法使用给定的分类函数构建自己的
收集器
:
@SuppressWarnings("unchecked")
@SafeVarargs
public static <T> Collector<T, ?, Map<?, ?>> multiGrouping(
Function<? super T, ?>... classifiers) {
Collector<T, ?, Map<?, ?>> result = null;
for(int i=classifiers.length-1; i>=0; i--) {
Collector<?, ?, ?> next;
if(result == null) {
next = Collectors.groupingBy(classifiers[i]);
} else {
next = Collectors.groupingBy(classifiers[i], result);
}
result = (Collector<T, ?, Map<?, ?>>)next;
}
return result;
}
@SuppressWarnings(“未选中”)
@安全变量
公共静态收集器>结果=null;
对于(int i=classifiers.length-1;i>=0;i--){
接下来是收集器;
如果(结果==null){
next=Collectors.groupingBy(分类器[i]);
}否则{
next=Collectors.groupingBy(分类器[i],结果);
}
结果=(Collector“读取配置字符串并在运行时更改分组”是什么意思??好的,假设它是用户定义的-因此,如果用户定义groupingOrder=x,y,z,它应该如上所述进行分组,如果另一个用户将它定义为y,x,z,它应该相应地更改(*groupingOrder只是我作为参考的名称)感谢您的快速回复,在这种情况下,我需要定义所有属性的顺序吗?我考虑在运行时基于配置字符串将“Collectors.groupingBy(…”构造为字符串,(例如“list.stream().collect(Collectors.groupingBy(g1,Collectors.groupingBy(g2,Collectors.groupingBy(g3)));”然后使用groovy执行它,但当前的groovy版本似乎不支持lambda。。
@SuppressWarnings("unchecked")
@SafeVarargs
public static <T> Collector<T, ?, Map<?, ?>> multiGrouping(
Function<? super T, ?>... classifiers) {
Collector<T, ?, Map<?, ?>> result = null;
for(int i=classifiers.length-1; i>=0; i--) {
Collector<?, ?, ?> next;
if(result == null) {
next = Collectors.groupingBy(classifiers[i]);
} else {
next = Collectors.groupingBy(classifiers[i], result);
}
result = (Collector<T, ?, Map<?, ?>>)next;
}
return result;
}
Map<?, ?> map = Stream.of("abc", "def", "cd", "cfff")
.collect(multiGrouping(String::length, s -> s.charAt(0)));