4 回答

TA贡献1811条经验 获得超4个赞
展平嵌套数据非常简单:
List<StrokePoint> pointList = strokesData.getListOfSessions() .streams() .map(SessionStrokes::getListOfStrokes) .flatMap(List::stream) .map(Strokes::getListOfStrokePoints) .flatMap(List::stream) .collect(Collectors.toList());
沿途收集划水次数比较棘手,而且有些争议。你可以创建一个
AtomicInteger strokesCounter = new AtomicInteger();
并在第一个之后增加它flatMap
:
.peek(strokesCounter::incrementAndGet)

TA贡献1883条经验 获得超3个赞
你可以只使用Stream.flatMap()
两次:
List<StrokePoint> pointList = strokesData.getListOfSessions().stream() .flatMap(session -> session.getListOfStrokes().stream()) .flatMap(strokes -> strokes.getListOfStrokePoints().stream()) .collect(Collectors.toList());
如果您需要计算笔画列表,您可以将其分成两部分并使用List.size()
:
List<Strokes> strokesList = strokesData.getListOfSessions().stream() .flatMap(session -> session.getListOfStrokes().stream()) .collect(Collectors.toList());int strokesCounter = strokesList.size(); List<StrokePoint> pointList = strokesList.stream() .flatMap(strokes -> strokes.getListOfStrokePoints().stream()) .collect(Collectors.toList());
或者你可以增加一个AtomicInteger
in flatMap()
:
final AtomicInteger strokesCounter = new AtomicInteger(); List<StrokePoint> pointList = strokesData.getListOfSessions().stream() .flatMap(session -> { List<Strokes> strokes = session.getListOfStrokes(); strokesCounter.addAndGet(strokes.size()); return strokes.stream(); }) .flatMap(strokes -> strokes.getListOfStrokePoints().stream()) .collect(Collectors.toList());
或与peek()
:
final AtomicInteger strokesCounter = new AtomicInteger(); List<StrokePoint> pointList = strokesData.getListOfSessions().stream() .flatMap(session -> session.getListOfStrokes().stream()) .peek(i -> strokesCounter.incrementAndGet()) .flatMap(strokes -> strokes.getListOfStrokePoints().stream()) .collect(Collectors.toList());

TA贡献1802条经验 获得超5个赞
由于主要目的是解决收集 的问题List<StrokePoint>,您可以使用以下flatMap操作执行它:
List<StrokePoint> points = strokesData.getListOfSessions()
.stream()
.flatMap(ss -> ss.getListOfStrokes().stream()
.flatMap(s -> s.getListOfStrokePoints().stream()))
.collect(Collectors.toList());
此外,Strokes 的计数也可以通过对列表的大小求和来使用流来计算:
long strokeCount = strokesData.getListOfSessions()
.stream()
.mapToLong(ss -> ss.getListOfStrokes().size())
.sum();
要合并这些操作,您可以构造AbstractMap.SimpleEntrywhile 减少条目为:
AbstractMap.SimpleEntry<Integer, Stream<StrokePoint>> reduce = strokesData.getListOfSessions()
.stream()
.map(ss -> new AbstractMap.SimpleEntry<>(ss.getListOfStrokes().size(),
ss.getListOfStrokes()
.stream()
.flatMap(s -> s.getListOfStrokePoints().stream())))
.reduce(new AbstractMap.SimpleEntry<>(1, Stream.empty()),
(e1, e2) -> new AbstractMap.SimpleEntry<>(
Integer.sum(e1.getKey(), e2.getKey()),
Stream.concat(e1.getValue(), e2.getValue())));
使用此条目,您可以获得 s 的计数和Strokes 的列表StrokePoint:
long strokeCount = reduce.getKey();
List<StrokePoint> strokePoints = reduce.getValue().collect(Collectors.toList());

TA贡献1851条经验 获得超5个赞
如果您担心副作用,这样做就可以了(但是在撰写本文时其他两个答案都更具可读性):
Entry<Integer, List<StrokePoint>> summary = //
strokesData.getListOfSessions()
.stream()
.flatMap(session -> session.getListOfStrokes().stream())
.map(strokes -> new SimpleEntry<>(1, strokes.getListOfStrokePoints()))
.reduce((l1, l2) -> {
int count = l1.getKey() + l2.getKey();
List<StrokePoint> list = l1.getValue();
list.addAll(l2.getValue());
return new SimpleEntry<>(count, list);
})
.orElse(new SimpleEntry<>(0, Collections.emptyList()));
strokesCounter = summary.getKey();
pointList = summary.getValue();
编辑以添加验证:
public class Scratch {
public static void main(String[] args) {
int strokesCounter = 0;
List<StrokePoint> pointList = new ArrayList<>();
StrokesData strokesData = new StrokesData();
SessionStrokes sessionStrokes = new SessionStrokes();
strokesData.sessionStrokes.add(sessionStrokes);
Strokes s1 = new Strokes();
sessionStrokes.strokesList.add(s1);
s1.strokePoints.add(new StrokePoint());
s1.strokePoints.add(new StrokePoint());
Strokes s2 = new Strokes();
sessionStrokes.strokesList.add(s2);
s2.strokePoints.add(new StrokePoint());
s2.strokePoints.add(new StrokePoint());
s2.strokePoints.add(new StrokePoint());
s2.strokePoints.add(new StrokePoint());
s2.strokePoints.add(new StrokePoint());
s2.strokePoints.add(new StrokePoint());
Entry<Integer, List<StrokePoint>> summary = //
strokesData.getListOfSessions()
.stream()
.flatMap(session -> session.getListOfStrokes()
.stream())
.map(strokes -> new SimpleEntry<>(1, strokes.getListOfStrokePoints()))
.reduce((l1, l2) -> {
int count = l1.getKey() + l2.getKey();
List<StrokePoint> list = l1.getValue();
list.addAll(l2.getValue());
return new SimpleEntry<>(count, list);
})
.orElse(new SimpleEntry<>(0, Collections.emptyList()));
strokesCounter = summary.getKey();
pointList = summary.getValue();
System.out.println(strokesCounter);
System.out.println(pointList);
}
}
class StrokesData {
List<SessionStrokes> sessionStrokes = new ArrayList<>();
public List<SessionStrokes> getListOfSessions() {
return sessionStrokes;
}
}
class SessionStrokes {
List<Strokes> strokesList = new ArrayList<>();
public List<Strokes> getListOfStrokes() {
return strokesList;
}
}
class Strokes {
List<StrokePoint> strokePoints = new ArrayList<>();
public List<StrokePoint> getListOfStrokePoints() {
return strokePoints;
}
}
class StrokePoint {
}
添加回答
举报