Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8流API中的分组方式_Java_Java 8_Java Stream - Fatal编程技术网

Java8流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()

我不熟悉java流API,有一个使用它来解决问题的用例

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)));