删除列表中的一些重复项

时间:2017-07-11 17:43:48

标签: java list collections unique items

我正在使用这样的java对象:

public class GeoName {
   private String country;
   private String city;
   private float lat;
   private float lon;
}

我收到了一份GeoName列表,我想删除列表中同一国家/地区的重复城市,尽可能高效。我的意思是,如果我收到以下列表:

Madrid, Spain, ...
London, England, ...
Madrid, Mexico, ...
London, England, ...
Paris, France, ...
Madrid, Spain, ...

我想删除重复的项目(城市+国家/地区),直到列表如下:

Madrid, Spain, ...
London, England, ...
Madrid, Mexico, ...
Paris, France, ...

我正在努力,但我不知道该怎么做!

请问,好吗?

谢谢!

PS:我不能使用Set系列,因为我发现一个城市的名称在一个纬度和经度不同的国家重复出现(它很奇怪,但它们存在)。所以它在集合

上不会是一个完全相同的项目

4 个答案:

答案 0 :(得分:2)

要从自定义数据集合中删除重复条目(例如GeoName),请实现equals()和hashcode()方法。

然后将数据添加到Set中以删除重复条目。

根据您的逻辑实现equals()和hashcode()以识别重复数据。

答案 1 :(得分:1)

您可以为仅考虑国家/地区和城市的GeoName实施hashCode()和equals()。

@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;
}

之后,您可以使用HashSet()将所有地理名称放入。重复项将自动有效地整理出来。

    List<GeoName> myInputList = ...;
    Set<GeoName> geoSet = new HashSet<>(myInputList);

答案 2 :(得分:1)

这应该这样做:

我使用修改后的.equals方法创建您的类,然后使用所述.equals方法检查该类的2个测试实例是否相同。

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;
    }
}

测试类:

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");
            }
    }
}

输出:

True 1

然后你会循环遍历数组并检查所有数组,如果它不存在,那么你把它添加到数组中,我把它留给你。

答案 3 :(得分:1)

这是一个完整的例子:

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);
        }          
    }    
}

<强>输出:

London, England, 3.0, 4.0
Madrid, Mexico, 9.0, 10.0
Paris, France, 7.0, 9.0
Spain, Madrid, 1.0, 2.0