【问题标题】:Java Comparable to Instance or StringJava 类比实例或字符串
【发布时间】:2013-02-25 19:38:57
【问题描述】:

我正在尝试创建一个可以与同一类的实例或String 进行比较的类。

例如,考虑以下情况:

public class Record implements Comparable<Record> {
    public String name;

    public Record(String name) {
        this.name = name;
    }

    public int compareTo(Record o) {
        return name.compareTo(o.name);
    }
}

然后我将其放入ArrayList 中,如下所示:

ArrayList<Record> records = new ArrayList<Record>();
records.add(new Record("3"));
records.add(new Record("1"));
records.add(new Record("2"));

如果我对它们进行排序,它们就会正确排序:

Collections.sort(records);

但是,我不希望能够通过基于字符串的二进制搜索来获取记录。例如:

int index = Collections.binarySearch(records, "3");

问题是没有compareTo 方法以String 作为参数,我不确定如何实现它。

我试过了:

public class Record implements Comparable<Record>, Comparable<String> {
    public String name;

    public Record(String name) {
        this.name = name;
    }

    public int compareTo(Record o) {
        return name.compareTo(o.name);
    }

    public int compareTo(String o) {
        return name.compareTo(o);
    }
}

但是,当然,您不能多次使用不同的参数实现同一个接口。

所以,我正在寻找一种方法来执行上述操作。我已经查看了以下先前的答案,但还没有找到一个真正充分回答这个问题的答案。至少,如果是这样,我不明白。

基本上,我想做的是以下几点:

public int compare(Record r, String s) {
    return r.name.compareTo(s);
}

据我所知,如果不实现某种通用接口或超类,就无法比较不同类型的对象。我真的没有String 的选项。

如果可能的话,有人可以告诉我如何做到这一点吗?谢谢。

更新 我意识到我可以做到以下几点:

Collections.binarySearch(records, new Record("3"));

但是,这不是我所追求的。谢谢。

【问题讨论】:

  • 在 Java 中,您总是有一个共同的超类,Object
  • @PatriciaShanahan 如果我使用Comparable&lt;Object&gt;,那是否允许与StringRecord 以外的对象进行比较?
  • int包含在总是列表中吗?
  • @crush 如果您不喜欢该类型,可以在运行时抛出 ClassCastException。
  • @skuntsel 我的意思是在上下文中可能会显示为 Comparable 的泛型类型。

标签: java arraylist compare comparable compareto


【解决方案1】:

您可以在不使用类型限定的情况下实现 Comparable,并使用 instanceof 检查传入的 Object,并根据您收到的类型采取不同的行为。

【讨论】:

  • 如果不是预期的类型,我应该抛出异常吗?
  • 是的,根据 Comparable API,如果不是预期类型,则抛出 ClassCastException
【解决方案2】:

你不能那样做。 来自 javadoc

从 compareTo 的契约可以立即得出,商是 C 上的等价关系 并且 String 的 compareTo 永远不会为您的 Record 返回 true。

您可以做的是创建比较字符串和记录的比较器。不用泛型就可以了。

【讨论】:

  • 也来自 javadoc:It is strongly recommended (though not required) that natural orderings be consistent with equals.
【解决方案3】:

您可以尝试下一个获取排序集合中的索引:

class Record implements Comparable<String> {

    public String name;

    public Record(String name) {
        this.name = name;
    }

    @Override
    public int compareTo(String o) {
        return name.compareTo(o);
    }

}

还有:

public static void main(String[] args) {

    ArrayList<Record> records = new ArrayList<Record>();
    records.add(new Record("3"));
    records.add(new Record("1"));
    records.add(new Record("2"));

    Collections.sort(records, new Comparator<Record>() {
        @Override
        public int compare(Record a, Record b) {
            return a.name.compareTo(b.name);
        }
    });

    int index = Collections.binarySearch(records, "3");
    System.out.println(index); // 2

}

【讨论】:

  • 因此,我没有将其设为Comparable&lt;Record&gt;,而是仅将其设为Comparable&lt;String&gt;,而不定义自定义Comparator。这不是一个坏主意。我想我可以通过在我的 Record 类中将 new Comparator&lt;Record&gt;() {} 封装在 public Comparator&lt;Record&gt; getComparator() {} 方法中来更进一步。
【解决方案4】:

定义接口 ComparableToString 并实现它有问题吗?它的 compareTo 方法可以将调用者限制为 String。无需 instanceof,无需强制转换。

    public class Record implements Comparable<Record>, ComparableToString
    {
        public String name;

        public Record(String name)
        {
            this.name = name;
        }

        public int compareTo(Record o)
        {
            return name.compareTo(o.name);
        }

        public int compareTo(String o)
        {
            return name.compareTo(o);
        }
    }
    interface ComparableToString
    {
        public int compareTo(String s);
    }

【讨论】:

  • 你能举例说明你的意思吗?
  • Collections.binarySearch(records, "3"); 不适用于此示例。我已经试过了。我收到错误:The method binarySearch(List&lt;? extends Comparable&lt;? super T&gt;&gt;, T) in the type Collections is not applicable for the arguments (ArrayList&lt;Record&gt;, String)
  • 是的,这不适用于您的 extended 问题——对于您原来的“我正在尝试创建一个可以与相同的类,或字符串。”,没问题。但是您还希望将生成的类提供给将使用 Comparable 接口的东西,而这将无法处理。
猜你喜欢
  • 2021-04-10
  • 2017-10-22
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多