首页 > 解决方案 > 使用 lambda 将对象列表减少为不可变映射

问题描述

我有一个Person对象列表。每个人都有一个唯一的 id,但这个人的名字可以是相同的。

Person {
    String id,
    String name,
}

我想将这组人员转换为ImmutableMap<String, ImmutableSet<String>>. map 的 key 应该是用户名,不可变集合包含特定用户名的 id。

我知道如何使用 HashMap 和 HashSet:

for (person : personList) {
    String id = person.id;
    String name = person.name;
    if (!hashMap.containsKey(name)) {
        hashMap.put(name, new HashSet<String>());
    }
    hashMap.get(name).add(id);
}

我想知道如何使用 ImmutableMap、ImmutableSet 和 lambda 来做到这一点。

标签: javalambdaimmutability

解决方案


这是一种可能的解决方案。

首先,生成一些数据。三个名字和 18 个 ID。把它们放在一个列表中。

      Random r = new Random();
      int[] ids = r.ints(1000, 1, 1000).distinct().limit(18).toArray();
      int id = 0;
      List<Person> people = new ArrayList<>();
      for (int i = 0; i < 6; i++) {
         for (String name : List.of("Bob", "Joe", "Mary")) {
            people.add(new Person(name, ids[id++]));
         }
      }

现在创建地图。

  1. 用于groupingBy创建key指向collection. 键是名称,集合是地图。

  2. collection(a set)持有_ids

      Map<String, Set<Integer>> nameToID =
            Collections.unmodifiableMap(people.stream().collect(
                  Collectors.groupingBy(Person::getName, Collectors.mapping(
                        Person::getID, Collectors.toUnmodifiableSet()))));

打印它们。

      nameToID.entrySet().forEach(
            e -> System.out.println(e.getKey() + " -> " + e.getValue()));

   }
}

这是带有一些附加方法和构造函数的 Person 类。

class Person {
   String name;
   int    id;

   public Person(String name, int id) {
      this.name = name;
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public int getID() {
      return id;
   }

   public String toString() {
      return "(" + name + "," + id + ")";
   }
}


推荐阅读