compareTo 与对象 returns 为假而为真

compareTo with objects returns a false while it is true

我正在尝试检查我的二叉搜索树的 levelorder 是否与另一个相同。为此,我尝试制作一个 compareTo 方法。我只给该方法相等的值,但它一直说条件为假。当我放置断点时,我发现值仍然相等。我可能没有正确理解它。有谁知道如何解决这个问题?

这是我所做的,如下所示,compareTo returns 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, stack, 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 class: BST.java

输出类似于:

compareTo 方法的断点说:

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

如果您只想测试是否相等,那么只需覆盖 equalshashCode。你可以这样做(省略 class 的其余部分):


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。然后你可以像这样声明你的 class 。其余 class 已省略。

它只是说

  • 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 通常不是很有用。做到 public.