個人的なメモ
- 忘れてしまうので、よく使いそうなパターンを記載
- 本当によく使うパターンは、自家版 Collectorsクラス/メソッドを作ってもいいのかも
Collectors#toMap()
LinkedHashMapを使いたい
明示的に LikedHashMap を使いたい。
ついでに、キー重複を許したい。
public static <T, K, V> Collector<T, ?, Map<K, V>> toMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return Collectors.toMap(
keyMapper,
valueMapper,
(a, b) -> b,
LinkedHashMap::new);
}
キー重複を許したくない場合には、例外を投げる。
(a, b) -> { throw new IllegalStateException(~); }
詳細は、標準の2引数 Collectors#toMap() を参照。
TreeMap を使いたい
キーで自然にソートしたい。
ほぼ同じ。
public static <T, K, V> Collector<T, ?, Map<K, V>> toTreeMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return Collectors.toMap(
keyMapper,
valueMapper,
(a, b) -> b,
TreeMap::new); // ★ここ
}
TreeMapにComparator を指定したいときは、コンストラクタ参照ではなくラムダ式で指定。
Collectors#toSet()
LinkedHashSetを使いたい
ここは toSet() ではなく、toCollection() を使うのがポイント。
public static <T> Collector<T, ?, Set<T>> toSet() {
return Collectors.toCollection(LinkedHashSet::new);
}
TreeSetを使いたい
基本同じ。
public static <T> Collector<T, ?, Set<T>> toTreeSet() {
return Collectors.toCollection(TreeSet::new);
}
Collectors#groupingBy
LinkedHashMapを使いたい
public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(
Function<? super T, ? extends K> classifier) {
return Collectors.groupingBy(classifier,
LinkedHashMap::new, // ★ここ
Collectors.toList());
}
TreeMapを使いたい
同じ。
public static <T, K> Collector<T, ?, Map<K, List<T>>> orderedGroupBy(
Function<? super T, ? extends K> classifier) {
return Collectors.groupingBy(classifier,
TreeMap::new, // ★ここ
Collectors.toList());
}
要素をListじゃなくSetにしたい
…良いメソッド名が思いつかない。
public static <T, K> Collector<T, ?, Map<K, Set<T>>> groupingBySet(
Function<? super T, ? extends K> classifier) {
return Collectors.groupingBy(classifier,
TreeMap::new,
Collectors.toCollection(LinkedHashSet::new)); // ★ここ
}
もちろん目的に応じて、TreeSetや、普通の Collectors.toSet() でもOK。
グルーピング時にListに詰める要素も変換したい
public static <T, K, D> Collector<T, ?, Map<K, List<D>>> groupingBy(
Function<? super T, ? extends K> classifier,
Function<? super T, ? extends D> mapper) {
return Collectors.groupingBy(classifier,
LinkedHashMap::new,
Collectors.mapping(mapper, // ★ここ
Collectors.toList()));
}
もちろん、List じゃなくて Set でもOK。
Collectors#collectingAndThen
変更不可な Map や List を生成したい場合。
public static <T, K, V> Collector<T, ?, Map<K, V>> toConstMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return Collectors.collectingAndThen(
Collectors.toMap(
keyMapper,
valueMapper),
Collections::unmodifiableMap);
}