1

グループ化中にコレクションを超えて文字列を収集することは可能ですか? Java 8 では次のように動作します。

Map<String, String> discountOptions = p.getDiscountOptions().Stream()
    .collect(groupingBy(
        this::getDiscountName,
        Collectors.mapping(this::getValue, Collectors.joining(","))));

私は興味があります.Google Guavaでそれを行うための簡潔な方法はありますか? それがGuavaでそれを複製しようとする方法です:

Map<String, Collection<String>> stringCollectionMap = Multimaps.transformValues(
    Multimaps.index(p.getDiscountOptions(), 
        new Function<DiscountOption, String>() {
            @Override
            public String apply(DiscountOption d) {
                return getDiscountName(d);
            }
        }),
    new Function<DiscountOption, String>() {
        @Override
        public String apply(DiscountOption d) {
            return getValue(d);
        }
    }).asMap();

Map<String, String> discountOptions =  Maps.transformValues(
    stringCollectionMap,
    new Function<Collection<String>, String>() {
        @Override
        public String apply(Collection<String> strings) {
            return Joiner.on(",").join(strings);
        }
    });
4

1 に答える 1

3

Java 8 ストリーム API が存在する理由は、この種の操作を改善することであるため、Java 8 ストリーム API よりも簡潔なものは得られません。

Java 8 より前の関数型プログラミングは、Guava の関数型ユーティリティを使用して仮装することができますが、次のように警告されています。

Java 7 の時点で、Java での関数型プログラミングは、無名クラスのぎこちなく冗長な使用によってのみ近似できます.... Guava の関数型プログラミングイディオムの過度の使用は、冗長で、混乱し、判読不能で、非効率的なコードにつながる可能性があります.... 命令型コードJava 7 での最初の選択肢であるdefaultにする必要があります。

コードの必須の翻訳は次のとおりです。

private static final Joiner COMMA_JOINER = Joiner.on(",");

ListMultimap<String, String> groupedByDiscountName = ArrayListMultimap.create();
for (DiscountOption option : p.getDiscountOptions()) {
  groupedByDiscountName.put(getDiscountName(option), getValue(option));
}

ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
for (Entry<String, Collection<String>> e : groupedByDiscountName.asMap().entrySet()) {
  builder.put(e.getKey(), COMMA_JOINER.join(e.getValues());
}
Map<String, String> discountOptions = builder.build();

短くて読みやすいです。現在の API を考えると、これはおおよそ Java 7 で実行できる最善の方法です。

とはいえ、API の再検討を検討することもできます。特に、クラスからデータを抽出するために静的メソッド ( getDiscountName()、 ) を使用するのは奇妙です。これらはインスタンス メソッドの明確な候補のようです。同様に、1 つ以上のインスタンスを含み、カンマ区切りの文字列を返す を提供するクラスを作成することを検討することもできます。次に、オブジェクトを作成するだけで、準備完了です。getValue()DiscountOptionDiscountsDiscountOptiontoString()Discounts

于 2016-06-02T15:46:23.493 に答える