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

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

  •  07-10-2022
  •  | 
  •  

Pergunta

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).

Foi útil?

Solução

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.

Outras dicas

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!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top