Remove multiple duplicate items in a list
I am using java objects like this:
public class GeoName {
private String country;
private String city;
private float lat;
private float lon;
}
I am getting a list of GeoName and I would like to remove the duplicate cities in the same country that are in the list as much as possible. I mean if I get the following list:
Madrid, Spain, ... London, England, ... Madrid, Mexico, ... London, England, ... Paris, France, ... Madrid, Spain, ...
I would like to remove duplicate items (city + country) until the list is like this:
Madrid, Spain, ... London, England, ... Madrid, Mexico, ... Paris, France, ...
I'm working on it, but I don't know how to do it!
Any idea please?
Thank!
PS: I cannot use the Set collection because I found the city name that is repeated in the country with different latitude and longitude (this is strange, but they exist). So it will not be the same on Set
source to share
You can implement hashCode () and equals () for GeoName
that only consider country and city.
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GeoName geoName = (GeoName) o;
if (!country.equals(geoName.country))
return false;
return city.equals(geoName.city);
}
@Override
public int hashCode() {
int result = country.hashCode();
result = 31 * result + city.hashCode();
return result;
}
Then you can use HashSet()
to enter all GeoNames. Duplicates will be sorted automatically and efficiently.
List<GeoName> myInputList = ...;
Set<GeoName> geoSet = new HashSet<>(myInputList);
source to share
To remove a duplicate record from a collection of user data (such as GeoName), implement the equals () and hashcode () methods.
Then add data to the set to remove the duplicate record.
Implement equals () and hashcode () according to your logic to identify duplicate data.
This should do it:
I create my class with modified .equals method and then check if 2 test instances of that class are the same using said .equals method.
class GeoName {
private String country;
private String city;
public GeoName(String country, String city) {
this.country = country;
this.city = city;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final GeoName other = (GeoName) obj;
if (!Objects.equals(this.country, other.country)) {
return false;
}
if (!Objects.equals(this.city, other.city)) {
return false;
}
return true;
}
}
Test class:
public class Cities {
public static void main(String[] args) {
// ArrayList<GeoName> geos = new ArrayList<>();
GeoName test = new GeoName("Madrid", "Spain");
GeoName test1 = new GeoName("Madrid", "Mexico");
if (test.equals(test)) {
System.out.println("True 1");
}
if (test.equals(test1)) {
System.out.println("True 2");
}
}
}
Output:
True 1
Then you go through the array and check all of them, and if it doesn't exist, you add it to the array, I'll leave that to you.
source to share
This is a complete example:
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class GeoName {
private String country, city;
private float lat, lon;
public GeoName(String country, String city, float lat, float lon){
this.country = country;
this.city = city;
this.lat = lat;
this.lon = lon;
}
@Override
public boolean equals(Object other){
if(other==null) return false;
if(other instanceof GeoName){
return ((GeoName)other).city.equals(this.city) &&
((GeoName)other).country.equals(this.country);
}
return false;
}
@Override
public String toString(){
return city + ", "+ country +
", " + lat +", " + lon;
}
@Override
public int hashCode(){
return Objects.hash(country, city);
}
// to test
public static void main(String[] args) {
List<GeoName> list = new ArrayList<>();
list.add(new GeoName("Madrid", "Spain",1.0f, 2.0f));
list.add(new GeoName("England", "London",3.0f, 4.0f));
list.add(new GeoName("England", "London",3.0f, 4.0f));
list.add(new GeoName("France", "Paris",7.0f, 9.0f));
list.add(new GeoName("Mexico", "Madrid",9.0f, 10.0f));
Set<GeoName> set = new HashSet<>(list);
for(GeoName geoName : set){
System.out.println(geoName);
}
}
}
Output:
London, England, 3.0, 4.0
Madrid, Mexico, 9.0, 10.0
Paris, France, 7.0, 9.0
Spain, Madrid, 1.0, 2.0
source to share