将几乎相同的对象排序到列表中

时间:2015-12-01 12:56:24

标签: java sorting arraylist

如果我有一个名为 Private Sub Macro1() ' ' Macro1 Macro ' ' Dim Lastrow As Long Lastrow = Sheet2.Cells(Rows.Count, 7).End(xlUp).Row Application.CutCopyMode = False ActiveWorkbook.Worksheets("Contacts").Sort.SortFields.Clear ActiveWorkbook.Worksheets("Contacts").Sort.SortFields.Add Key:=Range("G1"), _ SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal With ActiveWorkbook.Worksheets("Contacts").Sort .SetRange Range("A2:AJ2106") .Header = xlNo .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Range("A1").Select End Sub 的对象,它看起来与此类似:

Dog

我还有一个看起来像这样的其他对象:

public class Dog {
  String type;
  String furColor;
  String country;
  String name;
}

现在,我希望所有在同一个public class SimilarDogs { ArrayList<Dog> similarDogList; } ArrayList中具有相同typefurColorcountry的狗,但狗只能在一个{ {1}}。我怎么能做到这一点?

我想到了Dog ArrayList的双重迭代

  1. 在数组

  2. 中取第一......第二......第三[...]只狗
  3. 创建一个新的类似狗列表

  4. 再次通过狗列表重复

  5. 将所有类似的狗添加到列表中。

  6. 这个问题是,它会为整个列表中的每只狗创建一个similarDogList,但我希望similarDogList中没有重复的狗。{/ p> 编辑:我&#39;确实像这样解决了这个问题。

    similarDogList

3 个答案:

答案 0 :(得分:3)

使用多个地图(Map List s)为每个&#34;类别&#34;提供Dog s列表狗您需要指定一个&#34;代理人&#34;每类类似的狗:

解决方案1 ​​

  • 创建具有定义它的所有属性的类DogCategory(例如typefurColorcountry
    • 这个需要覆盖equals()hashCode(),如果所有属性相等则使实例相等
  • 创建一个方法,为每个DogCategory分配Dog
    • 这可能是Dogpublic DogCateogry getCategory() { ... }
    • 的一种方法
  • 创建Map<DogCategory, List<Dog>>以将狗存放在各自的类别中
  • 对于每只狗,获取他的DogCategory,查询地图以获取相应的列表并将狗添加到列表中

解决方案2

  • 当且仅当两个给定的Comparator<Dog>具有相关属性(即0Dog,{{}时,创建一个返回type的{​​{1}} 1}})相等(furColor可以是任何东西)
  • 使用以country作为排序/等式定义的地图
    • name就是这样一个地图实现,所以你可以使用
      Comparator
  • 对于每只狗,查询地图以查找相应的列表并将狗添加到列表中

解决方案3

  • 按解决方案1 ​​
  • 创建TreeMap
  • 重构您的TreeMap<Dog, List<Dog>>DogCategoryDog而不是所有属性
  • 创建DogCategory dogCategory并将其用作解决方案1 ​​

- 这可能是也可能不适合重构,您需要根据您的实际情况和域模型来决定。

答案 1 :(得分:1)

  

高级概述,使用HashSet删除重复。去除   在我们的自定义类(这里,Dog)上重复,必须要有   override,hashcode()&amp; equals()用于删除重复。

你可以尝试一下,

class Dog {

    String type;
    String furColor;
    String country;
    String name;

    Dog(String type, String furColor, String country, String name){
        this.type = type;
        this.furColor = furColor;
        this.country = country;
        this.name = name;
    }

    @Override
    public int hashCode() {
        if(name != null){
            return name.length();
        }
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        Dog d = (Dog)obj;
        if(d.name.equals(this.name)){
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
        return this.type + " :" + this.furColor + " :" +this.country + " :" +this.name;
    }

}

public class SetExample {


    public static void main(String[] args) {

        HashSet<Dog> similarDogList = new HashSet<Dog>();
        similarDogList.add(new Dog("A", "Red", "USA", "ABC"));
        similarDogList.add(new Dog("A", "Red", "USA", "XYZ"));
        similarDogList.add(new Dog("A", "Red", "USA", "PQR"));
        similarDogList.add(new Dog("A", "Red", "USA", "ABC"));

        for(Dog d : similarDogList){
            System.out.println(d);
        }

    }

}

输出

A :Red :USA :PQR
A :Red :USA :XYZ
A :Red :USA :ABC

答案 2 :(得分:0)

好的,如果我正确地阅读了你的问题,你想要有分享类型,毛皮颜色和国家的狗的列表吗?在每个列表中的含义,所有狗都具有相同的类型,毛发颜色和国家可能有不同的名称。

您可以创建从String到ArrayList的Map。由于那些对于所有狗应该相同的3个属性已经是字符串,您可以使用它们来生成地图键。现在,您只需计算每只狗的钥匙,以便找到正确的清单。

算法:

for(Dog dog : dogs) {
   String key = dog.type + dog.furColor + dog.country;
   ArrayList<Dog> dogList = map.get(key);
   if(dogList == null) {
      dogList = new ArrayList<Dog>();
      map.put(key, dogList);     
   }
   dogList.add(dog);
}
编辑:正如评论中所指出的那样,像连接字符串这样简单的密钥生成方法并不总是有效,所以最好采用更干净的方法来使用Comparators。