我正在学习泛型在Java中是如何工作的,我正在阅读Deitel & Deitel "Java - how to Program“一书中的练习,以获得这个主题的一些熟练程度。我对以下项目的结果感到困惑:
/*
* Exercise 20.7 from "Java - How To Program". This program will implement a
* generic isEqualTo() method that calls the equals() method on
* the passed in references. I suspect it will only return true if the
* passed in references refer to the same object, as the generic param will
* be replaced with Object after compilation, which means that the equals()
* method will be that of Object, which compares if two Objects are the SAME
* object.
*/
import java.util.ArrayList;
import java.util.Arrays;
public class EqualTo {
public static void main(String[] args) {
Integer[] intArray1 = {3, 4, 6, 2};
Integer[] intArray2 = {5, 0, 7, 1};
// identical content, but will become different lists, so should be
// false when compared in isEqualTo to each other
Float[] floatArray1 = {3.3f, 4.4f, 1.2f};
Float[] floatArray2 = {3.3f, 4.4f, 1.2f};
ArrayList<Integer> intList1 = new ArrayList<>(Arrays.asList(intArray1));
ArrayList<Integer> intList2 = new ArrayList<>(Arrays.asList(intArray2));
ArrayList<Float> floatList1 = new ArrayList<>(Arrays.asList(floatArray1));
ArrayList<Float> floatList2 = new ArrayList<>(Arrays.asList(floatArray2));
// CONSOLE OUTPUT: false - expected
System.out.println(isEqualTo(intList1, intList2));
// CONSOLE OUTPUT: true - expected
System.out.println(isEqualTo(intList1, intList1));
// ****CONSOLE OUTPUT: true - unexpected *****
System.out.println(isEqualTo(floatList1, floatList2));
// CONSOLE OUTPUT: true - expected
System.out.println(isEqualTo(floatList1, floatList1));
}
public static <T> boolean isEqualTo(ArrayList<T> list1, ArrayList<T> list2) {
return (list1.equals(list2) ? true : false);
}
}该练习指出,我应该像我所做的那样,通过调用equals()方法实现isEqualTo()。只有在list1和list2中传递的对象引用同一个对象时,我才会期望该方法返回true,因为object的API中相等方法的定义是这样的:
摘自:https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object- 类对象的等号方法实现了对象上最具区别性的可能的等价关系;也就是说,对于任何非空引用值x和y,该方法都返回true当且仅当x和y引用同一个对象(x == y的值为true)。
但是,正如您可以从我的注释中看到的,当我传入两个具有相同状态的不同对象时,输出是真的。下面是代码中意外行为的相关部分:
// identical content, but will become different lists, so should be
// false when compared in isEqualTo to each other
Float[] floatArray1 = {3.3f, 4.4f, 1.2f};
Float[] floatArray2 = {3.3f, 4.4f, 1.2f};
ArrayList<Float> floatList1 = new ArrayList<>(Arrays.asList(floatArray1));
ArrayList<Float> floatList2 = new ArrayList<>(Arrays.asList(floatArray2));
// ****CONSOLE OUTPUT: true - unexpected *****
System.out.println(isEqualTo(floatList1, floatList2));怎么会这样?我认为在编译时,泛型<T>类型参数被更改为它的上限,在本例中它是对象,因为这里没有任何扩展或超级关键字。如果是这样的话,floatList1和floatList2是不同的对象,因此它们不应该根据Object的equals()方法相等,对吗?
发布于 2016-04-06 02:05:08
虽然您对Object的看法是正确的,但Float.equals(Object)和Integer.equals(Object) 重写了 Object.equals;链接Float Javadoc表示(部分)
注意,在大多数情况下,对于类
Float、f1和f2的两个实例,f1.equals(f2)值是真的当且仅当 f1.floatValue() == f2. f2.floatValue()
而Integer Javadoc说
将此对象与指定的对象进行比较。如果并且只有当参数不是
null并且是包含与此对象相同的int值的Integer对象时,结果才是真。
发布于 2016-04-06 02:02:13
根据Object的等价物方法,它们不是,而是List 覆盖,即equals规范:
将指定的对象与此列表进行相等比较。返回true当且仅当指定的对象也是一个列表时,这两个列表具有相同的大小,并且两个列表中所有对应的元素对是相等的。(如果是
e1,则两个元素e2和(e1==null ? e2==null : e1.equals(e2)相等)。换句话说,如果两个列表以相同的顺序包含相同的元素,则定义为相等。此定义确保equals方法在List接口的不同实现中正常工作。
https://stackoverflow.com/questions/36440129
复制相似问题