使用对象中的值准备列表映射,其中键是此对象内列表中的值
Prepare map of list with values from object where key is value from list inside this object
我class喜欢:
public class User {
private Long id;
private String firstname;
private String lastname;
private Address address;
private boolean active;
private List<Country> countries;
}
public class Country {
private String name;
private String capital;
}
而且我需要按国家/地区名称对用户进行排序。我做了这样的事情:
final Map<String, List<UserHelper>> usersByCountry = new HashMap<>();
users.stream()
.filter(User::isActive)
.forEach(user -> user.getCountry().stream()
.map(Country::getName)
.forEach(name -> {
if (usersByCountry.containsKey(name)) {
usersByCountry.get(name).add(new UserHelper(user.getId(), user.getFirstname()));
} else {
usersByCountry.put(name, new ArrayList<>(List.of(new UserHelper(user.getId(), user.getFirstname()))));
}
}));
@Value
private class UserHelper {
Long id;
String firstname;
}
但我想避免在 foreach 中添加要映射的元素。我更喜欢 Collectors.toMap()
或 groupingBy
之类的东西,但我不知道如何在这个地方做到这一点。
如果我没有正确理解你的问题,你想按国家/地区对用户进行分组。由于一个用户可以有多个国家/地区,因此您必须预料到一个用户最终可能会出现在多个组中。
一种方法是引入辅助 class, UserCountry
:
public record UserCountry(User user, Country country) {}
(如果您没有 Java 16+,这可能是 class)。
然后你可以将所有用户和他们的国家放在一起,然后按每个国家分组:
final Map<Country, List<User>> result =
users.stream()
.flatMap(user -> user.countries.stream().map(country -> new UserCountry(user, country)))
.collect(
Collectors.groupingBy(
UserCountry::country,
Collectors.mapping(UserCountry::user, Collectors.toList())));
我class喜欢:
public class User {
private Long id;
private String firstname;
private String lastname;
private Address address;
private boolean active;
private List<Country> countries;
}
public class Country {
private String name;
private String capital;
}
而且我需要按国家/地区名称对用户进行排序。我做了这样的事情:
final Map<String, List<UserHelper>> usersByCountry = new HashMap<>();
users.stream()
.filter(User::isActive)
.forEach(user -> user.getCountry().stream()
.map(Country::getName)
.forEach(name -> {
if (usersByCountry.containsKey(name)) {
usersByCountry.get(name).add(new UserHelper(user.getId(), user.getFirstname()));
} else {
usersByCountry.put(name, new ArrayList<>(List.of(new UserHelper(user.getId(), user.getFirstname()))));
}
}));
@Value
private class UserHelper {
Long id;
String firstname;
}
但我想避免在 foreach 中添加要映射的元素。我更喜欢 Collectors.toMap()
或 groupingBy
之类的东西,但我不知道如何在这个地方做到这一点。
如果我没有正确理解你的问题,你想按国家/地区对用户进行分组。由于一个用户可以有多个国家/地区,因此您必须预料到一个用户最终可能会出现在多个组中。
一种方法是引入辅助 class, UserCountry
:
public record UserCountry(User user, Country country) {}
(如果您没有 Java 16+,这可能是 class)。
然后你可以将所有用户和他们的国家放在一起,然后按每个国家分组:
final Map<Country, List<User>> result =
users.stream()
.flatMap(user -> user.countries.stream().map(country -> new UserCountry(user, country)))
.collect(
Collectors.groupingBy(
UserCountry::country,
Collectors.mapping(UserCountry::user, Collectors.toList())));