从列表中删除一些重复的项目

3

我正在使用类似于以下的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集合,因为我发现一个城市的名称在一个具有不同纬度和经度的国家中重复出现(很奇怪,但它们确实存在)。因此,在Set中它不会完全相等。


你好,你目前尝试了什么? - Raquel Guimarães
1
使用Set而不是数组。 - victor
我昨天回答了一个类似的问题,但是被删除了 T_T - Daedric
无法设置,因为我发现同一国家的某些城市具有不同的纬度和经度(lat,lon属性)。 - Ommadawn
你能使用哈希集合,并定义该对象的哈希码仅使用国家和城市名称吗? - user1762507
可以创建一个 Set 集合;你只需要重写 Object#equals 方法,不考虑经纬度即可。 - Jacob G.
4个回答

2

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

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

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


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() 将所有GeoNames放入其中。重复项将被自动高效地排序。

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

1
我来翻译一下这段内容:

这应该可以做到:

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

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

你需要遍历数组并检查其中的所有元素,如果不存在,则将其添加到数组中,具体实现留给你自己。

你不应该这样做。你将不得不使用equals方法逐个比较每个实例,导致复杂度为O(n^2)。使用HashSet更通用、更清晰,并且运行时间为O(n) - A1m
这对小规模来说还可以。 - Daedric

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接