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

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

如何使用 Java 8 Streams 對對象屬性進行分組并映射到另一個對象?

如何使用 Java 8 Streams 對對象屬性進行分組并映射到另一個對象?

慕森王 2022-05-12 15:37:16
假設我有一組碰碰車,它們的側面有尺寸、顏色和標識符(“汽車代碼”)。class BumperCar {    int size;    String color;    String carCode;}現在我需要將碰碰車映射到一個List對象DistGroup,每個對象都包含屬性和size汽車代碼。colorListclass DistGroup {    int size;    Color color;    List<String> carCodes;    void addCarCodes(List<String> carCodes) {        this.carCodes.addAll(carCodes);    }}例如,[    BumperCar(size=3, color=yellow, carCode=Q4M),    BumperCar(size=3, color=yellow, carCode=T5A),    BumperCar(size=3, color=red, carCode=6NR)]應該導致:[    DistGroup(size=3, color=yellow, carCodes=[ Q4M, T5A ]),    DistGroup(size=3, color=red, carCodes=[ 6NR ])]我嘗試了以下方法,它實際上做了我想做的事情。但問題是它實現了中間結果(到 a 中Map),我也認為它可以立即完成(可能使用mappingorcollectingAndThen或reducingor ),從而產生更優雅的代碼。List<BumperCar> bumperCars = …;Map<SizeColorCombination, List<BumperCar>> map = bumperCars.stream()    .collect(groupingBy(t -> new SizeColorCombination(t.getSize(), t.getColor())));List<DistGroup> distGroups = map.entrySet().stream()    .map(t -> {        DistGroup d = new DistGroup(t.getKey().getSize(), t.getKey().getColor());        d.addCarCodes(t.getValue().stream()            .map(BumperCar::getCarCode)            .collect(toList()));        return d;    })    .collect(toList());如何在不使用中間結果的變量的情況下獲得所需的結果?編輯:如何在不實現中間結果的情況下獲得所需的結果?我只是在尋找一種不會實現中間結果的方法,至少表面上不會。這意味著我不喜歡使用這樣的東西:something.stream()    .collect(…) // Materializing    .stream()    .collect(…); // Materializing second time當然,如果這是可能的。請注意,為簡潔起見,我省略了 getter 和構造函數。您還可以假設equals和hashCode方法已正確實現。另請注意,我使用的SizeColorCombination是我用作分組鍵的。這個類顯然包含屬性size和color。也可以使用諸如Tuple、之類的Pair類或表示兩個任意值的組合的任何其他類。編輯:還請注意,當然可以使用 ol' skool for 循環,但這不在此問題的范圍內。Entry
查看完整描述

3 回答

?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

如果我們假設它DistGroup基于hashCode/equalsand size,color你可以這樣做:


bumperCars

    .stream()

    .map(x -> {

        List<String> list = new ArrayList<>();

        list.add(x.getCarCode());

        return new SimpleEntry<>(x, list);

    })

    .map(x -> new DistGroup(x.getKey().getSize(), x.getKey().getColor(), x.getValue()))

    .collect(Collectors.toMap(

        Function.identity(),

        Function.identity(),

        (left, right) -> {

            left.getCarCodes().addAll(right.getCarCodes());

            return left;

        }))

    .values(); // Collection<DistGroup>


查看完整回答
反對 回復 2022-05-12
?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

解決方案-1

只需將兩個步驟合并為一個:


List<DistGroup> distGroups = bumperCars.stream()

        .collect(Collectors.groupingBy(t -> new SizeColorCombination(t.getSize(), t.getColor())))

        .entrySet().stream()

        .map(t -> {

            DistGroup d = new DistGroup(t.getKey().getSize(), t.getKey().getColor());

            d.addCarCodes(t.getValue().stream().map(BumperCar::getCarCode).collect(Collectors.toList()));

            return d;

        })

        .collect(Collectors.toList());

解決方案-2

groupingBy如果您可以使用屬性兩次并將值映射為List代碼,那么您的中間變量會好得多,例如:


Map<Integer, Map<String, List<String>>> sizeGroupedData = bumperCars.stream()

        .collect(Collectors.groupingBy(BumperCar::getSize,

                Collectors.groupingBy(BumperCar::getColor,

                        Collectors.mapping(BumperCar::getCarCode, Collectors.toList()))));

并簡單地使用forEach添加到最終列表中:


List<DistGroup> distGroups = new ArrayList<>();

sizeGroupedData.forEach((size, colorGrouped) ->

        colorGrouped.forEach((color, carCodes) -> distGroups.add(new DistGroup(size, color, carCodes))));

注意:我已經更新了您的構造函數,使其接受卡代碼列表。


DistGroup(int size, String color, List<String> carCodes) {

    this.size = size;

    this.color = color;

    addCarCodes(carCodes);

}

進一步將第二個解決方案組合成一個完整的陳述(盡管我自己喜歡forEach老實說):


List<DistGroup> distGroups = bumperCars.stream()

        .collect(Collectors.groupingBy(BumperCar::getSize,

                Collectors.groupingBy(BumperCar::getColor,

                        Collectors.mapping(BumperCar::getCarCode, Collectors.toList()))))

        .entrySet()

        .stream()

        .flatMap(a -> a.getValue().entrySet()

                .stream().map(b -> new DistGroup(a.getKey(), b.getKey(), b.getValue())))

        .collect(Collectors.toList());


查看完整回答
反對 回復 2022-05-12
?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

查看我的圖書館AbacusUtil

StreamEx.of(bumperCars)
         .groupBy(c -> Tuple.of(c.getSize(), c.getColor()), BumperCar::getCarCode)
         .map(e -> new DistGroup(e.getKey()._1, e.getKey()._2, e.getValue())
         .toList();


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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