次のコードは機能し、読み込み可能ですが、必要ないはずのない中間的な操作があります。私は実際のコードがはるかに大きなプロセスの一部であるので、この単純化されたバージョンを書いています。Java 8ストリームコレクタ - 複数のバケットのオブジェクトを持つマップを作成するコレクタ
私はのWidget
を持っています。それぞれの名前と複数の種類(WidgetType
列挙型の定数で示されます)。これらの複数の型はStream<WidgetType>
として取得可能ですが、必要であれば他の型として返すことができます。 (様々な理由から、それはこれらが原因で、これらのウィジェットは、実際のコードで後に使用される方法のStream<WidgetType>
として返されることが強く望まある。)
これらのウィジェットは、後に翻訳されるEnumMap<WidgetType, List<Widget>>
に追加されEnumMap<WidgetType, Widget[]>
。
各Widget
が単一WidgetType
を持っていた場合、これは解決些細しかし、任意のウィジェットは、1種類以上を持っている可能性があるので、私はCollectors.groupingBy()
方法(およびその過負荷)の構文で、すべて自分につまずくいでしょう。
コード例はここでも完全に機能し、私に必要な正確な結果が得られます。
class StackOverFlowExample {
private final Map<WidgetType, Widget[]> widgetMap = new EnumMap<>(WidgetType.class);
public static void main(String[] args) { new StackOverFlowExample(); }
StackOverFlowExample() {
Collection<Widget> widgetList = getWidgetsFromWhereverWidgetsComeFrom();
{
final Map<WidgetType, List<Widget>> intermediateMap = new EnumMap<>(WidgetType.class);
widgetList.forEach(w ->
w.getWidgetTypes().forEach(wt -> {
intermediateMap.putIfAbsent(wt, new ArrayList<>());
intermediateMap.get(wt).add(w);
})
);
intermediateMap.entrySet().forEach(e -> widgetMap.put(e.getKey(), e.getValue().toArray(new Widget[0])));
}
Arrays.stream(WidgetType.values()).forEach(wt -> System.out.println(wt + ": " + Arrays.toString(widgetMap.get(wt))));
}
private Collection<Widget> getWidgetsFromWhereverWidgetsComeFrom() {
return Arrays.asList(
new Widget("1st", WidgetType.TYPE_A, WidgetType.TYPE_B),
new Widget("2nd", WidgetType.TYPE_A, WidgetType.TYPE_C),
new Widget("3rd", WidgetType.TYPE_A, WidgetType.TYPE_D),
new Widget("4th", WidgetType.TYPE_C, WidgetType.TYPE_D)
);
}
}
この出力:完全性期すため
TYPE_A: [1st, 2nd, 3rd]
TYPE_B: [1st]
TYPE_C: [2nd, 4th]
TYPE_D: [3rd, 4th]
は、ここWidget
クラスとWidgetType
列挙です:
class Widget {
private final String name;
private final WidgetType[] widgetTypes;
Widget(String n, WidgetType ... wt) { name = n; widgetTypes = wt; }
public String getName() { return name; }
public Stream<WidgetType> getWidgetTypes() { return Arrays.stream(widgetTypes).distinct(); }
@Override public String toString() { return name; }
}
enum WidgetType { TYPE_A, TYPE_B, TYPE_C, TYPE_D }
このロジックを実行するためのより良い方法上の任意のアイデアは歓迎されています。ありがとう!
これはまだ 'ウィジェット[]'へ '一覧'からのステップを必要とします。 'collectAndThen(toList()、l - > l.toArray(new Widget [0]))'を使うことができました。 –
ありがとう、@JornVernee。編集されました。 –
'Collectors.mapping()'は私が欠けていた部分です。 'collectingAndThen()'の解決策もボーナスです。 (私はかなりのステップを必要とすることにかなり辞職していた。)それを釘付けにした、ルーク。 1日中+1。感謝万円! :) – Darkly