I have the following issue:
Goal: I want literally all of instances of "City" that have duplicates based on "name".
Restraints: I need to use streams.
Errors: There are no errors.
Description:
I have a list of instances of the class "City".
The goal is to have a list with literaly all of the duplicates found based on "name", and not just one, using stream.
I have tried to research answers to my issue, but all answers found, only explain how add the element that is being repeated once, and not twice or three times if situation calls for it.
Research material that I found:
Goal again: With the list displayed beneath, a new list that would be created to take in the duplicates, would have inside the instace of "Lisboa" 3x, the instace of "Braga" 3x and the instace of "Guarda" 2x, this is because these are the repeated elements based on the name.
The list would contain instances of type "City", that have the names repeated.
Main:
public class Main {
public static void main(String[] args) {
List<City> portugalCities = List.of(
new City("Lisboa", "Estremadura", 2275591),
new City("Lisboa", "Estremadura", 2275591),
new City("Faro", "Algarve", 67650),
new City("Braga", "Minho", 193324),
new City("Braga", "Esposende", 193324),
new City("Braga", "Fafe", 193324),
new City("Alentejo", "Ribatejo", 704533),
new City("Viseu", "Beira Alta", 99561),
new City("Lisboa", "Alenquer", 2275591),
new City("Guarda", "Almeida", 143019),
new City("Guarda", "Aguiar da Beira", 143019)
);
}
}
City:
public class City {
private String name;
private String province;
private int population;
// ----- Properties
public City(String name, String province, int population) {
this.name = name;
this.province = province;
this.population = population;
}
// ----- Constructor
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProvince() {
return province;
}
public void setProvince(String district) {
this.province = district;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
// ----- Getter & Setters
@Override
public String toString() {
return String.format("|name: %s; district: %s; population: %s|", name, province, population);
}
// ----- toString
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
City city = (City) o;
return population == city.population && Objects.equals(name, city.name) && Objects.equals(province, city.province);
}
@Override
public int hashCode() {
return Objects.hash(name, province, population);
}
// ----- Equals & hashCode
}
First collect names and count them, then use that to filter out non-dupes:
Map<String, Long> freq = portugalCities.stream()
.map(City::getName)
.collect(groupingBy(n -> n, counting()));
List<City> dupes = portugalCities.stream()
.filter(c -> freq.get(c.getName()) > 1)
.collect(toList());
Then print them as you like:
dupes.forEach(System.out::println);