我有一个JsonNode流,我想把它转换成类似CSV的Stream〈String[]〉,其中第一行是头,然后是值。TextDataUtils.sample
也有同样的期望。我目前使用Stream.concat
来实现这一点,但第一行总是[]
,因为我只在开始处理值流后才提取头。
GoogleAdsGetValuesResponse getValuesResponse = client.getValues(getValuesRequest);
AtomicLong consumedRows = new AtomicLong();
List<String> headers = new ArrayList<>();
Stream<String[]> valueStream =
getValuesResponse
.getValuesStream()
.limit(request.getLimit())
.map(
rowNode -> {
if (consumedRows.get() == 0) {
extractAllKeys(rowNode, "", headers);
headers.removeIf(header -> !header.contains("."));
}
String[] row =
headers.stream()
.map(header -> rowNode.at(getJsonPointerString(header)).asText())
.toArray(String[]::new);
consumedRows.getAndIncrement();
return row;
});
Stream<String[]> headerStream = Stream.of(headers.toArray(String[]::new), new String[] {});
Stream<String[]> dataStream = Stream.concat(headerStream, valueStream);
return TextDataUtils.sample(dataStream, Collections.emptyMap(), request.getLimit(), false);
我如何实现这个目标?从同一个流中添加第一个元素到流中。感谢您的任何建议。我真的很感谢您能提供的任何帮助。
1条答案
按热度按时间7tofc5zh1#
Java不允许您在迭代集合时更改集合,因此您想做的事情是不可能的。
我建议首先用
limit(1)
处理头,然后继续用skip(1)
将其与剩余的已处理项连接起来。大致如下:
请注意,您不能重用启动响应流。如果底层流是正确的延迟获取,这仍然是有效的。
顺便说一句,我会避免编写有副作用的map函数。这会使代码更难推理。