地图可以将键和值都作为集合

时间:2016-11-22 05:45:50

标签: java collections treemap

我创建了一个TreeMap,其类型Set的参数既是键值又是树也是TreeSet,因此键和值对总是相互对应。但是我得到一个错误:

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

以下是以下代码:

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);
    }

}

但是当我使用Key Or值作为String Like(String,Set)或(Set,String)时,它可以正常工作。

我可以不将密钥和值都作为集合吗?或者如果是,如何使用它们?

4 个答案:

答案 0 :(得分:0)

TreeMapSortedMap。它只接受实现Comparable的键,或者你可以在初始化期间在TreeMap的构造函数中传递Comparator对象。

  

插入到有序映射中的所有键必须实现Comparable接口(或由指定的比较器接受)。

     

此外,所有这些键必须是可相互比较的:k1.compareTo(k2)(或comparator.compare(k1,k2))不得为有序映射中的任何键k1和k2抛出ClassCastException。

     

尝试违反此限制将导致违规方法或构造函数调用抛出ClassCastException。

如果排序不重要,您可以使用HashMap:

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

答案 1 :(得分:0)

catchTreeSet<K>的默认构造函数需要TreeMap<K,V>来实现KComparable<K>未实施TreeSet<K>,因此Comparable无法用作TreeSet的密钥。

您可以为TreeMap提供自定义比较器。因此,如果您可以自己定义TreeMap<K,V>的订单,那么您可以使用它。 TreeSet

new TreeMap<K,V>(comparator)也需要更少,因此如果您不需要按顺序存储地图中的值,则可以毫无困难地使用HashSet

答案 2 :(得分: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);

上述程序对我来说很好。

答案 3 :(得分:0)

根据我在评论中的理解,我认为你更喜欢这样的东西:

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);
}

使用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;
    }
}

它会:

  1. 确保两个链接的元素保持在一起(左和右)
  2. 让它们有序(如果您需要以不同方式订购,请以不同方式实施compareTo
  3. 使用更简单,意图更清晰
  4. 修改

    如果您已有两套,可以使用以下方法合并它们:

    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;      
    }