Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用流获取嵌套集合中的所有元素_Java_Java Stream - Fatal编程技术网

Java 如何使用流获取嵌套集合中的所有元素

Java 如何使用流获取嵌套集合中的所有元素,java,java-stream,Java,Java Stream,我有一个包含不同嵌套集合的类,现在我想接收嵌套集合的所有元素,具体来说,我想收集集合的所有strokepoint。我可以用“旧的”java解决这个问题,但是如何用流来解决呢 int strokesCounter = 0; List<StrokePoint> pointList = new ArrayList<>(); if (!strokesData.getListOfSessions().isEmpty()) { for (Ses

我有一个包含不同嵌套集合的类,现在我想接收嵌套集合的所有元素,具体来说,我想收集集合的所有strokepoint。我可以用“旧的”java解决这个问题,但是如何用流来解决呢

    int strokesCounter = 0;
    List<StrokePoint> pointList = new ArrayList<>();
    if (!strokesData.getListOfSessions().isEmpty()) {
        for (SessionStrokes session : strokesData.getListOfSessions()) {
            List<Strokes> strokes = session.getListOfStrokes();
            for (Strokes stroke : strokes) {
                strokesCounter++;
                List<StrokePoint> points = stroke.getListOfStrokePoints();
                pointList.addAll(stroke.getListOfStrokePoints());        
            }
        }
    }
int strokesCounter=0;
List pointList=new ArrayList();
如果(!StrokeData.getListOfSessions().isEmpty()){
for(SessionStrokes会话:strokesData.getListOfSessions()){
List strokes=session.getListOfStrokes();
用于(笔划:笔划){
冲程计数器++;
列表点=stroke.getListOfStrokePoints();
addAll(stroke.getListOfStrokePoints());
}
}
}

我正在寻找一种用流功能填充点列表的方法。

将嵌套数据展平非常简单:

List<StrokePoint> pointList = strokesData.getListOfSessions()
        .streams()
        .map(SessionStrokes::getListOfStrokes)
        .flatMap(List::stream)
        .map(Strokes::getListOfStrokePoints)
        .flatMap(List::stream)
        .collect(Collectors.toList());
并在第一个
平面图之后增加:

.peek(strokesCounter::incrementAndGet)
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());
您只需使用两次:

或者,您可以在
flatMap()
中增加一个
AtomicInteger


如果你担心副作用,这就可以了(但在撰写本文时,其他两个答案的可读性都会大大提高):

条目摘要=//
strokesData.getListOfSessions()的
.stream()
.flatMap(会话->会话.getListOfStrokes().stream())
.map(笔划->新建SimpleEntry(1,strokes.getListOfStrokePoints())
.减少((l1,l2)->{
int count=l1.getKey()+l2.getKey();
List=l1.getValue();
list.addAll(l2.getValue());
返回新的SimpleEntry(计数、列表);
})
.orElse(新的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 {
}
公共类刮擦{
公共静态void main(字符串[]args){
int strokesCounter=0;
List pointList=new ArrayList();
StrokesData StrokesData=新StrokesData();
SessionStrokes SessionStrokes=新SessionStrokes();
strokesData.sessionStrokes.add(sessionStrokes);
笔划s1=新笔划();
sessionStrokes.strokesList.add(s1);
s1.strokePoints.add(新StrokePoint());
s1.strokePoints.add(新StrokePoint());
笔划s2=新笔划();
sessionStrokes.strokesList.add(s2);
s2.strokePoints.add(新StrokePoint());
s2.strokePoints.add(新StrokePoint());
s2.strokePoints.add(新StrokePoint());
s2.strokePoints.add(新StrokePoint());
s2.strokePoints.add(新StrokePoint());
s2.strokePoints.add(新StrokePoint());
条目摘要=//
strokesData.getListOfSessions()的
.stream()
.flatMap(会话->会话.getListOfStrokes()
.stream())
.map(笔划->新建SimpleEntry(1,strokes.getListOfStrokePoints())
.减少((l1,l2)->{
int count=l1.getKey()+l2.getKey();
List=l1.getValue();
list.addAll(l2.getValue());
返回新的SimpleEntry(计数、列表);
})
.orElse(新的SimpleEntry(0,Collections.emptyList());
strokesCounter=summary.getKey();
pointList=summary.getValue();
系统输出打印LN(行程计数器);
System.out.println(点列表);
}
}
类StrokesData{
List sessionStrokes=new ArrayList();
公共列表getListOfSessions(){
返回会话行程;
}
}
类SessionStrokes{
List strokesList=new ArrayList();
公共列表getListOfStrokes(){
返回行程表;
}
}
课堂笔画{
List strokePoints=new ArrayList();
公共列表getListOfStrokePoints(){
返回行程点;
}
}
类频点{
}

由于主要目的是解决收集
列表的问题,您可以使用
flatMap
操作执行该操作,如下所示:

List<StrokePoint> points = strokesData.getListOfSessions()
        .stream()
        .flatMap(ss -> ss.getListOfStrokes().stream()
                .flatMap(s -> s.getListOfStrokePoints().stream()))
        .collect(Collectors.toList());

要合并这些操作,可以构造一个
AbstractMap.SimpleEntry
,同时将条目减少为:

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())));

你算错总数了。不妨执行
strokesCounter=pointList.size()
@shmosel,代码似乎可以工作-添加了一个带有一些类型存根实现的编辑-和
strokesCounter==2
pointList.size()==8
。。。(说真的)请记住我做错了什么,否则我会为此而烦恼的!!
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());
    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 {
}
List<StrokePoint> points = strokesData.getListOfSessions()
        .stream()
        .flatMap(ss -> ss.getListOfStrokes().stream()
                .flatMap(s -> s.getListOfStrokePoints().stream()))
        .collect(Collectors.toList());
long strokeCount = strokesData.getListOfSessions()
        .stream()
        .mapToLong(ss -> ss.getListOfStrokes().size())
        .sum();
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())));
long strokeCount = reduce.getKey();
List<StrokePoint> strokePoints = reduce.getValue().collect(Collectors.toList());