Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 泛型深度比较等于_Java_Generics - Fatal编程技术网

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();
    }
}