StringBuffer对象可以作为Java中TreeSet的键吗?

eag*_*arn 2 java stringbuffer hashset comparable treeset

我有以下代码,试图将 StringBuffer 对象作为键放入 TreeSet 中。我这样做的原因是看看是否可以将可变对象作为键。我没有收到任何编译错误。但是当我运行此代码时,我收到代码下方的错误。特别是,我明白了java.lang.StringBuffer cannot be cast to java.lang.Comparable。这个错误表明什么?

从javadoc我看到StringBuffer类被声明为final(public final class StringBuffer),这是否意味着它是不可变的,因此是可散列的?

我是散列和不可变的东西的新手,所以请在这里帮助我。

谢谢

import java.util.*;
class MutableKeys {
public static void main(String[] args) {
        StringBuffer one = new StringBuffer("one");
        StringBuffer  two = new StringBuffer("two");
        StringBuffer three = new StringBuffer("three");
        Set<StringBuffer> sb=new TreeSet<StringBuffer>();
        sb.add(one);
        sb.add(two);
        sb.add(three);
        System.out.println("set before change: "+ sb);
        one.append("onemore");
        System.out.println("set After change: "+ sb);
    }
}

Exception in thread "main" java.lang.ClassCastException: java.lang.StringBuffer cannot be cast to java.lang.Comparable
    at java.util.TreeMap.put(TreeMap.java:542)
    at java.util.TreeSet.add(TreeSet.java:238)
    at inheritance.MutableKeys.main
Run Code Online (Sandbox Code Playgroud)

dka*_*zel 5

  1. 事实上,这StringBuffer意味着public final class StringBuffer你不能对它进行子类化。StringBuffer 是非常可变的(这就是重点,您可以修改缓冲区的内容。)

  2. 你不想使用可变的东西作为键,因为对象被修改后,它的 equals() 和 hashcode() 方法将返回不同的结果,你将无法再在 Map 中找到它。

  3. 如果您确实想在 TreeSet 中使用 StringBuffer,则必须提供自己的 Comparator,因为 StringBuffer 没有实现 Comparable。