У меня есть список объектов класса Job, у каждого объекта есть коллекция тегов (сетей), эта коллекция изменчива и не влияет на равенство hashCode и объектов.Java 8 post grouping by
Что мне нужно сделать, чтобы получить список всех уникальных объектов Job и для каждого такого объекта объединить все теги, например, у меня есть список:
[{position: "CTO", dates: "2012-2014", city: "New York", networks: ["foo"]}, {position: "CTO", dates: "2012-2014", city: "New York", networks: ["bar"]}]
Это должно быть уменьшено до [{position: "CTO", dates: "2012-2014", city: "New York", networks: ["foo", "bar"]}]
public class Job {
private final String position;
private final String dates;
private final Integer startYear;
private final Integer endYear;
private final String city;
private Set<NetworkType> networks;
public String getPosition() {
return position;
}
public String getDates() {
return dates;
}
public String getCity() {
return city;
}
public Set<NetworkType> getNetworks() {
return networks;
}
public void setNetworks(Set<NetworkType> networks) {
this.networks = networks;
}
public Integer getStartYear() {
return startYear;
}
public Integer getEndYear() {
return endYear;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Job)) {
return false;
}
Job job = (Job) o;
return Objects.equals(position, job.position) &&
Objects.equals(dates, job.dates) &&
Objects.equals(city, job.city);
}
@Override
public int hashCode() {
return Objects.hash(position, dates, city);
}
}
Это фактический код класса работы, и это, как я осуществил эту операцию:
Map<Job, List<Job>> jobsMap = jobs.stream().collect(Collectors.groupingBy(job -> job));
jobsMap.keySet().stream()
.peek(job -> jobsMap.get(job).stream().forEach(j -> job.getNetworks().addAll(j.getNetworks())))
.sorted(Comparator.comparing((Job o) -> Objects.firstNonNull(o.getEndYear(), Integer.MAX_VALUE))
.reversed())
.collect(Collectors.toList());
Но я чувствую себя очень плохо для этого кода, тем более что я использую внешнюю карту внутри потока, и мне интересно, есть ли способ сделать это в одной цепочке без промежуточных преобразований. Я был бы признателен за любую действительную критику в отношении моей реализации этой функции. Спасибо!
Вам нужно 'groupBy' ваше' задание' 'position', а затем использовать пользовательский коллекционер для объединения вашего' List 'в' Map' в одно задание '. –
Если другие поля, такие как «город», различны, должны ли сети быть объединены с другой работой? – Bohemian
Нет, на самом деле, я группирую объекты по принципу равенства groupingBy (job -> job). Сеть не участвует в равных. – Skeeve