У меня есть коллекция объектов, которая внутри себя содержит также коллекцию объектов, которые требуется отсортировать в алфавитном порядке по имени поля name. Каким способом лучше это всего сделать, через стримы я смог отсортировать только внешние объекты, но как подобраться к внутренним не понятно.
Прикладываю скрин структуры объектов. Соответственно, нужна сортировка только коллекции members. Подскажите, каким способом это лучше всего сделать?
UPDATE:
public class SmbpStructUserType extends SmbpUserType {
@XmlElement(name = "Members")
MembersList membersList = new MembersList();
public boolean addMember(Member member) {
return membersList.members.add(member);
}
public List<Member> getMembers() {
return Collections.unmodifiableList(membersList.members);
}
static class MembersList {
@XmlElement(name = "Member")
List<Member> members = new ArrayList<>();
}
public static class Member {
private String name;
private long userTypeId;
public String getName() {
return name;
}
@XmlAttribute(name = "Name", required = true)
public void setName(String name) {
this.name = name;
}
public long getUserTypeId() {
return userTypeId;
}
@XmlAttribute(name = "UserTypeId", required = true)
public void setUserTypeId(long userTypeId) {
this.userTypeId = userTypeId;
}
}
}
Добавление элементов:
Map<Integer, SmbpStructUserType> structUserTypeMap = new HashMap<>();
jdbcTemplate.query(queryForGetStructUserTypes, resultSet -> {
SmbpStructUserType smbpStructUserType = structUserTypeMap.computeIfAbsent(userTypeId, p -> {
SmbpStructUserType userType = new SmbpStructUserType();
userType.setId(userTypeId);
userType.setName(typeName);
userType.setNamespace(namespace);
userType.setDescription(description);
return userType;
});
SmbpStructUserType.Member member = new SmbpStructUserType.Member();
member.setName(resultSet.getString("MemberName"));
member.setUserTypeId(resultSet.getLong("MemberUserTypeId"));
smbpStructUserType.addMember(member);
}, UserTypeKind.STRUCT.getId());
HashMap? Которая внутри содержит коллекцию? У вас формулировка идет вразрез с тем, что на скриншотике и в коде.
Обновил ответ
Для того, чтобы отсортировать (по полю name) объекты Member внутри коллекций members, которые в свою очередь находятся в объектах MembersList которые находятся в объектах SmbpStructUserType, вам нужно сделать вот так:
structUserTypeMap.forEach((k, v) -> {
v.membersList.members.sort(Comparator.comparing(m -> m.name));
});
Что делаю:
Проходим-пробегаем по мапе structUserTypeMap, из каждого ее value берем membersList.members - ArrayList. На этой коллекции вызываем метод sort, передавая компаратор, который будет сравнивать объекты Member по их полю name. Коллекция отсортирована в том месте, где и была. И все довольны!
Если брать values:
values = structUserTypeMap.values();
values.forEach(v -> {
v.membersList.members.sort(Comparator.comparing(m -> m.name));
});
В способе с потоками (stream) создаются временные наборы элементов, а исходные остаются нетронутыми, поэтому тут потоки я не использовал.
Однако с точки зрения читаемости кода, да и в целом как хороший тон, вам стоило бы инкапсулировать вашу сортировку внутри, скажем, вашего SmbpStructUserType:
public void sortMembers() {
// логика сортировки тут
}
Чтобы потом можно было просто и понятно сортировать всю карту:
structUserTypeMap.forEach((k, v) -> v.sortMembers());
А для values еще приятнее:
values.forEach(SmbpStructUserType::sortMembers);
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости