Java LinkedList迭代器:为什么它们只返回对象?

时间:2010-11-15 12:41:06

标签: java iterator linked-list type-conversion

在这里,我只是发布我的代码:

    int len = InternalList.size();

    ListIterator<E> forward = InternalList.listIterator( 0 );
    ListIterator<E> backward = InternalList.listIterator( len );
    while( forward.hasNext() && backward.hasPrevious() )
    {
        E next = forward.next();
        E prev = backward.previous();

        // When the object references are the same, we expect to be at the
        // center of the list (for odd-numbered lists?); we're done
        if( next == prev )
            return true;

        // Otherwise, if the object values aren't the same, we're not a
        // palindrome
        if( !((E)next).equals( prev ) )
            return false;
    }

这是内部列表:

private LinkedList<E> InternalList;

所以基本上我的问题是最后一个if语句只检查Object的equals()方法;不是E等于()。如果强行施法它不起作用,那会是什么?

3 个答案:

答案 0 :(得分:5)

从迭代器返回的元素的运行时类型不会(实际上也不会)更改。它们被分配到E类型的字段,在运行时可能会被删除到Object(取决于通用边界),但这不会影响对象本身。

当调用equals()时,它是一个非静态方法,因此无论next对象的类是什么,都会调用它。如果此类没有重写的equals方法,那么肯定会使用默认的Object.equals。但是,如果此对象的类直接或间接覆盖equals,则将使用最具体的覆盖。

换句话说,这段代码应该没问题(并且完全不需要演员)。

我建议您仔细检查是否已在相关课程中正确覆盖equals。我猜你已经把它实现为:

public class MyFoo {
    ...
    public boolean equals(MyFoo other) {
       ...
    }
}

而参数必须是 Object 类型,否则你只是重载equals方法而不是覆盖它。如果您使用的是Java 6,则可以将@Override注释添加到方法中,这将捕获此类错误。

答案 1 :(得分:4)

由于运行时多态性,将在运行时选择equals(Object)的正确实现。为什么你认为情况并非如此?

实际上,您可能犯了一个常见错误并实施了equals(ASpecificType)而不是equals(Object):您想要覆盖equals(Object)中的java.lang.Object方法。指定其他参数类型意味着您不再重写该方法。

equals()的常见ASpecificType实施可以这样开始:

public boolean equals(Object o) {
  if (this==o) {
    return true;
  } else if (o==null || o.getClass() != getClass()) {
    return false;
  }
  ASpecificType other = (ASpecificType) other;
  // insert specific comparison here
  return result;
}

答案 2 :(得分:1)

  1. 该投射会将E投射到E,因此它不会执行任何操作。
  2. equals应该无需投射即可。
  3. 正如您在评论中发布的那样,next == prev不适用于偶数列表。
  4. 关于如何实施equals

    public boolean equals(Object o) {
      if(this == o) { return true; }
      if(o == null) { return false; }
      if(o instanceof [ClassOfThis]) {
        o = (Type)o;
        // compare here.
      } else {
        return false;
      }
    }