亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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

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

慕尼黑8549860 2022-12-28 10:48:58
我有一個包含不同嵌套集合的類,現在我想接收嵌套集合的所有元素,具體我想收集集合的所有 StrokePoints。我可以用“舊的”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());                    }        }    }我正在尋找一種使用流功能填充 pointList 的方法。
查看完整描述

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)


查看完整回答
反對 回復 2022-12-28
?
白板的微信

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

或者你可以增加一個AtomicIntegerin 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());


查看完整回答
反對 回復 2022-12-28
?
慕后森

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


查看完整回答
反對 回復 2022-12-28
?
江戶川亂折騰

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 {

}


查看完整回答
反對 回復 2022-12-28
  • 4 回答
  • 0 關注
  • 160 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號