【问题标题】:Java Comparable, mutliple/different implenetations of compareTo() methodJava Comparable,多个/不同的 compareTo() 方法实现
【发布时间】:2011-10-06 23:17:54
【问题描述】:

我有这门课:

public class Sample implements Comparable<Sample> {
public String a;
public String b;
public String c;

public int compareTo (Sample sampleToCompare) {
int compResult = this.a.compareTo(sampleToCompare.a);
      return (compResult != 0 ? compResult : 
                   this.b.compareTo(sampleToCompare.b));    
    }
}

我希望compareTo() 使用不同的类属性进行行为或排序,具体取决于是否设置了标志。

所以,如果flag == 1 我希望compareTo() 使用属性c,否则是flag == 0,无论当前在方法中。

换句话说,以不同的方式对同一类进行排序。

我不确定如何实现这一点。请帮忙。

另外,如果我需要更多信息,请告诉我。

【问题讨论】:

    标签: java overloading compareto


    【解决方案1】:

    如果你想实现不同类型的排序,你应该看看java.util.Comparator接口。

    public class SampleComparatorA implement Comparator<Sample> {
    
        public int compare(Sample a, Sample b) {
            // Your sorting
        }
    }
    

    并使用 java.util.Collections.sort() 方法和 Comparator 作为第二个参数。

    Collections.sort(aSampleList, new SampleComparatorA());
    

    【讨论】:

    • 有一个相关的例子here
    【解决方案2】:

    怎么样:

    public int compareTo(Sample sampleToCompare) {
        if (flag == 1) {
            return this.c.compareTo(sampleToCompare.c);
        }
        if (flag == 0) {
            // current stuff
        }
        ...
    }
    

    不过,这不是一种非常面向对象的方式。可能您应该有两个不同的比较器和一种根据您的“标志”值选择它们的方法。比如:

    class Sample {
        private String a;
        private String b;
        private String c;
    }
    
    class ASampleComparator implements Comparator<Sample> {
        public int compare(Sample o1, Sample o2) {
            return o1.a.compareTo(o2.a);
        }
    }
    
    class BSampleComparator implements Comparator<Sample> {
        public int compare(Sample o1, Sample o2) {
            return o1.b.compareTo(o2.b);
        }
    }
    
    class CSampleComparator implements Comparator<Sample> {
        public int compare(Sample o1, Sample o2) {
            return o1.c.compareTo(o2.c);
        }
    }
    
    public Comparator<Sample> pickComparator(int flag) {
        switch (flag) {
            case 0:
                return new ASampleComparator();
            case 1:
                return new BSampleComparator();
            case 2:
                return new CSampleComparator();
            default:
                throw new IllegalArgumentException("Bad flag value: " + flag);
        }
    }
    

    【讨论】:

    • 你能给我一个比较器的例子吗?知道 a,b,c 是字符串
    • @Sabertooth:使用比较器示例更新答案
    【解决方案3】:

    您应该将标志设为静态,以便比较一致(如 Effective Java, item 12 中所述),否则,您可能会得到 a.compareTo(b) 返回 a &gt; b,但 b.compareTo(a) 返回 b &gt; a。所以我能想到的最简单的实现是:

    public class Sample implements Comparable<Sample> {
    public String a;
    public String b;
    public String c;
    public static boolean my_flag = false;
    
    public int compareTo (Sample sampleToCompare) {
        if (flag) {
            return this.c.compareTo(sampleToCompare.c);
        }
        int compResult = this.a.compareTo(sampleToCompare.a);
          return (compResult != 0 ? compResult : 
                       this.b.compareTo(sampleToCompare.b));    
        }
    }
    

    【讨论】:

    • 我不购买static 部分。 final:是的。 static:没必要。
    • @Jason - 如果它可能会改变,你为什么要把它定为最终版本?为什么不是静态的?我真的很想要一个答案,因为我可能会遗漏一些东西。
    • #MByD:我的错,我在考虑Comparator,而不是Comparable,你可能想要不同的。至于final,您真的不想将对象作为键粘贴在TreeMap 中并在中途更改规则。