2011-10-30 45 views
2

我尝试了下面的简单测试。使用与indexOf类似的工具

class ZiggyTest{ 
    public static void main(String[] args){ 

     List<Cities> cities3 = new ArrayList<Cities>(); 
     Cities city = new Cities("London"); 

     cities3.add(new Cities("Manchester")); 
     cities3.add(new Cities("Glasgow")); 
     cities3.add(new Cities("Leeds")); 
     cities3.add(city); 
     cities3.add(new Cities("Leicester")); 
     cities3.add(new Cities("Croydon")); 
     cities3.add(new Cities("Watford")); 

     System.out.println("IndexOf(new Croydon) " 
         + cities3.indexOf(new Cities("Croydon"))); 
     System.out.println("IndexOf(city) " 
         + cities3.indexOf(city)); 
    } 
} 

class Cities implements Comparable<Cities>{ 
    String title; 

    Cities(String aTitle){ 
     this.title = aTitle; 
    } 

    public String getTitle(){ 
     return title; 
    } 

    public String toString(){ 
     return "Title : " + title; 
    } 

    public int compareTo(Cities c){ 
     return title.compareTo(c.getTitle()); 
    } 
} 

上述测试的输出是

IndexOf(new Croydon) -1 
IndexOf(city) 3 

我明白为什么第二行制备3,但我不理解为什么第一行没有找到新的具有标题=”克罗伊登”。

的API描述为一个

返回指定元件的第一次出现的索引在此列表中,或-1,如果该列表不包含该元素的indexOf方法。更正式地说,如果没有这样的索引,则返回最低索引i,即(o==null ? get(i)==null : o.equals(get(i)))-1

我认为API是说如果对象为null,那么它将返回列表中第一个出现空对象的索引。如果它不为null,它将返回传入的对象等于方法返回true的第一次出现的索引。

不应该创建为cities3.indexOf(new Cities("Croydon")的对象是否等于之前添加的对象cities3.add(new Cities("Croydon"));

+2

也许这是Java想忘记克罗伊登的愿望?真的不能指责它......(请参阅mishadoff对于真正的解决方案的回答,但作为一个老惠特吉,我无法抗拒......) –

+0

哈哈很有趣:) – ziggy

回答

9

重新定义equals而不是compareTo如果您要执行搜索操作。

默认情况下,indexOf使用equals操作进行比较,在您的情况下,equals不重新定义,这意味着您通过引用进行比较。当你用相同的名字创建新的City对象时,你有另一个对象的引用,所以equals返回false。

P.S.如果您使用的是描述城市的对象,那么城市的名称不适用于城市

+1

确实。定义一个'equals()'覆盖将解决'indexOf()'问题。 @ziggy:请注意,您不能覆盖'equals()'而不覆盖'hashCode()'。如果你没有这样做,那么“违反equals()”的对象必须具有相同的'hashCode()'“要求。 – Barend

+0

谢谢。 compareTo()会在什么情况下有用呢?我认为它会工作,因为字符串不会覆盖equals()。 – ziggy

+0

compareTo()当您不按自然顺序执行排序操作时,或者在使用SortedSet时有用。字符串覆盖等于,但你的班级城市不是。 – mishadoff