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@817
而 o.e
指向 Queue@819
.
如果您只想测试是否相等,那么只需覆盖 equals
和 hashCode
。你可以这样做(省略 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.
我正在尝试检查我的二叉搜索树的 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@817
而 o.e
指向 Queue@819
.
如果您只想测试是否相等,那么只需覆盖 equals
和 hashCode
。你可以这样做(省略 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.