代码之家  ›  专栏  ›  技术社区  ›  Margus

一般深度比较等于

  •  0
  • Margus  · 技术社区  · 15 年前

    基本上我不想比较元素,而是比较你所包含的元素。如果下面的内容有效,那就很酷了,但事实并非如此。

    public boolean equals(Ie<T> that) {
        T This = this.value;
        T That = that.value;
        boolean x = That.compareTo(This) == 0;
        return 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.toStruts(); +新元素?

    编辑:

    IE类定义为:

    public static class Ie<T extends Number & Comparable<? super T>>
            extends Number implements Comparable<Ie<T>> {
    

    类与方法相比相当简单:

    public int compareTo(Ie<T> that) {
        T This = this.value;
        T That = that.value;
        return (This.compareTo(That) < 0 ? -1 : (This
                .compareTo(That) > 0 ? 1 : 0));
    }
    

    我正在使用集合中的类addall方法,其中contains调用equals。

    埃里克森溶液工作良好:

    @Override
    public boolean equals(Object that) {
        if (that == null)
            return false;
        if (this == that)
            return true;
        if (that instanceof Ie<?>) {
            Object ThisValue = this.value;
            Object ThatValue = ((Ie<?>) that).value;
            return ThisValue.equals(ThatValue);
        }
    
        return false;
    }
    
    5 回复  |  直到 15 年前
        1
  •  0
  •   erickson    15 年前
    @Override
    public boolean equals(Object that)
    {
        if (this == that)
          return true;
        if (that instanceof Ie) {
          Object ThisValue = this.value;
          Object ThatValue = ((Ie<?>) that).value;
          return ThisValue.equals(ThatValue);
        } else 
          return false;
    }
    
        2
  •  1
  •   Community CDub    7 年前

    为了让它起作用,每种类型 T 必须执行 Comparable 接口和实现的每个类 可比的 应该实施 equals 以一致的方式。所以, Matt Ball's 答案就足够了。

    但是,如果由于某种原因,它不需要,在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;
      }
    
    }
    
        3
  •  0
  •   idrosid    15 年前

    首先,不要混淆 equals ()与 compareTo ()第一个显示两个对象是否相等。另一方面,比较试图找出哪个更大(排序时很有用)。

    比较引入了相对性的元素。例如,如果您有一个Person对象列表,那么如果按名称比较,Person“allon”比“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;
      }
    }
    

    或者,如果您有另一个对象,并且希望检查是否为空:

    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;
      }
    }
    
        4
  •  0
  •   Rotsor    15 年前

    是的,最简单的方法是使用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;
        }
    }
    
        5
  •  0
  •   Tom Hawtin - tackline    15 年前

    考虑 Ie<String> Ie<Integer> 那会扔一个 ClassCastException 如果尝试比较泛型参数类型的实例。

    我建议给埃里克森一个稍微不同的解决方案。如果我们添加一个 Comparator Ie 我们可以委托比较。

    不利的是,这需要您创建一个 比较器 (可能有定义 equals )你不能为了不安全的情况 比较器 例如(比如, Collections.emptyList 做)。

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