1. ホーム
  2. java

HashMapのListに追加するためのショートカット

2023-11-27 21:54:58

質問

私はしばしば、オブジェクトのリストを取得し、オブジェクトに含まれる値に基づいてマップにそれらをグループ化する必要があります。例えば、ユーザーのリストを取り、国によってグループ化します。

このための私のコードは通常次のようになります。

Map<String, List<User>> usersByCountry = new HashMap<String, List<User>>();
for(User user : listOfUsers) {
    if(usersByCountry.containsKey(user.getCountry())) {
        //Add to existing list
        usersByCountry.get(user.getCountry()).add(user);

    } else {
        //Create new list
        List<User> users = new ArrayList<User>(1);
        users.add(user);
        usersByCountry.put(user.getCountry(), users);
    }
}

しかし、これでは不格好で、もっと良い方法を知っている人がいるのではないかと思わずにはいられません。今のところ、私が見ることのできる最も近いものは Google コレクションからの MultiMap .

標準的なアプローチはありますか?

ありがとうございます。

どのように解決するのですか?

Java 8 では Map#computeIfAbsent() .

Map<String, List<User>> usersByCountry = new HashMap<>();

for (User user : listOfUsers) {
    usersByCountry.computeIfAbsent(user.getCountry(), k -> new ArrayList<>()).add(user);
}

または、Stream APIの Collectors#groupingBy() から List から Map を直接指定します。

Map<String, List<User>> usersByCountry = listOfUsers.stream().collect(Collectors.groupingBy(User::getCountry));

Java7以下では、以下のようなものが最適です。

Map<String, List<User>> usersByCountry = new HashMap<>();

for (User user : listOfUsers) {
    List<User> users = usersByCountry.get(user.getCountry());
    if (users == null) {
        users = new ArrayList<>();
        usersByCountry.put(user.getCountry(), users);
    }
    users.add(user);
}

コモンズ・コレクション には LazyMap がありますが、パラメータ化されていません。 グアバ には、ある種の LazyMap または LazyList を使用することができます。 Multimap で示すように の回答は以下の通りです。 .