开发者

Java LinkedList Iterators: Why are they returning only Objects?

开发者 https://www.devze.com 2023-01-25 07:55 出处:网络
Here, I\'ll just post my code: int len = InternalList.size(); ListIterator<E> forward = InternalList.listIterator( 0 );

Here, I'll just post my code:

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

And here's the internal list:

private LinkedList<E> InternalList;

So basically my problem is the last if statement only checks Object's equals() method; not the E's equals(). If 开发者_如何转开发forcibly casting it doesn't work, what does?


The runtime types of the elements returned from the iterators are not (and indeed cannot be) changed. They're assigned to fields of type E, which may well be erased to Object at runtime (depending on the generic bounds) but this won't affect the objects themselves.

When equals() is invoked, it's a non-static method and so is invoked on whatever the class of the next object happens to be. If this class doesn't have an overridden equals method then sure, the default Object.equals will be used. However, if this object's class directly or indirectly overrides equals, the most specific override will be used.

In other words, this code should be fine (and the cast is completely unnecessary).

I suggest that you double-check you've overridden equals correctly in the class in question. I would guess that you've implemented it as something like:

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

whereas the argument must be of type Object, otherwise you're just overloading the equals method instead of overriding it. If you're using Java 6, you can add the @Override annotation to your method, which will catch this sort of error.


The correct implementation of equals(Object) will be chosen at runtime, due to runtime polymorphism. Why do you think that's not the case?

Actually, you might have made a common mistake and implemented equals(ASpecificType) instead of equals(Object): you want to override the equals(Object) method from java.lang.Object. Specifying a different parameter type means you no longer override that method.

A common equals() implementation for ASpecificType could start like this:

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


  1. The casting casts E to E so it doesn't do anything.
  2. equals should work without casting.
  3. As you posted in the comment, next == prev will not work for even-numbered lists.

Concerning how to implement 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;
  }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号