簡體   English   中英

java:Comparator和Treeset刪除重復項

[英]java: Comparator and Treeset to remove duplicates

我有一個像這樣的java類

public class A {

    private String field1;
    private String field2;

    // getters, setters but no equals and hashcode
}

和這個類的對象列表,我想從這個列表中刪除所有具有相同field1或相同field2的重復元素,所以我有2個比較器

public class Comparator1 implements Comparator<A> {
    public int compare(A o1, A o2) {

        return o1.getField1().compareToIgnoreCase( o2.getField1() );
    }
}

public class Comparator2 implements Comparator<A> {
    public int compare(A o1, A o2) {

        return o1.getField2().compareToIgnoreCase(o2.getField2());
    }
}

所以要做我使用treeset的任務

TreeSet<A> ts1 = new TreeSet<A>(new Comparator1())
ts1.addAll(list)

TreeSet<A> ts2 = new TreeSet<A>(new Comparator2())
ts2.addAll(ts1)

list.clear()
list.addAll(ts2)

但是我怎么能只使用一個比較器和一個樹集來做同樣的事情呢?

謝謝您的幫助

更新:

謝謝所有的答案,但閱讀后我不知道這是否是解決實際問題的正確方法。

在我的實際案例中,field1就像一個電話號碼,而field2就像一個名字。 所以我不想多次調用相同的電話號碼(這是第一個刪除重復的樹集),我不想多次調用相同的名稱(第二個樹集來刪除重復項)

你可以修改類,但我想知道這種方法是否可以解決真正的問題。

如果這種方法是正確的,從你的問題,我看到,如果不修改類,就不可能只使用一個比較器

謝謝

您不能同時使用一個比較器按兩個條件進行排序,因此在您的情況下,沒有比兩個TreeSet更好的方法。 當然,您可以將它們包裝在一個數據結構中。

(或者你可以使用兩個HashMaps,每個都有一個字符串作為鍵 - 平均速度會更快,但編程起來會更復雜。)

你不能,而且我不清楚你要做的事情是明確定義的。

您是否知道您當前的方法取決於添加元素的順序以及是否首先檢查field1或field2是否為重復項? 想象一下,你有A類的這些對象:

A ab = new A("a", "b");
A cb = new A("c", "b");
A cd = new A("c", "d");

檢查field1首先給出結果[ab][ab, cd] ,具體取決於添加的順序。

檢查field2首先給出結果[cb][ab, cd] ,具體取決於添加的順序。

這是非常奇怪的行為。 這是你的意圖嗎? 我不認為在一般情況下使用單個TreeSet和Comparator重現這一點。

如果您打算進行兩個級別的排序(第一個:PhoneNumber和第二個:Name),那么您可以使用以下代碼,其中將對兩個字段(field1和field2)執行重復檢查。 由於我們已經在兩個字段中使用了compareTo ,因此不需要使用equalshashcode 但是使用hashcodeequals總是好的做法。

public class A implements Comparable<A> {

private String field1;
private String field2;

public A(String number, String name) {
    this.field1 = number;
    this.field2 = name;
}

// First level sorting will be done by field1. 
// If field1 is equal then second level sorting will be done on field2
@Override
public int compareTo(A o) {
    int compareTo = field1.compareTo(o.getNumber());
    if(compareTo==0){
        return field2.compareTo(o.getName());
    }
    return compareTo;
}

public String getNumber() {
    return field1;
}

public String getName() {
    return field2;
}

}

 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.Comparator;
 import java.util.List;

 public class RemoveDuplicate {

public static void main(String[] args) {
    Set<Student> set = new TreeSet<Student>();
    List<Student> students = Arrays.asList(new Student("Student1", "1005"), new Student("Student2", "1004"),
            new Student("Student3", "1003"), new Student("Student6", "1002"), new Student("Student5", "1001"),
            new Student("Student6", "1000"));

    // Sorting Using Lambda

    students.sort(new Comparator<Student>() {

        @Override
        public int compare(Student s1, Student s2) {

            return s1.getId().compareTo(s2.getId());
        }

    });

    System.out.println(students);
    set.addAll(students);

    System.out.println("\n***** After removing duplicates *******\n");

    final ArrayList<Student> newList = new ArrayList<Student>(set);

    /** Printing original list **/
    System.out.println(newList);
}

  }

 class Student implements Comparable<Student> {
private String name;
private String id;

public Student(String name, String id) {
    this.name = name;
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

@Override
public String toString() {
    return "\n" + "Name=" + name + "   Id=" + id;
}

@Override
public int compareTo(Student o1) {
    if (o1.getName().equalsIgnoreCase(this.name)) {
        return 0;
    }
    return 1;
    }

// public static Comparator<Student> StudentIdComparator = (Student
// s1,Student s2) -> s1.getId().compareTo(s2.getId());
   }
public static <A extends Comparable<?>>  TreeSet<A> getTreeSet(Collection<A> list){
    TreeSet<A> result = new TreeSet<A>();
    HashSet<A> unique = new HashSet<A>();
    unique.addAll(list);
    result.addAll(unique);
    return result;
}

將項添加到hashset以使其唯一的通用函數,然后將它們放到TreeSet中進行排序。 你可以使用它: TreeSet<A> ts1 = getTreeSet(list);

這種方法適用於固定列表。

@BalusC不,這是假設的

public class A implements Comparable<A> {

    private String field1;
    private String field2;

    @Override
    public int compareTo(A o) {
        // No null checks, because it's illegal anyways.
        int tmp = 0;
        if ((tmp = field1.compareToIgnoreCase(o.field1)) != 0)
            return tmp;
        if ((tmp = field2.compareToIgnoreCase(o.field2)) != 0)
            return tmp;
        return tmp;
    }
    // getters, setters but no equals and hashcode
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM