相关疑难解决方法(0)

带有批处理的Java 8 Stream

我有一个包含项目列表的大文件.

我想创建一批项目,使用此批处理发出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())

最好的方法是什么?

java batch-processing java-8 java-stream

80
推荐指数
8
解决办法
4万
查看次数

通过鉴别器功能对流进行分区

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)

java java-8 java-stream

19
推荐指数
1
解决办法
3914
查看次数

分组值序列

我想知道是否有任何漂亮的方式使用新的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)

java sorting lambda java-8 java-stream

9
推荐指数
2
解决办法
793
查看次数

如何正确地将流减少到另一个流

我有字符串和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)

java java-8 java-stream

4
推荐指数
2
解决办法
248
查看次数

标签 统计

java ×4

java-8 ×4

java-stream ×4

batch-processing ×1

lambda ×1

sorting ×1