Java 有什么开源包可以做结构化数据处理?
几乎每个 Java 程序员都会创建和处理集合,它们是编程的基础,但是如果经常处理类似 SQL 的操作,(例如 "找出英语平均分低于 70 分的班级",“select CLASS,avg(English) as avg_En from students_scores group by CLASS having avg(English)<70”,大多数数据库仅以这样简单声明方式的操作),你会发现需要一遍又一遍地使用循环,一遍又一遍重复实现那些 SQL 中的简单操作。其次,还需要考虑如何才能仅在本机就能处理非常大的集合。为了加快处理速度,还需要利用多核架构,但是编写并行代码很困难且容易出错。其实如果使用Open-esProc,这个问题就迎刃而解了。但 Open-esProc 和一般 Java 包有所不同,是将数据类型和计算方法封装到一个叫 SPL 的脚本语言中,然后在 Java 程序中调用 SPL 脚本,返回 ResultSet 对象。
比如:找出英语平均分低于70分的班级。SPL 代码如下:
A |
|
1 |
=file(“E:/txt/Students_scores.csv”).import@tc() |
2 |
=A1.groups(CLASS;avg(English):avg_En) |
3 |
=A2.select(avg_En<70) |
完成上述任务,直接用 Java 显然代码十分冗长,但用 SPL 做结构化计算,对集合做过滤、排序、分组统计、连接等都非常简单。脚本文件(比如 condition.dfx)和 Java 存储在一起,通过 JDBC 接口在 JAVA 中调用,用法类似存储过程。这样,SPL 计算过程都是独立的,当遇到需求变动后,改动也非常方便。
…
ResultSet result = statement.executeQuery("call condition.dfx");
…
SPL 也支持类似 SQL 的用法,无须脚本文件,直接将其嵌入 JAVA
…
ResultSet result = statement.executeQuery("
=file(\“E:/txt/Students_scores.csv\”).import@tc()
.groups(CLASS;avg(English):avg_En).select(avg_En<70)");
…
SPL 中还提供了用 SQL 查询数据的方法,方便熟悉 SQL 的程序直接使用。比如:州信息,部门信息和员工信息分别存储在三个文本文件中(将三个文件换成三个 SPL 序表对象也同样成立),查询经理在 California 州的 New York 州员工。
A |
|
1 |
$select e.NAME as ENAME from E:/txt/EMPLOYEE.txt as e join E:/txt/DEPARTMENT.txt as d on e.DEPT=d.NAME join E:/txt/EMPLOYEE.txt as emp on d.MANAGER=emp.EID where e.STATE='New York' and emp.STATE='California' |
当数据很大时,内存大小就会形成处理的瓶颈,SPL 还通过游标读取的方式,类似数据库中的游标,做小批量读取,然后在游标上绑定计算,实现排序、关联和分组计算,这样就可以利用小内存完成大数据的计算。
A |
|
1 |
=file("E:/txt/Employees.txt").cursor@t().sortx(EId) |
2 |
=file("E:/txt/Orders.txt").cursor@t().sortx(SellerId) |
3 |
=joinx(A2:O,SellerId; A1:E,EId) |
4 |
=A3.groups(E.Dept;sum(O.Amount)) |
大数据处理经常需要加入并行计算提高计算效率,每个线程各自计算的方式处理一段数据,最后将各线程处理的结果进行汇总。
A | |
---|---|
1 | =file(“E:/txt/user_info_reg.csv”).cursor@tcm(;4) |
2 | =A1.groups(id_province;count(~):cnt) |
在 SPL 中使用并行提速非常容易,@m 表示并行计算,参数 4 表示 4 路并行,与单线程代码相比,仅仅多一个游标选项与参数,让用户使用并行非常方便。
利用 SPL 可以极大简化 Java 程序中的结构化数据计算,示例总结整理如下:
更多计算示例,参见 SPL 应用计算