我有这个清单(List<String>):
["a", "b", null, "c", null, "d", "e"]
Run Code Online (Sandbox Code Playgroud)
我想要这样的事情:
[["a", "b"], ["c"], ["d", "e"]]
Run Code Online (Sandbox Code Playgroud)
换句话说,我想使用null值作为分隔符将我的列表拆分为子列表,以获取列表列表(List<List<String>>).我在寻找Java 8解决方案.我尝试过,Collectors.partitioningBy但我不确定这是我在寻找什么.谢谢!
我是一个ETL进程,我从Spring Data Repository中检索了很多实体.然后我使用并行流将实体映射到不同的实体.我可以使用使用者将这些新实体逐个存储在另一个存储库中,或者将它们收集到List中并将其存储在单个批量操作中.第一种是昂贵的,而后者可能超过可用的内存.
有没有一种很好的方法来收集流中的一定数量的元素(如限制),消耗该块,并继续并行处理直到所有元素都被处理?
让我们考虑以下代码:
客户代码:
public class MyClient {
private final MyClientSideService myClientSideService;
public MyClient(MyClientSideService myClientSideService) {
this.myClientSideService = myClientSideService;
}
public String requestRow(Integer req) {
return myClientSideService.requestSingleRow(req);
}
}
Run Code Online (Sandbox Code Playgroud)
客户端服务:
public class MyClientSideService {
private final MyServerSideService myServerSideService;
public MyClientSideService(MyServerSideService myServerSideService) {
this.myServerSideService = myServerSideService;
}
public String requestSingleRow(int req) {
return myServerSideService.requestRowBatch(Arrays.asList(req)).get(0);
}
}
Run Code Online (Sandbox Code Playgroud)
服务器端服务:
@Slf4j
public class MyServerSideService {
//single threaded bottleneck service
public synchronized List<String> requestRowBatch(List<Integer> batchReq) {
log.info("Req for {} started");
try {
Thread.sleep(100);
return batchReq.stream().map(String::valueOf).collect(Collectors.toList());
} catch …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading batching java.util.concurrent
我正在处理遵循以下模式的潜在无限数据元素流:
E1 <start mark>
E2 foo
E3 bah
...
En-1 bar
En <end mark>
也就是说,<String> 流必须先累积在缓冲区中,然后才能将它们映射到对象模型。
目标:将 a 聚合Stream<String>为 a,Stream<ObjectDefinedByStrings> 而无需收集无限流的开销。
用英语来说,代码类似于“一旦看到开始标记,就开始缓冲。缓冲直到看到结束标记,然后准备返回旧缓冲区,并准备一个新缓冲区。返回旧缓冲区。”
我当前的实现形式如下:
Data<String>.stream()
.map(functionReturningAnOptionalPresentOnlyIfObjectIsComplete)
.filter(Optional::isPresent)
Run Code Online (Sandbox Code Playgroud)
我有几个问题:
这个操作正确的名称是什么?(即我可以通过 Google 搜索更多示例吗?我发现的每个讨论都.map()涉及 1:1 映射。每个关于 .reduce 的讨论)都涉及 n:1 缩减。每次讨论都.collect()讨论将累积作为终端操作......)
从很多方面来看,这似乎都很糟糕。有更好的方法来实现这个吗?(候选人的形式.collectUntilConditionThenApplyFinisher(Collector,Condition,Finisher)......?)
谢谢!
I'm having something like:
List<Data> dataList = stepts.stream()
.flatMap(step -> step.getPartialDataList().stream())
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
So I'm combining into dataList multiple lists from every step.
My problem is that dataList might run into OutOfMemoryError. Any suggestions on how I can batch the dataList and save the batches into db?
My primitive idea is to:
for (Step step : steps) {
List<Data> partialDataList = step.getPartialDataList();
if (dataList.size() + partialDataList.size() <= MAXIMUM_SIZE) {
dataList.addAll(partialDataList);
} else {
saveIntoDb(dataList);
dataList = new ArrayList<>();
}
} …Run Code Online (Sandbox Code Playgroud) java ×4
java-8 ×4
java-stream ×3
batching ×1
collectors ×1
concurrency ×1
dictionary ×1
hibernate ×1
list ×1
mysql ×1
reduce ×1