【问题标题】:Error Exception in thread "main" java.lang.ClassCastException whenever I use treeset .add() method in java每当我在 java 中使用 treeset .add() 方法时,线程“main”java.lang.ClassCastException 中的错误异常
【发布时间】:2020-06-10 10:26:42
【问题描述】:

所以我有这个任务,我需要将数据放入树集中。我有三个班级:

  1. 兄弟.java。赋值说构造函数是不公开的,所以我使用getInstance()来初始化Brother对象

    public class Brother {
    String name;
    int day;
    int month;
    private static Brother instance = null;
    
    private Brother()
    {
        name = "0";
        day = 0;
        month = 0;
    }
    
    public static Brother getInstance()
    {
        if(instance == null)
        {
            instance = new Brother();
        }
        return instance;
    }
    }
    
  2. 家庭班。该类用于将兄弟对象分配到以兄弟为对象的树集中。

    import java.util.Set;
    import java.util.TreeSet;    
    public class Family {
    Set<Brother> Brothers;
    
    public Family()
    {
        this.Brothers = new TreeSet<Brother>(); 
    }
    
    public Brother makeBrother()
    {
        Brother B = Brother.getInstance();
        return B;
    }
    
    public boolean addBrother(String name, int day, int month)
    {
        Brother B = Brother.getInstance(); 
        return Brothers.add(B);
    }
    }
    
  3. 最后是主类

        public class Main {
          public static void main(String[] args) {
            Family myFamily = new Family();
    
            myFamily.makeBrother();
            // myFamily.addBrother("Shane", 3, 2);
        }
    }
    

每当我尝试使用 myFamily.addBrother() 时,我总是收到此错误“线程“main”java.lang.ClassCastException 中的异常:类 Brother 无法转换为类 java.lang.Comparable(Brother 位于未命名的模块中) loader 'app'; java.lang.Comparable 在 loader 'bootstrap' 的模块 java.base 中)”。我和那有什么关系?当我使用 myFamily.makeBrother() 时,该程序非常好。该算法尚未全部完成,但是当我尝试运行它时,这发生在我身上,我无法继续下一步。之前谢谢你。

【问题讨论】:

    标签: java collections treeset


    【解决方案1】:

    您使用 Set 而不是 List 是因为您想避免重复。要知道哪些兄弟是重复的,TreeSet 需要一个比较器,或者对象本身需要实现 Comparable。

    阅读 TreeSet 的 javadoc 了解更多信息:https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html

    顺便说一句,getInstance 总是返回相同的实例。您可能需要将其更改为 createInstance 或实际创建新实例的东西。

    【讨论】:

    • 您好,感谢您的回答。我已经更改了 getInstance(),因此它不会返回相同的实例,但错误仍然相同。我仍然迷失在“TreeSet 需要比较器,或者对象本身需要实现 Comparable”。因为我认为我所要写的只是 add(E e) 并且我正在关注它,但是仍然有同样的错误
    • A HashSet 不会关心 ComparableComparator(它在 hashCode 之外运行)...但 TreeSet 这样做是因为它是 SortedSet跨度>
    【解决方案2】:

    我同意@GreyFairer,你必须提供一个比较器才能使用 Set,参见这个例子:

    Class Cast Exception problems with TreeSet

    希望对你有帮助!

    【讨论】:

      【解决方案3】:

      我发现那里有一些问题。

      1. 您已将Brother 定义为单例。这意味着您的程序中只存在一个Brother 实例。所以所有对Brother 的引用都将指向同一个实例。我会避免这个类的单例,因为没有意义。
      2. 如果您要使用TreeSet(不为树提供比较器),那么Brother 必须实现Comparable
      3. Family.makeBrother 只返回单例Brother,但不将其添加到家谱中,这就是您没有收到错误消息的原因。

      这是您的代码的工作返工

      import java.util.Comparator;
      import java.util.Set;
      import java.util.TreeSet;
      
      public class FamilyTreeSet {
          public static void main(String[] args) {
              Family myFamily = new Family();
      
              myFamily.addBrother("Shane", 3, 2);
              myFamily.addBrother("Bob", 2, 4);
      
              System.out.println(myFamily);
          }
      
          public static class Brother implements Comparable<Brother>{
              private String name;
              private int day;
              private int month;
      
              public Brother(String name, int day, int month) {
                  this.name = name;
                  this.day = day;
                  this.month = month;
              }
      
              public String getName() {
                  return name;
              }
      
              public int getDay() {
                  return day;
              }
      
              public int getMonth() {
                  return month;
              }
      
              @Override
              public int compareTo(Brother o) {
                  return Comparator.comparing(Brother::getName, String.CASE_INSENSITIVE_ORDER).compare(this, o);
              }
      
              @Override
              public String toString() {
                  return "Brother{" +
                          "name='" + name + '\'' +
                          ", day=" + day +
                          ", month=" + month +
                          '}';
              }
          }
      
          public static class Family {
              Set<Brother> Brothers;
      
              public Family()
              {
                  this.Brothers = new TreeSet<Brother>();
              }
      
              public boolean addBrother(String name, int day, int month)
              {
                  Brother B = new Brother(name, day, month);
                  return Brothers.add(B);
              }
      
              @Override
              public String toString() {
                  return "Family{" +
                          "Brothers=" + Brothers +
                          '}';
              }
          }
      }
      

      我用每个兄弟的名字来比较兄弟。检查我是否首先添加 Shane,但在输出中 Bob 先添加。如果您想按生日比较兄弟,只需更改 compareTo。 Family{Brothers=[Brother{name='Bod', day=2, month=4}, Brother{name='Shane', day=3, month=2}]}

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-10
        • 1970-01-01
        • 1970-01-01
        • 2017-09-24
        • 2015-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多