Java与实例或字符串类似

问题描述:

我试图创建一个类,可以将其与相同类的实例进行比较,也可以创建一个类到StringJava与实例或字符串类似

例如,请考虑以下几点:

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")); 

如果我再对它们进行排序,它们是正确排序:

​​

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

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我真的没有这个选择。

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

UPDATE 我知道我可以做到以下几点:

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

但是,这不是我后。谢谢。

+1

在Java中,你总是** **都有一个共同的超类,'Object' 。 – 2013-02-25 19:41:44

+0

@PatriciaShanahan如果我使用“可比较的”,是否不允许与除“String”或“Record”之外的对象进行比较? – crush 2013-02-25 19:42:34

+0

是int包含int那**始终**列表? – skuntsel 2013-02-25 19:44:26

您可以实现Comparable而不需要使用类型进行限定,并使用instanceof检查传入Object,并根据您接收的类型来执行不同的行为。

+0

如果它不是预期的类型,我应该抛出异常吗? – crush 2013-02-25 19:43:06

+1

是的,根据可比较的API,如果它不是预期的类型,抛出一个ClassCastException – 2013-02-25 19:44:02

定义接口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); 
    } 
+0

你能提供一个你的意思吗? – crush 2013-02-25 19:47:29

+0

'Collections.binarySearch(记录,“3”);'不适用于这个例子。我已经尝试过了。我收到错误:类型集合中的binarySearch(List >,T)方法不适用于参数(ArrayList ,String)' – crush 2013-02-25 19:52:02

+0

是的,这不适用于* extended *问题 - 为你的原始“我试图创建一个类,可以比较相同的类的实例,或字符串。”,它确定。但是你也想把结果类提供给将要使用Comparable接口的东西,而这不会处理它。 – arcy 2013-02-25 20:05:08

你不能那样做。 从javadoc中

It follows immediately from the contract for compareTo that the quotient is an equivalence relation on C and String's compareTo will never return true for your Record.

你可以做什么,是建立比较会比较字符串和记录。只是把它放在没有泛型的地方。

+0

同样来自javadoc:'强烈建议(尽管不要求)自然顺序与equals相等。“ – 2013-02-25 20:03:58

你可以尝试下为获得该指数的排序集合中:

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 

} 
+0

因此,我没有定义自定义的”比较器“,而是将其设置为”Comparable “,而不是将其设置为”Comparable “ 。这不是一个坏主意。我猜想,我可以通过在我的Record类的'public Comparator getComparator(){}'方法中封装新的Comparator (){}'来进一步实现。 – crush 2013-02-25 20:12:59