Итераторы Java LinkedList: почему они возвращают только объекты? - PullRequest
1 голос
/ 15 ноября 2010

Здесь я просто опубликую свой код:

    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;

Так что, в принципе, моя проблема - последняя, ​​если оператор проверяет только объекты равными() метод;не равно E ().Если принудительное приведение не работает, что делает?

Ответы [ 3 ]

5 голосов
/ 15 ноября 2010

Типы времени выполнения элементов, возвращаемых из итераторов, не изменяются (и не могут быть изменены). Они назначены полям типа E, которые могут быть стерты до Object во время выполнения (в зависимости от общих границ), но это не повлияет на сами объекты.

Когда вызывается equals(), это нестатический метод, поэтому он вызывается для любого класса объекта next. Если этот класс не имеет переопределенного метода equals, тогда, конечно, будет использоваться значение по умолчанию Object.equals. Однако, если класс этого объекта прямо или косвенно переопределяет равные, будет использоваться наиболее специфичное переопределение.

Другими словами, этот код должен быть в порядке (и приведение совершенно не нужно).

Я предлагаю вам еще раз проверить, правильно ли вы переопределили equals в рассматриваемом классе. Я предполагаю, что вы реализовали это как что-то вроде:

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

тогда как аргумент должен иметь тип Object , в противном случае вы просто перегружаете метод equals вместо его переопределения. Если вы используете Java 6, вы можете добавить аннотацию @Override в ваш метод, который будет отлавливать ошибки такого рода.

4 голосов
/ 15 ноября 2010

Правильная реализация 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;
}
1 голос
/ 15 ноября 2010
  1. Кастинг кастует E в E, поэтому ничего не делает.
  2. equals должно работать без приведения.
  3. Как вы написали в комментарии, next == prev не будет работать для четных списков.

Относительно того, как реализовать 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;
  }
}
...