自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用Java Steams創(chuàng)建數(shù)據(jù)透視表

譯文
移動開發(fā)
眾所周知,數(shù)據(jù)透視表很適合于數(shù)據(jù)的匯總。你可以使用Streams來創(chuàng)建數(shù)據(jù)透視表,對各種數(shù)據(jù)進行準備和排序,使之表現(xiàn)出更為易讀的格式。

【51CTO.com快譯】這次讓我們來看看如何使用Java 8 Streams(流)來實現(xiàn)一張數(shù)據(jù)透視表。通常情況下,原始數(shù)據(jù)本身一般并不容易被人們所讀懂,因此我們需要進行一些數(shù)據(jù)聚合操作來辨別出原始數(shù)據(jù)中的各種規(guī)律模式。而數(shù)據(jù)透視表就是這樣一種工具,它運用聚合的方法來展示出各種可視的圖形和圖表。

[[189685]]

在過往的文章中,我們曾展示過如何使用Java 8 Streams進行類似SQL的效果對原始數(shù)據(jù)進行切割與分解。而今天的文章就建立在那些例子之上,如果你覺得這些對你有些難度的話,我建議你先通過如下鏈接瀏覽那兩篇文章。

 

https://dzone.com/articles/java-streams-groupingby-examples

https://dzone.com/articles/using-java-collectors

 

如果你不喜歡使用這種“原始數(shù)據(jù)”的方法來創(chuàng)建一張數(shù)據(jù)透視表,而選擇使用Excel來實現(xiàn)的話,我為你提供了另外的備選方案,請參考如下鏈接:

 

http://www.novixys.com/blog/excel-pivot-table-using-apache-poi/

 

將CSV數(shù)據(jù)表示為POJO

 

我們用如下的POJO(簡單的Java對象,Plain Ordinary Java Object)來表示棒球運動員及其工資。

 

public class Player {

    private int year;

    private String teamID;

    private String lgID;

    private String playerID;

    private int salary;

    // defined getters and setters here

}

 

它的數(shù)據(jù)來自于一個簡單的CSV文件,該文件內(nèi)既沒有引用的字段,也沒有多行的字段,而且單個字段中還不存在著逗號。我們可以使用一個簡單的正則表達式模式來解析該CSV文件,并將數(shù)據(jù)加載到一個列表之中。其數(shù)據(jù)看起來如下所示,它一共有大約26428行:

 

yearID,teamID,lgID,playerID,salary

198***TL,NL,barkele01,870000

198***TL,NL,bedrost01,550000

198***TL,NL,benedbr01,545000

198***TL,NL,campri01,633333

198***TL,NL,ceronri01,625000

...

 

我們用類似于如下代碼的Streams加載CSV的數(shù)據(jù):

 

Pattern pattern = Pattern.compile(",");

try (BufferedReader in = new BufferedReader(new FileReader(filename));){

    List<Player> players = in

        .lines()

        .skip(1)

        .map(line -> {

                String[] arr = pattern.split(line);

                return new Player(Integer.parseInt(arr[0]),

                                  arr[1],

                                  arr[2],

                                  arr[3],

                                  Integer.parseInt(arr[4]));

            })

        .collect(Collectors.toList());

}

 

定義數(shù)據(jù)透視表列的類

 

我們使用下面的類來定義數(shù)據(jù)透視表的各個列容器的類。這些列是用于對數(shù)據(jù)進行分組的。如果你使用的是SQL的話,這些列將出現(xiàn)在“GROUP BY”的語句中。

 

public class YearTeam

{

    public int year;

    public String teamID;

    public YearTeam(int year,String teamID) {

        this.year = year;

        this.teamID = teamID;

    }

    @Override

    public boolean equals(Object other)

    {

        if ( other == null ) return false;

        if ( this == other ) return true;

        if ( other instanceof YearTeam ) {

            YearTeam yt = (YearTeam)other;

            if ( year == yt.year && teamID.equals(yt.teamID) )

                return true;

        }

        return false;

    }

    @Override

    public int hashCode()

    {

        int hash = 1;

        hash = hash * 17 + year;

        hash = hash * 31 + teamID.hashCode();

        return hash;

    }

    @Override

    public String toString()

    {

        StringBuilder sbuf = new StringBuilder();

        sbuf.append('[').append(year).append(", ").append(teamID)

            .append(']');

        return sbuf.toString();

    }

}

 

僅僅是為了方便起見,這些字段被定義為了“public(公有)”訪問屬性。而對于你自己的應(yīng)用程序,你完全可以將其設(shè)置為“private(私有)”屬性,并根據(jù)需要添加getter和/或setter。

這個類覆蓋重寫了equals()和hashCode(),因為它將在存儲一張Map(映射表)時被作為key(鍵)使用。

 

用Streams分組數(shù)據(jù)

 

我們在此讀取該CSV的數(shù)據(jù),為每一行創(chuàng)建一個POJO,并用上面所定義的透視表列的類來對數(shù)據(jù)進行分組。

 

