1

I have created a TreeMap which is having arguments of type Set as both key value and the sets are also TreeSet so that the key and value pairs are always corresponding to each other.But I am getting an error as :

Exception in thread "main" java.lang.ClassCastException: java.util.TreeSet  cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1290)
at java.util.TreeMap.put(TreeMap.java:538)
at hello.Sam.main(Sam.java:49)`

Here is The code below:

package hello;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class Sam {

public static void main(String args[])
{
    Set<String> set=new TreeSet<String>();
    Set<String> set2=new TreeSet<String>();
    List<String> list=new ArrayList<String>();
    list.add("hello1");
    list.add("bye1");
    list.add("bye2");
    list.add("bye3");
    list.add("bye4");
    list.add("bye5");
    list.add("bye6");
    Map<Set<String>,Set<String>> map=new TreeMap<Set<String>,Set<String>>();

    set.add("set11");
    set.add("set12");
    set.add("set13");
    set.add("set14");
    set.add("set15");
    set.add("set16");
    set.add("set17");

    set2.add("set21");
    set2.add("set21");
    set2.add("set21");
    set2.add("set21");
    set2.add("set21");
    set2.add("set21");
    set2.add("set21");

    map.put(set,set2);
    System.out.println(map);
    }

}

But When I use Key Or value as String Like (String,Set) or (Set,String) it works fine.

Can I not have both the key and value as collection? or If yes how to use them??

Mandar Pandit
  • 2,171
  • 5
  • 36
  • 58
  • Possible duplicate of [Why does TreeSet throws ClassCastException](http://stackoverflow.com/questions/15943031/why-does-treeset-throws-classcastexception) – Mandar Pandit Nov 22 '16 at 06:07
  • what is role of 'List' in your code ? – PSabuwala Nov 22 '16 at 06:19
  • It sounds like an [XY Problem](http://xyproblem.info/). Why do you want to use a `Set` as a key in a `Map` ? What are you trying to achieve ? – Spotted Nov 22 '16 at 06:29
  • @Spotted I am just trying to use two sets as key and value pairs and also to make sure that both sets have same elements pointing to each other I have used TreeSet to keep them sorted. – Manish Anand Nov 22 '16 at 07:20

4 Answers4

0

TreeMap is a SortedMap. It will only accept keys that implements Comparable, or you can pass Comparator object in TreeMap's constructor during initialization.

All keys inserted into a sorted map must implement the Comparable interface (or be accepted by the specified comparator).

Furthermore, all such keys must be mutually comparable: k1.compareTo(k2) (or comparator.compare(k1, k2)) must not throw a ClassCastException for any keys k1 and k2 in the sorted map.

Attempts to violate this restriction will cause the offending method or constructor invocation to throw a ClassCastException.

If ordering is not important, you may use HashMap:

Map<Set<String>,Set<String>> map = new HashMap<Set<String>,Set<String>>();
0

The default constructors for TreeSet<K> and TreeMap<K,V> require K to implement Comparable<K>. TreeSet<K> doesn't implement Comparable so a TreeSet can not be used as a key into a TreeMap.

You can provide a custom comparator for a TreeMap<K,V>. So if you can define an ordering on TreeSet yourself, then you can use that. new TreeMap<K,V>(comparator)

Also HashSet requires less, and so if you dont require the values in your map to be stored in order, you could use a HashMap<Set<String>, Set<String>> without any trouble.

Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
0
 Map<Set,Set> map=new HashMap();
 Set s=new HashSet();
 Set s1=new HashSet();
 s.add("asd");
 s.add("a1sd");
 s.add("as2d");
 s.add("asd2");
 s.add("asd3");
 s1.add("asd");
 s1.add("a1sd");
 s1.add("as2d");
 s1.add("asd2");
 s1.add("asd3");
 map.put(s, s1);
    System.out.println(map);

the above program works fine for me.

mayank agrawal
  • 628
  • 5
  • 20
0

From what I understood in your comment, I think you rather want something like that:

public static void main(String[] args) {
    Set<Pair> s1 = new TreeSet<>();

    s1.add(new Pair("set11", "set21"));
    s1.add(new Pair("set12", "set22"));
    s1.add(new Pair("set13", "set23"));

    System.out.println(s1);
}

With Pair beeing:

public final class Pair implements Comparable<Pair> {
    public final String left;
    public final String right;

    public Pair(String left, String right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int compareTo(Pair that) {
        return this.left.concat(this.right).compareTo(that.left.concat(that.right));
    }

    @Override
    public String toString() {
        return left + ";" + right;
    }
}

It will:

  1. Make sure that two linked elements stay together (left and right)
  2. Make them ordered (if you need to order them differently, implement compareTo differently)
  3. Make the usage easier and the intent clearer

Edit

If you already have the two sets, you can merge them with the following method:

public static Set<Pair> merge(Set<String> s1, Set<String> s2) {
    Set<Pair> result = new TreeSet<>();
    Iterator<String> it1 = s1.iterator();
    Iterator<String> it2 = s2.iterator();

    while(it1.hasNext() && it2.hasNext()) {
        result.add(new Pair(it1.next(), it2.next()));
    }

    return result;      
}
Spotted
  • 4,021
  • 17
  • 33
  • what I wanted was that if I already have two sets with elements already added into them and if I want to reuse them by making them key and value pairs how can i do? rather than creating sets and adding elements one by one (which is supposed to be done already). – Manish Anand Nov 22 '16 at 07:49