Java:从 Stream 到 esProc
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,执行非常复杂的查找、过滤和映射数据等操作,类似于使用 SQL 执行的数据库查询,还可以并行计算。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。
Stream 提供了集合运算,使用 filter, map, reduce, find, match, sorted 等可以比较方便地实现过滤、排序、查找、遍历等操作,表现与 SQL 很接近。
如过滤操作通过 Stream 只简单一句就可以完成:
Liststrings = Arrays.asList(“abc”, ““, “bc”, “efg”, “abcd”,””, “jkl”);
long count = strings.stream().filter(string -> string.isEmpty()).count();
分组汇总也很简单:
Map<BlogPostType, Integer> likesPerType = posts.stream().collect(groupingBy(BlogPost::getType, summingInt(BlogPost::getLikes)));
Stream 的多个操作可以串联成管道,这样可以优化操作,比如延迟执行 (laziness) 和短路 (short-circuiting)。Stream 还支持内部迭代,通过访问者模式(Visitor) 实现。
有了 Stream 的 Java 进行集合运算比之前硬写方便不少,但还是缺乏数据表对象,很多情况下写起来仍远不如 SQL 简单。
比如:按地区和部门汇总订单金额。
使用 SQL 查询很简单:
select area, department,sum(amount) total from orders group by area,department
使用 Stream 进行多字段分组汇总则要麻烦很多,要么使用嵌套的方式逐层分组,要么将多个分组字段先拼接成唯一 key 再分组(进行 key 的组装和拆分),代码远没有 SQL 简洁。
但是 SQL 也很麻烦,需要独立安装部署数据库,不像 Stream 那样是全 Java 的,一起打包部署都很方便。
用 esProc SPL 就方便多了:
SPL 有完善数据表对象及运算能力,不依赖于数据库,可以像 SQL 一样写,而且更强大,可以计算各种数据源。
esProc 作为 JAVA 计算类库就可以达到与 SQL 同样简单的效果
=orders.groups(area,department;sum(amount):total)
同时,在 SPL 中还允许直接使用 SQL 查询文件:
$select area, department,sum(amount) total from orders.txt group by area, department
当面对复杂计算时,SPL 可以比 SQL 更简单,进一步简化 Java 计算难度。比如:
计算一支股票最长连续上涨了多少天
SQL 写法:
select max(continuousDays) - 1
from (select count(*) continuousDays
from (select sum(changeSign) over(order by tradeDate) unRiseDays
from (select tradeDate,
case
when closePrice > lag(closePrice)
over(order by tradeDate) then
0
else
1
end changeSign
from stock))
group by unRiseDays)
SQL 的解法会很绕,看懂都不容易;使用 SPL 就要简单的多。
SPL 写法:
=stock.sort(tradeDate).group@i(closePrice < closePrice [-1]).max(~.len())
esProc 用 Java 开发,提供标准 JDBC 接口,可以无缝集成嵌入 Java 应用
集成代码:
public static void callspl() {
Connection con = null;
java.sql.Statement st;
try {
Class.forName("com.esproc.jdbc.InternalDriver");
con = DriverManager.getConnection("jdbc:esproc:local://");
st = con.createStatement();
ResultSet rst = st.executeQuery(""); // 计算股票最长连续上涨天数
System.out.println(rst);
} catch (Exception e) {
System.out.println(e);
} finally {
// 关闭连接
if (con != null) {
try {
con.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
}
SPL 是解释执行的,算法修改只要替换脚本就可以了,不需要重新启动应用。
更多介绍看这里:
JAVA 计算库