Использование groupingBy для создания Карты с неизменяемым списком в качестве ключа
Скажем, у меня есть класс под названием Project,
class Project {
private String projectId;
private String projectName;
}
и класс Employee, который имеет список проектов
class Employee {
private String name;
private List<Project> projects
}
У меня также есть список объектов Employee. Теперь мне нужно создать карту со списком проектов как ключ и набор объектов-сотрудников в качестве значения из этого списка. Я могу заставить его работать с помощью
Map<List<Project>, Set<Employee>> x =
employees
.stream
.collect(Collectors.groupingBy(Employee::getProjects, Collectors.toSet()));
Однако, поскольку я использую List в качестве ключа, я хочу быть более осторожным и следить за тем, чтобы список был неизменным. Есть ли способ достичь этого?
Спасибо.
Ответы
Ответ 1
Непрерывность списка поддерживается в Java 9. Вы можете просто изменить Employee#getProjects
на следующее:
public List<Project> getProjects() {
return List.of(projects.toArray(new Project[projects.size()]));
}
Если вы не хотите, чтобы этот метод возвращал неизменяемый List
, вы можете изменить Collector
:
employees.stream()
.collect(Collectors.groupingBy(e -> List.of(e.getProjects().toArray(new Project[0])), Collectors.toSet()));
Ответ 2
Если я не пропущу что-то очевидное здесь, не можете ли вы просто обернуть это в Collections.unmodifiableList
:
collect(Collectors.groupingBy(
emps -> Collections.unmodifiableList(emps.getProjects()),
Collectors.toSet());
Если у вас есть guava
на пути к классу, с другой стороны, вы можете использовать ImmutableList
Ответ 3
Вы можете использовать
private List<? extends Project> projects = new LinkedList<>();
при заполнении сотрудников. Он устанавливает логически неизменный список.
Ответ 4
Если вы не возражаете, чтобы ваша карта была первоначально сохранена в измененной карте и затем скопирована в неизменяемую коллекцию, вы можете сделать что-то вроде следующего:
ImmutableMap<List<Project>, List<Employee>> collect = employees.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Employee::getProjects),
ImmutableMap::copyOf));
The ImmutableMap - это структура Google Common (com.google.common.collect.ImmutableMap). Кредиты .