2010-11-15 19 views
1

Ici, je vais poster mon code:Java LinkedList Iterators: Pourquoi ne retournent-ils que des objets?

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

Et voici la liste interne:

private LinkedList<E> InternalList; 

Donc, fondamentalement, mon problème est la dernière instruction if vérifie que la méthode des égaux de l'objet(); pas les E sont égaux(). Si le lancer de force ne fonctionne pas, que fait-il?

+0

Et oui, je sais que je pourrais optimiser ce pour les listes paires.: P – Hamster

+0

Ce n'est pas une optimisation, c'est une solution, à moins de visiter les éléments deux fois est inoffensif ... –

+0

Pourquoi ça ne serait pas? – Hamster

Répondre

4

L'implémentation correcte de equals(Object) sera choisie au moment de l'exécution, en raison du polymorphisme d'exécution. Pourquoi pensez-vous que ce n'est pas le cas?

En fait, vous pourriez avoir fait une erreur commune et mis en œuvre equals(ASpecificType) au lieu de equals(Object): vous voulez remplacer la méthode equals(Object) de java.lang.Object. La spécification d'un type de paramètre différent signifie que vous ne remplacez plus cette méthode.

Une implémentation equals() commune pour ASpecificType pourrait commencer comme ceci:

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

Hmm. Ça pourrait être ça. Lemme check ... – Hamster

+1

+1 pour afficher le squelette 'equals', puisque je suis d'accord que c'est la cause la plus probable du problème (et donc la vérification de type et le casting ne seront pas présents). –

+0

Oui, il semble que c'était l'erreur que j'ai faite. – Hamster

5

Les types d'exécution des éléments renvoyés par les itérateurs ne sont pas (et ne peuvent d'ailleurs pas être modifiés). Ils sont affectés aux champs de type E, qui peuvent être effacés à Object lors de l'exécution (en fonction des limites génériques), mais cela n'affecte pas les objets eux-mêmes.

Lorsque equals() est invoqué, il s'agit d'une méthode non statique qui est donc appelée quelle que soit la classe de l'objet next. Si cette classe n'a pas de méthode equals substituée, alors la valeur par défaut Object.equals sera utilisée. Toutefois, si la classe de cet objet remplace directement ou indirectement les équivalents, le remplacement le plus spécifique sera utilisé. En d'autres termes, ce code devrait être bon (et la distribution est complètement inutile).

Je vous suggère de revérifier que vous avez corrigé equals correctement dans la classe en question. Je suppose que vous avez mis en place comme quelque chose comme:

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

alors que l'argument doit être de type objet, sinon vous êtes juste surcharger la méthode equals au lieu de remplaçant. Si vous utilisez Java 6, vous pouvez ajouter l'annotation @Override à votre méthode, qui détectera ce type d'erreur.

+0

Il en a un. Mais les étapes du débogueur me montrent que cela passe toujours par la méthode equals() de Object. C'est tout ce que je sais jusqu'ici. – Hamster

1
  1. La coulée jette E-E il ne fait rien.
  2. equals devrait fonctionner sans coulée.
  3. Comme vous l'avez posté dans le commentaire, next == prev ne fonctionnera pas pour les listes paires.

En ce qui concerne la façon de mettre en œuvre 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

'instanceof getClass()' ne sera pas compilé. 'instanceof' attend un nom de classe et non une expression renvoyant un objet' Class'. Vous devrez utiliser 'isInstance()'. –

+0

D'accord, merci. En fait, je ne l'écris jamais de cette manière. J'utilise la classe que j'ai. Actualisé. – khachik