Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.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
Java流:如何按关键字分组?_Java_Java Stream - Fatal编程技术网

Java流:如何按关键字分组?

Java流:如何按关键字分组?,java,java-stream,Java,Java Stream,我有一个文本文件,看起来像 Group: A 12 27 14 Group: B 68 10 42 79 Group: D ... 我想计算每组数字列表的统计数据 问题:有没有一种好的方法可以用Java流实现这一点 注意:我知道,给定一个IntStream,可以通过应用方法summaryStatistics获得统计信息。我的问题是,我不知道如何将关键字“group:”下面的元素分组 补充:关于有些奇怪的评论:没有流,问题可以通过 String group = null;

我有一个文本文件,看起来像

Group: A 
12
27 
14 
Group: B 
68
10 
42
79
Group: D
...
我想计算每组数字列表的统计数据

问题:有没有一种好的方法可以用Java流实现这一点

注意:我知道,给定一个
IntStream
,可以通过应用方法
summaryStatistics
获得统计信息。我的问题是,我不知道如何将关键字“group:”下面的元素分组

补充:关于有些奇怪的评论:没有流,问题可以通过

   String group = null;  
   boolean first = true; 
   List<String> lines = Files.readAllLines(path); 
   for (String s: lines) { 
     if (s.startsWith("Group:") { 
       if (!first) { 
         System.out.println(group + " sum: " + sum); 
       }  
       first = false; 
       group = s; 
       sum = 0; 
     } else { 
       sum += Integer.parseInt(s.strip()); 
     }
   }
   System.out.println(group + " sum: " + sum); 
字符串组=null;
布尔值优先=真;
列表行=文件。readAllLines(路径);
对于(字符串s:行){
如果(s.startsWith(“组:”){
如果(!first){
System.out.println(组+“总和:”+sum);
}  
第一个=假;
组=s;
总和=0;
}否则{
sum+=Integer.parseInt(s.strip());
}
}
System.out.println(组+“总和:”+sum);

试试这个。我把数据放在一个数组中进行演示


        String[] vals = {
                "Group: A ",
                "12       ",
                "27       ",
                "14       ",
                "Group: B ",
                "68       ",
                "10       ",
                "42       ",
                "79       ",
                "Group: D ",
                "10       ",
                "20       ",
                "30       ", 
                "18       ",
                "12       "
                };
在映射中对数据进行分组很简单,只需捕获
标记,然后将值添加到该标记的
列表
值中。在处理之前,数据会被删除空白,并将适当的字符串转换为整数。 由于数据的异步性,我想不出一种更简洁的方法,其他人可能会有更好的想法

        Map<String, List<Integer>> map = new HashMap<>();


        List<Integer> numbs = null;
        for (String v : vals) {
            v = v.trim();
            if (v.startsWith("Group")) {
                // add a new List and save its reference
                map.put(v, numbs = new ArrayList<>());
            } else {
                // add using current object
                numbs.add(Integer.valueOf(v));
            }
        }
如上所述,流不适用于有状态操作。但是,串行处理可以将每组的多行转换为每组一行,因此(
src/temp.txt
):

变成这样:

Group:A 12 27 14
Group:B 68 10 42 79
Group:D 98 187 894 67
Group:G 3 3
Group:G 5 5
String
列表中,通过在每个
组前面添加换行符:X
,修剪所有空格,然后连接所有字符串。然后,您可以以无状态方式流式处理列表,并将每个组映射到
IntSummaryStatistics

import java.util.List;
导入java.util.Map;
导入java.util.stream.collector;
导入java.util.stream.IntStream;
导入java.util.IntSummaryStatistics;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.io.IOException;
公共类堆栈溢出测试{
公共静态void main(字符串[]args){
Path Path=Path.of(“src/temp.txt”);
试一试{
//通过向匹配组特征的字符串添加换行符来转换字符串
列表转换=
Files.readAllLines(路径)
.stream()
.map(s->s.matches(“^[a-zA-Z]*:*”)?
“\n”+s.replace(“,”):s.trim())
.collect(collector.joining(“”)//一个长字符串
.lines()//根据换行符拆分
.skip(1)//不需要第一个空行
.collect(Collectors.toList());
System.out.println(“转换列表:\n”+转换);
System.out.println();
//使用各自的IntSummaryStatistics将转换后的列表映射到各个组
地图摘要=
转化
.stream()
.map(s->s.split(\\s”))
.collect(Collectors.toMap(s->s[0],//第一个索引是组
s->IntStream.range(1,s.length)
.map(i->Integer.parseInt(s[i]))
.summaryStatistics(),
(a,b)->{a.combine(b);返回a;}
)
);
System.out.println(“映射统计信息:\n”+mapSummary);
}捕获(IOEX异常){
System.out.println(“Oops:+ex”);
}
}
}
结果(被添加的换行符欺骗):


这需要一个有状态函子。我会在
collect()中使用一个
ing,但我不记得有状态函子在流API中是否合法。为什么使用downvote?实践中有许多类似的文本文件。正如所解释的,使用循环写下解决方案是很简单的。但我希望有一个更简单的流解决方案。这就是问题的原因,这个原因显然是错误的在标题(“Java stream”)和问题(“使用Java streams执行此操作”)。根据这一点,函子需要是无状态的,也就是说,在我看来,不能仅使用流。您可能需要首先使用普通循环(或其他库)将
映射中的元素分组,然后对条目进行流式处理。
Group: A=IntSummaryStatistics{count=3, sum=53, min=12, average=17.666667, max=27}
Group: B=IntSummaryStatistics{count=4, sum=199, min=10, average=49.750000, max=79}
Group: D=IntSummaryStatistics{count=5, sum=90, min=10, average=18.000000, max=30}

Group: A 
12
27 
14 
Group: B 
68
10 
42
79
Group: D
98
187
894
67
Group: G
3
3
Group: G
5
5
Group:A 12 27 14
Group:B 68 10 42 79
Group:D 98 187 894 67
Group:G 3 3
Group:G 5 5
Transformed list:
[Group:A 12 27 14 , Group:B 68 10 42 79 , Group:D 98 187 894 67 , Group:G 3 3 , Group:G 5 5]

Mapping statistics:
{
Group:B=IntSummaryStatistics{count=4, sum=199, min=10, average=49.750000, max=79},
Group:A=IntSummaryStatistics{count=3, sum=53, min=12, average=17.666667, max=27},
Group:G=IntSummaryStatistics{count=4, sum=16, min=3, average=4.000000, max=5},
Group:D=IntSummaryStatistics{count=4, sum=1246, min=67, average=311.500000, max=894}
}