Ошибка при добавлении значений HashMap в TreeSet - PullRequest
1 голос
/ 05 августа 2011

Вот пример кода ... Мне всегда кажется, что я получаю ClassCastException ... кто-нибудь указывает, что я делаю неправильно?

    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 ]

2 голосов
/ 05 августа 2011

Чтобы быть добавленным в TreeSet (с естественным упорядочением), класс должен быть сопоставим с самим собой:

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

, тогда как в вашем случае Base сопоставим с T:

private class Base<T extends BaseType> implements Comparable<T> { ... }
0 голосов
/ 05 августа 2011

TreeSet использует метод CompareTo объектов для сортировки.Поэтому при добавлении второго экземпляра A в TreeSet вызывается A # compareTo с другим экземпляром A в качестве аргумента, но поскольку этот метод ожидает BaseType (или подкласс BaseType) в качестве аргумента, создается исключение ClassCastException.

...