compareTo with objects 返回 false 而它为 true

问题描述

我正在尝试检查我的二叉搜索树的 levelorder 是否等于另一个。为此,我尝试创建一个 compareto 方法。我只为方法赋予相等的值,但它一直说条件为假。当我放置断点时,我看到这些值仍然相等。我可能没有正确理解它。有大佬知道怎么解决吗?

这是我所做的,如下所示,compareto 返回 1 而不是 0:

import edu.princeton.cs.algs4.BST;
import java.util.*;

public class MyBST implements Comparable<MyBST>{

    private Object e;

    public MyBST(Object e){
        this.e = e;
    }

    private Object getE(){
        return e;
    }

    public static void main(String[] args) {

        int size = 4;

        Random r = new Random();
        Set<Integer> tes = new LinkedHashSet<>(size);
        Stack<Integer> stack = new Stack<>();

        while (tes.size() < size) {
            tes.add(r.nextInt(10));
        }

        System.out.println("possible combinations");
        Set<Stack<Integer>> combos = combos(tes,stack,tes.size());

        Object[] arr = combos.toArray();
        List<String> d = new ArrayList<>();
        for (Object s : arr) {
            String b = s.toString();
            b = b.replaceAll("\\[","").replaceAll("\\]","");
            d.add(b);
        }

        int index = 0;

        do {
            BST<String,Integer> bst1 = new BST<String,Integer>();
            BST<String,Integer> bst2 = new BST<String,Integer>();
            String key1 = d.get(index);
            String key2 = d.get(index);
            key1 = key1.replaceAll(" ","");
            String[] m = key1.split(",");

            key2 = key2.replaceAll(" ","");
            String[] n = key2.split(",");

            System.out.println("1e order");
            for (int j = 0; j < m.length; j++) {

                System.out.println(m[j]);
                bst1.put(m[j],0);
            }

            System.out.println("2e order");
            for (int j = 0; j < n.length; j++) {

                System.out.println(n[j]);
                bst2.put(n[j],0);
            }

            System.out.println("levelorder 1e BST");

            MyBST e = new MyBST(bst1.levelOrder());
            MyBST y = new MyBST(bst2.levelOrder());

            System.out.println(bst1.levelOrder());

            System.out.println("levelorder 2e BST");

            System.out.println(bst2.levelOrder());

            System.out.println(e.compareto(y) + "\n");
            index++;
        } while (index < arr.length - 1);

    }
    public static Set<Stack<Integer>> combos(Set<Integer> items,Stack<Integer> stack,int size) {
        Set<Stack<Integer>> set = new HashSet<>();

        if (stack.size() == size) {
            set.add((Stack) stack.clone());
        }
        Integer[] itemz = items.toArray(new Integer[0]);
        for (Integer i : itemz) {
            stack.push(i);
            items.remove(i);
            set.addAll(combos(items,size));
            items.add(stack.pop());
        }
        return set;
    }

    @Override
    public int compareto(MyBST o) {
        if (this.e == o.e) {
            return 0;
        }
        else
            return 1;
    }
}

在这里您可以找到 BST.java 类:BST.java

输出类似于:

enter image description here

compareto 方法处的断点说:

enter image description here

解决方法

当您使用 == 运算符时,您实际上是在检查引用是否指向内存中的同一对象。从您的调试屏幕截图中您可以看到它们不是。 this.e 指向对象 Queue@817o.e 指向 Queue@819

,

如果您只想测试相等性,那么只需覆盖 equalshashCode。您可以这样做(省略其余课程):


public class MyBST {  

   private Object e;
  
   public MyBST(Object e) {
        this.e = e;
    }

    public Object getE(){
        return e;
    }
    
    @Override
    public int hashCode() {
        return Objects.hashCode(e);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!(obj instanceof MyBST))
            return false;
        MyBST me = (MyBST) obj;
        if (e == null) {
            if (me.e != null)
                return false;
        } else if (!e.equals(me.e))
            return false;
        return true;
    }
}

实现 Comparable 更加复杂,因为您需要检查比其他 MyBST 实例更少、相等或更大的情况。不幸的是,MyBST 中唯一的字段是一个对象,它不会告诉您有关 its 实际字段的任何信息。因此,如果没有用于测试的特定字段,您需要确保您传递的对象也实现了 Comparable。然后你可以像这样声明你的类。其余课程省略。

简单地说

  • MyBST 具有可比性。
  • 和构造函数中传入的对象是可比的。
class MyBST<T extends Comparable<? super T>> implements Comparable<MyBST<T>>{

    private T e;

    public MyBST(T e){
        this.e = e;
    }

    public T getE(){
        return e;
    }
    
    @Override
    public int compareTo(MyBST<T> o) {
        return e.compareTo(o.e);    
    }
}

另一种选择是简单地传递实际的对象类型并将其存储为这样,而不是作为对象。然后只需在 MyBST 中实现 Comparable 并使用传递对象的适当字段。假设对象是 Apple 对象,您可以这样做。

class Apple {
    String type;
    int weight;
}

class MyBST implements Comparable<MyBST> {
    
    private Apple apple;
    
    public MyBST(Apple apple) {
        this.apple = apple;
    }
    
    @Override
    public int compareTo(MyBST e) {
        // this could be different depending on how you wanted
        // to compare one apple to another. This comparison favors
        // type over weight.

        // check type - String class implements comparable
        int ret = apple.type.compareTo(e.apple.type);
        if (ret != 0) { 
            return ret;
        }
        
        // same type so check weight
        if (apple.weight < e.apple.weight) {
            return -1;
        }
        if (apple.weight > e.apple.weight) {
            return 1;
        }
        return 0;  // equals apples based on criteria
    }
}

终于有了这个。

    private Object getE(){
        return e;
    }

私有 getter 通常不是很有用。公开。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...