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 应用

imagepng

集成代码:

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 计算库

http://www.raqsoft.com.cn/wx/java-computing.html