如何将集合拆分为子集?

时间:2014-05-18 00:35:26

标签: java list collections

我有一个用户列表,其中包含姓名和年龄。我想将此列表拆分为子列表,其中每个列表包含具有特定年龄的所有用户。

以下是一些示例代码:

public class User{
    public String name;
    public int age;
}

User user1 = new User();
user1.setName("Tom");
user1.setAge("20");

User user2 = new User();
user2.setName("Jack");
user2.setAge("21");

User user3 = new User();
user3.setName("Peter");
user3.setAge("21");

List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);

如何分割userList以便List1(持有20岁的用户)包含Tom 和List2(持有21岁的用户)包含杰克和彼得?

4 个答案:

答案 0 :(得分:3)

您似乎想要创建一个Map<Integer, List<User>>,它会将年龄映射到用户列表。

Map<Integer, List<User>> myMap = new HashMap<Integer, List<User>>();
for (User u: userList) {
   if (!myMap.containsKey(u.age)) myMap.put(u.age, new ArrayList<User>());
   myMap.get(u.age).add(u);
}

如果您想迭代它们并将其打印出来,您可以像这样迭代地图。

for (Integer i : myMap.keySet()) {
    System.out.print(i + ": ");
    StringBuilder sb = new StringBuilder();
    for (User u: myMap.get(i))
       sb.append("," + u.name);
    System.out.println(sb.toString().substring(1)); // Remove the first comma
}

输出:

21: Jack,Peter
20: Tom

请注意,如果您希望Mapage按顺序进行迭代,则可以将HashMap替换为上面的TreeMap,并认识到您的插入和访问将是O(log n)而不是O(1)

答案 1 :(得分:1)

使用具有关键年龄和值用户列表的地图,如下所示

Map<Integer,List<User>> userMap = new HashMap<Integer,List<User>>();

Then, whenever you want to add a new age you put a new empty list and
public void addNewAge(Integer age) {
    userMap.put(age, new ArrayList<User>());
}

When you want to add a user, you obtain the user list based on the age represented by a Integer.
public void addUserToList(Integer age, User user) {
    if(userMap.containsKey(age))
        userMap.get(age).add(user);        
}

在地图上再看一下,这样你就会感到舒适。

答案 2 :(得分:0)

如果您使用的是java 8,则可以使用lambda&#39; s,如本文所述 - &gt; Java lambda sublist

如果你不使用java 8,那么我也会使用一个Map实现,它将age作为键,列表作为值。

答案 3 :(得分:0)

如果要使用Streams API执行此操作,可以使用GroupingBy收集器:

Map<Integer, List<User>> groupedByAge = users.stream()
    .collect(Collectors.groupingBy((u)->u.age));

List<User> age20 = groupedByAge.get(20); // contains Tom
List<User> age21 = groupedByAge.get(21); // contains Jack, Peter

如果您想要超过特定年龄的所有用户,并且他们的年龄不是很方便,您可以从地图中收集,或者您可以将groupingBy功能更改为:

Map<Boolean, List<User>> groupedByAge = users.stream()
    .collect(Collectors.groupingBy((u)->u.age>20));

List<User> ageUnder21 = groupedByAge.get(false);
List<User> age21AndOver = groupedByAge.get(true);