Map<YearTeam,List<Player>> grouped = in

    .lines()

    .skip(1)

    .map(line -> {

            String[] arr = pattern.split(line);

            return new Player(Integer.parseInt(arr[0]),

                              arr[1],

                              arr[2],

                              arr[3],

                              Integer.parseInt(arr[4]));

        })

    .collect(Collectors.groupingBy(x-> new YearTeam(x.getYear(), x.getTeamID())));

 

至此,這些數(shù)據(jù)已被正確地收集到了在一張Map(映射表)中,并按指定的列項進行了分組。

 

將數(shù)據(jù)透視表打印成CSV 

 

讓我們將數(shù)據(jù)透視表里的數(shù)據(jù)打印成一個CSV文件,以便我們可以將其加載到Excel中用以比較。在打印數(shù)據(jù)的時候,我們用到了求和函數(shù)summingLong()。Java 8 Streams同樣也提供了averagingLong()函數(shù)讓你求出平均值。如果你需要一次性地快速獲取的話,那么summarizingLong()就能夠?qū)⑺行畔⒊尸F(xiàn)到你的面前,請盡情享用吧!

 

CSV列的頭部標題

 

我們使用teamID的各個數(shù)值來作為列的頭部標題。對它們的收集和打印操作,如下所示。我們這里使用TreeSet來對其進行字母順序的排列。

 

Set<String> teams = 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();

 

打印數(shù)據(jù)

 

這樣就創(chuàng)建并打印出來一張完整的數(shù)據(jù)透視表。對于團隊每年的總和,我們從運動員列表中提取出來,并執(zhí)行一個加總和打印的操作。

Set<Integer> years = grouped

    .keySet()

    .stream()

    .map(x -> x.year)

    .collect(Collectors.toSet());

years

    .stream()

    .forEach(y -> {

            System.out.print(y + ",");

            teams.stream().forEach(t -> {

                    YearTeam yt = new YearTeam(y, t);

                    List<Player> players = grouped.get(yt);

                    if ( players != null ) {

                        long total = players

                            .stream()

                   .collect(Collectors.summingLong(Player::getSalary));

                        System.out.print(total);

                    }

                    System.out.print(',');

                });

            System.out.println();

        });

 

比較來自Excel的輸出

 

我們將該CSV文件加載到Excel中并輸出如下數(shù)據(jù):

 

用Excel自帶的數(shù)據(jù)透視表功能進行比較,可見這些數(shù)據(jù)是相同的。(如下所示,由于某種原因,列“MON”出現(xiàn)在了Excel的前端。也許這是諸多神奇“特性”中的一種吧。反正各個數(shù)值都是相同的。)

朋友們,這就是使用Java自帶的簡單Collections(類集)來創(chuàng)建數(shù)據(jù)透視表的一種方法。你可以通過它去發(fā)現(xiàn)更多酷炫的用途!

 

總結(jié)

 

數(shù)據(jù)透視表的確是一種十分有用的數(shù)據(jù)匯總工具。大多數(shù)的數(shù)據(jù)分析軟件,包括Excel都有用到它。在此,我們學(xué)會了如何使用Java 8 Streams來創(chuàng)建出相同的數(shù)據(jù)結(jié)構(gòu)。同時,我們也用到了分組和加總來實現(xiàn)該功能。

 

【原標題】Making Pivot Table Using Java Streams (作者: Jay Sridhar )

原文鏈接:https://dzone.com/articles/java-pivot-table-using-streams

【51CTO譯稿,合作站點轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】

責任編輯:關(guān)崇 來源: 51CTO
相關(guān)推薦

2021-06-08 09:18:54

SQLPandas數(shù)據(jù)透視表

2020-05-09 10:38:31

Python透視表數(shù)據(jù)

2010-09-15 08:53:50

SQL Server

2022-11-27 11:00:15

2011-06-02 14:51:00

SQL Server

2021-09-10 16:10:21

panda透視表語言

2011-08-29 10:30:38

2009-06-11 13:16:57

JBPM數(shù)據(jù)庫

2022-06-17 09:21:53

Pandas代碼透視表

2012-08-23 10:21:01

大數(shù)據(jù)商業(yè)智能數(shù)據(jù)中心

2009-07-31 16:35:15

ibmdwRational

2009-02-26 16:05:23

Java手機終端J2ME

2014-04-28 14:06:41

2010-10-19 15:54:38

sql server創(chuàng)

2010-11-11 09:20:46

SQL Server創(chuàng)

2009-12-09 10:52:24

ibmdwLotus

2011-03-15 09:15:06

MyisamchkMySQL

2013-05-16 09:37:14

R語言

2009-11-06 14:25:20

Oracle創(chuàng)建用戶表

2010-04-12 16:50:47

Oracle索引聚簇表
點贊
收藏

51CTO技術(shù)棧公眾號