当前位置: 首页 > 科技观察

用JavaSteams创建数据透视表

时间:2023-03-17 13:16:01 科技观察

【.com快译】这次我们就来看看如何使用Java8Streams(流)实现数据透视表。通常,原始数据本身并不容易被人们理解,因此我们需要进行一些数据聚合操作来识别原始数据中的各种规律模式。数据透视表就是这样一个工具,它使用聚合的方法来展示各种可视化的图形和图表。在之前的文章中,我们展示了如何使用Java8Streams执行类似SQL的效果来切割和分解原始数据。今天的文章就是基于这些例子。如果你觉得这些对你来说有点难,我建议你通过以下链接浏览这两篇文章。https://dzone.com/articles/java-streams-groupingby-exampleshttps://dzone.com/articles/using-java-collectors如果您不喜欢使用这种“原始数据”方法来创建数据透视表,如果你选择使用Excel来实现,我为你提供了另一种选择,请参考以下链接:http://www.novixys.com/blog/excel-pivot-table-using-apache-poi/RepresentingCSV数据作为POJO我们有以下POJO(普通普通Java对象)来表示棒球运动员和他们的薪水。publicclassPlayer{privateintyear;私有字符串团队ID;私有字符串lgID;私有字符串播放器ID;私人薪水;//definedgettersandsettershere}它的数据来自于一个简单的CSV文件,既没有引用Fields,也没有多行字段,也没有单个字段中的逗号。我们可以使用简单的正则表达式模式来解析CSV文件并将数据加载到列表中。它的数据是这样的,大约有26428行:yearID,teamID,lgID,playerID,salary198***TL,NL,barkele01,870000198***TL,NL,bedrost01,550000198***TL,NL,benedbr01,545000198***TL,NL,campri01,633333198***TL,NL,ceronri01,625000...我们使用类似于下面代码的Streams加载CSV数据:Patternpattern=Pattern.compile(",");try(BufferedReaderin=newBufferedReader(newFileReader(filename));){Listplayers=in.lines().skip(1).map(line->{String[]arr=pattern.split(line);returnnewPlayer(Integer.parseInt(arr[0]),arr[1],arr[2],arr[3],Integer.parseInt(arr[4]));}).collect(Collectors.toList()));}定义数据透视表列的类我们使用下面的类来定义数据透视表的每个列容器的类。这些列用于对数据进行分组。如果您正在使用SQL,这些列将出现在“GROUPBY”语句中。公共课YearTeam{publicintyear;公共字符串团队ID;publicYearTeam(intyear,StringteamID){this.year=year;this.teamID=teamID;}@Overridepublicbooleanequals(Objectother){if(other==null)returnfalse;如果(这个==其他)返回真;if(otherinstanceofYearTeam){YearTeamyt=(YearTeam)other;if(year==yt.year&&teamID.equals(yt.teamID))返回true;}返回假;}@OverridepublicinthashCode(){inthash=1;散列=散列*17+年;hash=hash*31+teamID.hashCode();返回散列;}@OverridepublicStringtoString(){StringBuildersbuf=newStringBuilder();sbuf.append('[').append(year).append(",").append(teamID).append(']');返回sbuf.toString();}}只是为了方便起见,这些字段被定义为“公共(public)”访问属性。对于您自己的应用程序,您可以将其设为“私有”属性并根据需要添加getter和/或setter。这个类重写了equals()和hashCode(),因为它会在存储一个Map(映射表)时作为key使用。使用Streams对数据进行分组这里我们从CSV中读取数据,为每一行创建一个POJO,并使用上面定义的数据透视表列类对数据进行分组。Map>grouped=in.lines().skip(1).map(line->{String[]arr=pattern.split(line);returnnewPlayer(Integer.parseInt(arr[0]),arr[1],arr[2],arr[3],Integer.parseInt(arr[4]));}).collect(Collectors.groupingBy(x->newYearTeam(x.getYear()),x.getTeamID())));至此,这些数据已经被正确的收集到一个Map(映射表)中,并按照指定的列项进行分组。将数据透视表打印为CSV让我们可以将数据透视表中的数据打印为CSV文件,以便我们可以将其加载到Excel中进行比较。打印数据时,我们使用求和函数summingLong()。Java8Streams还提供了averagingLong()函数来计算平均值。如果你需要一次快速获取,那么summarizingLong()可以将所有的信息呈现在你的面前,请尽情享受吧!CSV列的标题我们使用teamID的每个值作为列的标题。对它们的采集和打印操作如下。这里我们使用TreeSet按字母顺序排列它们。Setteams=grouped.keySet().stream().map(x->x.teamID).collect(Collectors.toCollection(TreeSet::new));System.out.print(',');teams.stream().forEach(t->System.out.print(t+","));System.out.println();打印数据这将创建并打印出完整的数据透视表。对于每年球队的总和,我们从球员列表中提取并执行求和和打印操作。Setyears=grouped.keySet().stream().map(x->x.year).collect(Collectors.toSet());years.stream().forEach(y->{System.out.print(y+",");teams.stream().forEach(t->{YearTeamyt=newYearTeam(y,t);Listplayers=grouped.get(yt);if(玩家!=null){longtotal=players.stream().collect(Collectors.summingLong(Player::getSalary));System.out.print(total);}System.out.print(',');});System.out.println();});对比Excel的输出我们将CSV文件加载到Excel中,输出如下数据:对比Excel自带的数据透视表功能,可以看出这些数据是一样的。(如下图,不知为何,Excel前端出现了“MON”这一列,也许是众多神奇“功能”之一,反正数值都是一样的。)朋友们,这是使用Java自带的简单Collections(类集)创建数据透视表的方法。你可以用它来寻找更多炫酷的用途!总结数据透视表确实是一个非常好用的数据汇总工具。大多数数据分析软件都使用它,包括Excel。在这里,我们学习了如何使用Java8Streams创建相同的数据结构。同时,我们还使用分组和求和来实现这个功能。【原标题】MakingPivotTableUsingJavaStreams(作者:JaySridhar)原文链接:https://dzone.com/articles/java-pivot-table-using-streams作者及出处为.com]