В поисках элегантного решения задался вопросом: Каа преобразовать список объектов в массив с подсчетом количества повторений. Т.е если на входе есть
class Example {
private String s;
public Example(String s) {
this.s = s;
}
@Override
public boolean equals(Object obj) {
// для иллюстрации
if (obj instanceof Example) {
return this.s.equals(((Example) obj).s);
}
return false;
}
}
List<Example> list = Arrays.asList(new Example("example1"), new Example("example2"), new Example("example1"), new Example("example3"));
Требуется получить Map содержащий:
Key Value
-------------------------------------------
obj equals new Example("example1") 2
obj equals new Example("example2") 1
obj equals new Example("example3") 1
Интересует решение именно для абстрактного класса где экземпляры будут сравниваться основывясь на результате equal() и используя stream API. Для частного случая со строками или при группировке по полю проблем нет.
Для свертки по строковому полю можно поступить вот так:
Map<String, Long> messagesMap =
this.list.stream().collect(Collectors.groupingBy(e -> e.getS(), Collectors.counting()));
В вашем примере ничего не мешает вам группировать не по полю, а по объекту, то есть вот так:
Map<Example, Long> messagesMap =
list.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));
Не работает это потому, что используемый Collector в качестве accumulator использует HashMap, который сравнивает объекты сперва по hashCode, а не по equals.
Я думаю, вам следует реализовать методы hashCode для использования HashMap и compareTo для использования SortedMap.
Пример с реализованным hashCode:
@Test
public void ttt(){
List<Example> list = Arrays.asList(new Example("example1"), new Example("example2"), new Example("example1"), new Example("example3"));
Map<Example, Long> messagesMap = list.stream()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
messagesMap.entrySet().stream().forEach(e -> System.out.println(e.getKey() + " : " + e.getValue()));
}
class Example {
private String s;
public Example(String s) {
this.s = s;
}
public String getS(){
return s;
}
@Override
public boolean equals(Object obj) {
// для иллюстрации
if (obj instanceof Example) {
return this.s.equals(((Example) obj).s);
}
return false;
}
@Override
public int hashCode() {
return s.hashCode();
}
}
$Example@737d1c09 : 1
$Example@737d1c08 : 1
$Example@737d1c07 : 2
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости