What causes the ClassCastException: java.util.TreeSet cannot be cast to java.lang.Comparable?

StackOverflow https://stackoverflow.com/questions/21592485

  •  07-10-2022
  •  | 
  •  

문제

So I'm trying to move all Strings of a certain length from a Collection of Strings (could either be a Set or a List) to a TreeMap and setting a Set of the characters in each String as the key for that String but the line map.put(keyRinger(word), word); throws java.lang.ClassCastException: java.util.TreeSet cannot be cast to java.lang.Comparable

Map<Set<Character>, String> map = new TreeMap<Set<Character>, String>();
for (String words : words)    {
  if (word.length() == length)  {
    map.put(keyRinger(word), word);
  }
}

This is the keyRing method in case you're curious.

private Set<Character> keyRinger(String current)  { 
  Set<Character> keyRing = new TreeSet<Character>();
  for (int i = 0; i < current.length(); i++)   {
    char key = current.charAt(i); 
    keyRing.add(key);
  }
  return keyRing;
}

So my question is what can I do to avoid this? I've read I need a Comparator or to implement Comparable but I don't know how to do that, and I think there might be a simpler solution (although perhaps not as efficient).

도움이 되었습니까?

해결책

You'll notice the javadoc of TreeMap states

The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.

So if you don't provide a Comparator, it will use natural ordering. What is natural ordering? The javadoc of the Comparable interface states

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.

So your key element in your TreeMap must implement Comparable. You are trying to use TreeSet instances as keys in your TreeMap. TreeSet does not implement Comparable.

You get a ClassCastException when TreeMap tries to cast the key to a Comparable reference in order to use its compareTo method.

To correct this issue, you should create a TreeMap by providing your own custom Comparator for comparing Set<Character> instances.

다른 팁

Here's how you can create the comparator class:

public class NutrientByInclusionOrderComparator  implements Comparator<ProductNutrient>{

@Override
public int compare(ProductNutrient o1, ProductNutrient o2) {
    if (o1 == null && o2 == null){
        return 0;
    }
    else if (o1 == null){
        return -1;
    }
    else if (o2 == null){
        return 1;
    }
    else if ( o1.getNumOrder().compareTo(o2.getNumOrder()) == 0) {
        return o1.getDtInclusion().compareTo(o2.getDtInclusion());
    } else {
        return o1.getNumOrder().compareTo(o2.getNumOrder());
    }
}

}

And then, when creating your TreeSet:

Set<ProductNutrient> productNutrients = new TreeSet<ProductNutrient>(new NutrientByInclusionOrderComparator());

Cheers!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top