我有一个包含项目列表的大文件.
我想创建一批项目,使用此批处理发出HTTP请求(所有项目都需要作为HTTP请求中的参数).我可以通过for循环很容易地完成它,但作为Java 8的爱好者,我想尝试用Java 8的Stream框架编写它(并获得延迟处理的好处).
例:
List<String> batch = new ArrayList<>(BATCH_SIZE);
for (int i = 0; i < data.size(); i++) {
batch.add(data.get(i));
if (batch.size() == BATCH_SIZE) process(batch);
}
if (batch.size() > 0) process(batch);
Run Code Online (Sandbox Code Playgroud)
我想做一些很长的路要走
lazyFileStream.group(500).map(processBatch).collect(toList())
最好的方法是什么?
Streams API中缺少的一个功能是"分区依据"转换,例如Clojure中定义的.假设我想重现Hibernate的fetch join:我想发出一个SQL SELECT语句来从结果中接收这种对象:
class Family {
String surname;
List<String> members;
}
Run Code Online (Sandbox Code Playgroud)
我发出:
SELECT f.name, m.name
FROM Family f JOIN Member m on m.family_id = f.id
ORDER BY f.name
Run Code Online (Sandbox Code Playgroud)
我检索一个平坦的(f.name, m.name)记录流.现在我需要将其转换为Family对象流,并在其中包含其成员列表.假设我已经有了Stream<ResultRow>; 现在我需要将其转换为a Stream<List<ResultRow>>然后使用映射转换对其进行操作,将其转换为a Stream<Family>.
转换的语义如下:List只要提供的鉴别器函数保持返回相同的值,就保持将流收集到for中; 一旦值改变,发出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"
+ " …Run Code Online (Sandbox Code Playgroud) 我想知道是否有任何漂亮的方式使用新的Stream API来"分组"值序列.
例如,将一系列整数拆分为整数组,其中每个组都是一个递增的数字序列:
IntStream seq = IntStream.of(1, 2, 3, -1, -1, 1, 2, 1, 2);
IntFunction next = i -> i + 1;
// DESIRED OUTPUT: [[1,2,3], [-1], [-1], [1,2], [1,2]]
Run Code Online (Sandbox Code Playgroud) 我有字符串和null的流
Stream<String> str1 = Stream.of("A","B","C",null,null,"D",null,"E","F",null,"G",null);
Run Code Online (Sandbox Code Playgroud)
我想将它减少到另一个流,其中任何非空字符串序列连接在一起,即喜欢
Stream<String> str2 = Stream.of("ABC", "", "D", "EF","G")
Run Code Online (Sandbox Code Playgroud)
第一种方式,我发现 - 创建收集器,首先将完整的输入流减少到单个对象,并列出所有连接的字符串,然后从中创建新的流:
class Acc1 {
final private List<String> data = new ArrayList<>();
final private StringBuilder sb = new StringBuilder();
private void accept(final String s) {
if (s != null)
sb.append(s);
else {
data.add(sb.toString());
sb.setLength(0);
}
}
public static Collector<String,Acc1,Stream<String>> collector() {
return Collector.of(Acc1::new, Acc1::accept, (a,b)-> a, acc -> acc.data.stream());
}
}
...
Stream<String> str2 = str.collect(Acc1.collector());
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,如果使用str2,即使作为str2.findFirst(),输入流也将被完全处理.消耗时间和内存的操作以及来自某些生成器的无限流,它根本不起作用
另一种方法 - 创建外部对象,保持中间状态并在flatMap()中使用它:
class Acc2 {
final private StringBuilder …Run Code Online (Sandbox Code Playgroud)