第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

Collectors.groupingBy 的自定義收集器無法按預(yù)期工作

Collectors.groupingBy 的自定義收集器無法按預(yù)期工作

翻閱古今 2022-06-15 16:42:04
考慮簡單的類Foo:public class Foo {    public Float v1;    public Float v2;    public String name;    public Foo(String name, Float v1, Float v2) {        this.name = name;        this.v1 = v1;        this.v2 = v2;    }    public String getName() {        return name;    }}現(xiàn)在,我有一個Foos 的集合,我想按 s 對它們進行分組Foo::getName。我寫了一個自定義收集器來做到這一點,但它似乎沒有按預(yù)期工作。更準確地說,combiner()永遠不會被調(diào)用。為什么?public class Main {    public static void main(String[] args) {        List<Foo> foos = new ArrayList<>();        foos.add(new Foo("blue", 2f, 2f));        foos.add(new Foo("blue", 2f, 3f));        foos.add(new Foo("green", 3f, 4f));        Map<String, Float> fooGroups = foos.stream().collect(Collectors.groupingBy(Foo::getName, new FooCollector()));        System.out.println(fooGroups);    }    private static class FooCollector implements Collector<Foo, Float, Float> {        @Override        public Supplier<Float> supplier() {            return () -> new Float(0);        }        @Override        public BiConsumer<Float, Foo> accumulator() {            return (v, foo) -> v += foo.v1 * foo.v2;        }        @Override        public BinaryOperator<Float> combiner() {            return (v1, v2) -> v1 + v2;        }        @Override        public Function<Float, Float> finisher() {            return Function.identity();        }        @Override        public Set<Characteristics> characteristics() {            Set<Characteristics> characteristics = new TreeSet<>();            return characteristics;        }    }}
查看完整描述

2 回答

?
翻過高山走不出你

TA貢獻1875條經(jīng)驗 獲得超3個贊

首先,如果您不使用多個線程(并行流),則不需要調(diào)用組合器函數(shù)。調(diào)用組合器以組合流塊上的操作結(jié)果。這里沒有并行性,因此不需要調(diào)用組合器。


由于您的累加器功能,您得到零值。表達方式


v += foo.v1 * foo.v2;

將替換 v為新Float對象。原來的累加器對象沒有被修改;它仍然是0f。此外,F(xiàn)loat與其他數(shù)字包裝器類型(和String)一樣,它是不可變的,無法更改。


您需要一些其他類型的可變累加器對象。


class FloatAcc {

    private Float total;

    public FloatAcc(Float initial) {

        total = initial;

    }

    public void accumulate(Float item) {

        total += item;

    }

    public Float get() {

        return total;

    }

}

然后您可以修改您的自定義Collector以使用FloatAcc. 提供一個新的,F(xiàn)loatAcc調(diào)用函數(shù)等。accumulateaccumulator


class FooCollector implements Collector<Foo, FloatAcc, Float> {

    @Override

    public Supplier<FloatAcc> supplier() {

        return () -> new FloatAcc(0f);

    }

    @Override

    public BiConsumer<FloatAcc, Foo> accumulator() {

        return (v, foo) -> v.accumulate(foo.v1 * foo.v2);

    }

    @Override

    public BinaryOperator<FloatAcc> combiner() {

        return (v1, v2) -> {

            v1.accumulate(v2.get());

            return v1;

        };

    }

    @Override

    public Function<FloatAcc, Float> finisher() {

        return FloatAcc::get;

    }

    @Override

    public Set<Characteristics> characteristics() {

        Set<Characteristics> characteristics = new TreeSet<>();

        return characteristics;

    }

}

通過這些更改,我得到了您所期望的:


{green=12.0, blue=10.0}


查看完整回答
反對 回復(fù) 2022-06-15
?
慕沐林林

TA貢獻2016條經(jīng)驗 獲得超9個贊

您可以解釋為什么電流收集器不能從rgettman工作。

值得檢查一下存在哪些幫助方法來創(chuàng)建自定義收集器。例如,整個收集器可以更簡潔地定義為:

reducing(0.f, v -> v.v1 * v.v2, (a, b) -> a + b)

并非總是可以使用這些方法;但是簡潔性(并且可能是經(jīng)過充分測試的)應(yīng)該盡可能使它們成為首選。


查看完整回答
反對 回復(fù) 2022-06-15
  • 2 回答
  • 0 關(guān)注
  • 279 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號