按鉴别器函数对流进行分区
2022-09-01 19:18:20
Streams API中缺少的功能之一是“分区依据”转换,例如Clojure中定义的转换。假设我想重现Hibernate的抓取联接:我想发出一个SQL SELECT语句来从结果中接收这种对象:
class Family {
String surname;
List<String> members;
}
我问题:
SELECT f.name, m.name
FROM Family f JOIN Member m on m.family_id = f.id
ORDER BY f.name
我检索了一个平坦的记录流。现在,我需要将其转换为对象流,其中包含其成员列表。假设我已经有一个 ;现在我需要将其转换为 a,然后通过映射转换将其转换为 .(f.name, m.name)
Family
Stream<ResultRow>
Stream<List<ResultRow>>
Stream<Family>
转换的语义如下:只要提供的鉴别器函数继续返回相同的值,就继续将流收集到 a 中;一旦值更改,就将 作为输出流的元素发出,并开始收集新的 .List
List
List
我希望能够编写这种代码(我已经有了方法):resultStream
Stream<ResultRow> dbStream = resultStream(queryBuilder.createQuery(
"SELECT f.name, m.name"
+ " FROM Family f JOIN Member m on m.family_id = f.id"
+ " ORDER BY f.name"));
Stream<List<ResultRow> partitioned = partitionBy(r -> r.string(0), dbStream);
Stream<Family> = partitioned.map(rs -> {
Family f = new Family(rs.get(0).string(0));
f.members = rs.stream().map(r -> r.string(1)).collect(toList());
return f;
});
毋庸置疑,我希望生成的流保持懒惰(非具体化),因为我希望能够在不达到任何O(n)内存限制的情况下处理任何大小的结果集。如果没有这个关键要求,我会对提供的收藏家感到满意。groupingBy