2011-08-05 34 views
1

以下是一些示例代碼...我似乎總是得到一個ClassCastException ...有人指出我做錯了什麼?向TreeSet添加HashMap值時出錯

package com.query; 

    import java.util.ArrayList; 
    import java.util.Collection; 
    import java.util.HashMap; 
    import java.util.Map; 
    import java.util.Set; 
    import java.util.TreeSet; 

    import org.junit.Test; 

    import com.google.common.collect.Sets; 


    public class ClassCastExceptionTest { 

     @Test 
     public void test() { 

      A<SomeType> a1 = new A<SomeType>(1); 
      A<SomeType> a2 = new A<SomeType>(2); 
      A<SomeType> a3 = new A<SomeType>(3); 

      Map<String, A<SomeType>> map = new HashMap<String, A<SomeType>>(); 
      map.put("A1", a1); 
      map.put("A2", a2); 
      map.put("A3", a3); 

      Collection<A<SomeType>> coll = map.values(); 

      Set<A<SomeType>> set = Sets.newTreeSet(coll); 

      System.out.println("Done."); 

      //EXCEPTION... 
      //com.query.ClassCastExceptionTest$A cannot be cast to 
      //com.query.ClassCastExceptionTest$BaseType 
     } 

     private class A<T extends BaseType> extends Base<T> { 

      public A(int i) { 
       super(i); 
      } 
     } 

     private class Base<T extends BaseType> implements Comparable<T> { 

      private Integer id; 

      public Base(int id) { 
       this.id = id; 
      } 

      /** 
      * @return the id 
      */ 
      public Integer getId() { 
       return id; 
      } 

      /** 
      * @param id the id to set 
      */ 
      @SuppressWarnings("unused") 
      public void setId(int id) { 
       this.id = id; 
      } 

      @Override 
      public int compareTo(T o) { 
       return getId().compareTo(o.getId()); 
      } 
     } 

     private class SomeType extends BaseType { 

      @Override 
      public Integer getId() { 
       return 0; 
      } 

      @Override 
      public int compareTo(BaseType o) { 
       return this.getId().compareTo(o.getId()); 
      }  
     } 

     private abstract class BaseType implements Comparable<BaseType> { 

      public abstract Integer getId(); 
     } 

    } 

回答

2

爲了被添加到TreeSet(自然排序)一類應該與自身相媲美:

private class Base<T extends BaseType> implements Comparable<Base> { ... } 

,而在你的情況Base是比得上T

private class Base<T extends BaseType> implements Comparable<T> { ... } 
+2

謝謝axtavt ...更改爲...'私人類Base 實現可比較> {...}'並解決了這個問題。 – Ash

0

TreeSet使用對象compareTo方法進行排序。因此,在將第二個A實例添加到TreeSet時,會將A#compareTo與其他A實例一起作爲參數進行調用,但由於此方法期望BaseType(或BaseType的子類)作爲參數,因此會拋出ClassCastException。