В поисках элегантного решения задался вопросом: Каа преобразовать список объектов в массив с подсчетом количества повторений. Т.е если на входе есть
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
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
существуют ли эффективные образовательные курсы по распределенным вычислениямна java
Использую связку jpa/hibernate, нужно достать из таблицы сущности и представить их в отсортированном видеКак предпочтительнее и быстрее это сделать?...