Java 泛型深度比较等于
基本上,我不想比较元素,而是比较包含的元素。如果下面的方法能奏效,那就很酷了,但事实并非如此Java 泛型深度比较等于,java,generics,Java,Generics,基本上,我不想比较元素,而是比较包含的元素。如果下面的方法能奏效,那就很酷了,但事实并非如此 public boolean equals(Ie<T> that) { T This = this.value; T That = that.value; boolean x = That.compareTo(This) == 0; return x; } public boolean等于(即该值){ T This=This.value; T那=那值; 布尔
public boolean equals(Ie<T> that) {
T This = this.value;
T That = that.value;
boolean x = That.compareTo(This) == 0;
return x;
}
public boolean等于(即该值){
T This=This.value;
T那=那值;
布尔值x=That.compareTo(This)==0;
返回x;
}
我所做的是:
public boolean equals(Object obj) {
if (obj == null)
return false;
String tmp = obj.toString();
if (this.value instanceof Integer)
return equalsInt(new Ie<Integer>(Integer.parseInt(tmp)));
// etc.
return false;
}
public boolean equalsInt(Ie<Integer> ie) {
Integer This = this.value.intValue();
Integer That = ie.value;
boolean x = That.compareTo(This) == 0;
return x;
}
公共布尔等于(对象obj){
if(obj==null)
返回false;
字符串tmp=obj.toString();
if(this.value instanceof Integer)
返回equalsInt(新的Ie(Integer.parseInt(tmp));
//等等。
返回false;
}
公共布尔等式(Ie){
整数This=This.value.intValue();
整数=ie.value;
布尔值x=That.compareTo(This)==0;
返回x;
}
这是一个显而易见的暴力解决方案。没有obj.toString()可以完成吗强>+新元素
编辑:
Ie类定义为:
public static class Ie<T extends Number & Comparable<? super T>>
extends Number implements Comparable<Ie<T>> {
公共静态类Ie@Override
公共布尔等于(该对象)
{
如果(这个==那个)
返回true;
如果(Ie的那个实例){
对象ThisValue=this.value;
对象ThatValue=((即)that).value;
返回此值。等于(该值);
}否则
返回false;
}
首先,不要把()和()。第一个显示两个对象是否相等。另一方面,比较试图找出哪个更大(排序时有用)
比较引入了相对性的元素。例如,如果您有一个Person对象列表,那么如果您按姓名进行比较,Person“Allun”比“Dave”小,但如果您按年龄进行比较,则两者可能相等。即使他们在年龄上是相等的,根据equals()方法,他们也不相等,因为他们代表不同的人
关于equals()方法本身,这可能会帮助您:
class MyClass {
int anInt;
public boolean equals(Object obj) {
if (obj instance of MyClass) {
MyClass that = (MyClass) obj;
return this.anInt==that.anInt;
}
return false;
}
}
或者,如果您有另一个对象,并且希望检查null:
class MyClass {
Object anObject;
public boolean equals(Object obj) {
if (obj instance of MyClass) {
MyClass that = (MyClass) obj;
return this.anObject==null ? that.object==null : this.object.equals(that.object);
}
return false;
}
}
为此,每个类型T
都必须实现Comparable
接口,每个实现Comparable
的类都应该以一致的方式实现equals
。所以,答案应该足够了
然而,如果出于某种原因它没有,就需要一个围绕Java类型擦除的解决方案。通过明确指定T
的类型,可以进行必要的类型检查。Ie
类可以这样定义:
class Ie<T extends Comparable<T>>
{
private final Class<? extends T> type;
private final T value;
public Ie(Class<? extends T> type, T value)
{
this.type = type;
this.value = value;
}
@Override
public boolean equals(Object obj)
{
if (obj == this)
return true;
if (obj instanceof Ie) {
Object that = ((Ie<?>) obj).value;
if (type.isInstance(that)) {
return value.compareTo(type.cast(that)) == 0;
}
}
return false;
}
}
Ie类
{
private final Class是的,最简单的方法是使用Object.equals方法比较包含的对象(如Matt Ball的答案)。
但是,如果出于某种原因无法使用它,则必须存储类型并执行一些动态类型转换(如erickson的回答中所示),或者执行未经检查的转换,如以下示例中所示:
class Ie<T extends Comparable<T>>
{
public Ie(T value) {this.value = value;}
private final T value;
public boolean equals(Object obj) {
if(obj == this)
return true;
if(obj instanceof Ie<?>)
{
Ie<?> That = (Ie<?>)obj;
if(value.getClass() != That.value.getClass())
return false;
// Cast to anything that allows calling typed equals().
// The type will be erased at runtime anyway.
return ((Ie<String>)this).equals((Ie<String>)That);
}
return false;
}
public boolean equals(Ie<T> that)
{
return that.value.compareTo(this.value) == 0;
}
}
Ie类
{
公共Ie(T值){this.value=value;}
私人最终T值;
公共布尔等于(对象obj){
如果(obj==此)
返回true;
if(Ie的obj实例)
{
即=(即)obj;
如果(value.getClass()!=That.value.getClass())
返回false;
//强制转换为允许调用typed equals()的任何对象。
//无论如何,该类型将在运行时被擦除。
返回这个等于那个;
}
返回false;
}
公共布尔等于
{
返回.value.compareTo(this.value)==0;
}
}
考虑Ie
和Ie
,如果您尝试比较泛型参数类型的实例,它们将抛出ClassCastException
我将向erickson建议一个稍微不同的解决方案。如果我们在Ie
中添加比较器
,我们可以委托比较
另一方面,这确实需要您创建一个比较器
(可能使用定义的等于
),并且您不能使用不安全的情况来获取比较器
实例(例如,Collections.emptyList
)
Ie类{
private final ComparatorI实际上不理解您的问题和目标。您只想比较两个对象吗?如果是,您应该继续比较对象的每个属性。请澄清您的问题。这是一个令人困惑的equals方法,因为它没有正确覆盖object.equals(object other)。equals()的参数应该是Object,然后在运行时检查它是否等于此对象。我非常喜欢这里的基本思想,所以我将其设置为正常工作。希望您不介意。@erickson:EWWWW,instanceOf。但是,是的,谢谢您的实现。如果您执行equals(Ie)
方法,它不会覆盖对象。等于,因此您只需使用实例的。好吧,还有其他方法可以确保“that”是“right”类型…取决于“right”是什么类型的意思是。例如,您可以通过检查getClass().equals(that.getClass())
来要求this
和that
是相同的运行时类型。但是,既然value
似乎是这里最重要的,我认为instanceof
是合适的。
class MyClass {
Object anObject;
public boolean equals(Object obj) {
if (obj instance of MyClass) {
MyClass that = (MyClass) obj;
return this.anObject==null ? that.object==null : this.object.equals(that.object);
}
return false;
}
}
class Ie<T extends Comparable<T>>
{
private final Class<? extends T> type;
private final T value;
public Ie(Class<? extends T> type, T value)
{
this.type = type;
this.value = value;
}
@Override
public boolean equals(Object obj)
{
if (obj == this)
return true;
if (obj instanceof Ie) {
Object that = ((Ie<?>) obj).value;
if (type.isInstance(that)) {
return value.compareTo(type.cast(that)) == 0;
}
}
return false;
}
}
class Ie<T extends Comparable<T>>
{
public Ie(T value) {this.value = value;}
private final T value;
public boolean equals(Object obj) {
if(obj == this)
return true;
if(obj instanceof Ie<?>)
{
Ie<?> That = (Ie<?>)obj;
if(value.getClass() != That.value.getClass())
return false;
// Cast to anything that allows calling typed equals().
// The type will be erased at runtime anyway.
return ((Ie<String>)this).equals((Ie<String>)That);
}
return false;
}
public boolean equals(Ie<T> that)
{
return that.value.compareTo(this.value) == 0;
}
}
class Ie<T> {
private final Comparator<? super T> comparator;
private final T value;
public Ie(Comparator<? super T> comparator, T value) {
if (comparator == null || value == null) {
throw new NullPointerException();
}
this.comparator = comparator;
this.value = value;
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Ie)) {
return false;
}
Object other = (Ie<?>)obj;
return
this.comparator.equals(other.comparator) &&
this.comparator.compare(this.value, (T)other.value) == 0
}
@Override
public int hashCode() {
return comparator.hashCode()*31 + value.hashCode();
}
}