2016-09-29 10 views
0

Für eine Klassenzuweisung muss ich meinen eigenen Iterator von Grund auf neu implementieren. Der Iterator durchläuft eine verknüpfte Liste von Knoten. Alle meine Testfälle, die den Iterator benutzen, scheitern und ich kann nicht sagen, was daran falsch ist.Warum funktioniert mein Iterator nicht?

import java.util.Iterator; 
import java.util.NoSuchElementException; 

class LinkedNodeIterator<E> implements Iterator<E> { 
    LinkedNode<E> headNode; 
    LinkedNode<E> curr; 


    // Constructors 
    public LinkedNodeIterator(LinkedNode<E> head) { 
     headNode = head; 
     curr = headNode;  
    } 

    @Override 
    public boolean hasNext() { 
     if(headNode == null) 
      return false; 
     if(curr.getNext() == null) 
      return false; 
     return true; 
    } 

    @Override 
    public E next() { 
    if(curr.getNext() == null || curr == null) 
    throw new NoSuchElementException(); 
     LinkedNode<E> save = curr; 
     curr = curr.getNext(); 
     return save.getData(); 

    } 


    @Override 
    public void remove() { 
    throw new UnsupportedOperationException(); 
    } 
} 

einige Testfälle, die nicht (sie alle zurück count = 0):

public class PublicLinkedSetTest { 
    Set<String> set0; 
    Set<String> set1; 
    Set<String> set2; 
    Set<String> set3; 
    Set<String> set4; 


@Before 
    public void before() { 
    set0 = new LinkedSet<String>(); 
    set1 = new LinkedSet<String>(); 
    for (String e : new String[]{"c", "a", "d", "b", "e"}) { 
     set1 = set1.adjoin(e); 
    } 
    set2 = new LinkedSet<String>(); 
    for (String e : new String[]{"b", "d", "a", "e", "c"}) { 
     set2 = set2.adjoin(e); 
    } 
    set3 = new LinkedSet<String>(); 
    for (String e : new String[]{"a", "d", "b"}) { 
     set3 = set3.adjoin(e); 
    } 
    set4 = new LinkedSet<String>(); 
    for (String e : new String[]{"x", "y", "z", "a", "b", "d"}) { 
     set4 = set4.adjoin(e); 
    } 
    } 

    public void testIterator1() { 
    int count = 0; 
    for (String e : set1) { 
     count += 1; 
    } 
    assertEquals(5, count); 
    } 

    @Test 

    public void testIterator2() { 
    int count = 0; 
    for (String e : set2) { 
     count += 1; 
    } 
    assertEquals(5, count); 
    } 

    @Test 

    public void testIterator3() { 
    int count = 0; 
    for (String e : set3) { 
     count++; 
    } 
    assertEquals(3, count); 
    } 

Hier ist der Code für meine LinkedSet

import java.util.Iterator; 

public class LinkedSet<E> implements Set<E> { 
    private LinkedNode<E> head = null; 
    private LinkedNode<E> link; 

    // Constructors 
    public LinkedSet() { 
    } 

    public LinkedSet(E e) { 
    this.head = new LinkedNode<E>(e, null); 
    } 

    private LinkedSet(LinkedNode<E> header) { 
    header = head; 

    } 

    @Override 
    public int size() { 
     int count = 0; 
    for(E e : this){ 
     count++;} 
    return count; 
    } 

    @Override 
    public boolean isEmpty() { 
    for(E e : this){ 
     if(e != null) 
      return false; 
    } 
     return true; 
    } 

    @Override 
    public LinkedNodeIterator<E> iterator() { 
    return new LinkedNodeIterator<E>(this.head); 
    } 

    @Override 
    public boolean contains(Object o) { 
    for(E e : this){ 
     if(e == o) 
      return true; 
    } 
    return false; 
    } 

    @Override 
    public boolean isSubset(Set<E> that) { 
     that = new LinkedSet<E>(); 
     if(this.size()>that.size()) 
      return false; 
    for(E e : this){ 
     if(that.contains(e) == false) 
      return false; 
    } 
    return true; 
    } 

    @Override 
    public boolean isSuperset(Set<E> that) { 
    that = new LinkedSet<E>(); 
    if(this.isSubset(that)) 
    return true; 
    else 
     return false; 
    } 

    @Override 
    public Set<E> adjoin(E e) { 
     boolean alwaysEqual = true; 
     if(this.head == null) 
      return this; 
    for(E t : this){ 
     if(t != e) 
      alwaysEqual = false;} 
    if(alwaysEqual == true) 
     return this; 
    LinkedNode<E> temp = this.head; 
    LinkedNode<E> newNode = new LinkedNode<E>(e, temp); 
    LinkedSet<E> newSet = new LinkedSet<E>(newNode); 
    Set<E> otherSet = newSet; 

    return otherSet; 
    } 

    @Override 
    public Set<E> union(Set<E> that) { 
     Set<E> thisSet = this; 
    for(E e : that){ 
     if(!this.contains(e)) 
      thisSet = thisSet.adjoin(e); 

    } 

    return thisSet; 
    } 

    @Override 
    public Set<E> intersect(Set<E> that) { 
     LinkedSet<E> newSet = null; 
     Set<E> otherNewSet = newSet; 
    for(E e : that){ 
     if(this.contains(e)){ 
      if(otherNewSet == null){ 
       LinkedNode<E> newNode = new LinkedNode<E>(e, null); 
       otherNewSet = new LinkedSet<E>(newNode); 
      } 
      else{ 

       otherNewSet = otherNewSet.adjoin(e); 
      } 

     } 
    } 

    return otherNewSet; 
    } 

    @Override 
    public Set<E> subtract(Set<E> that) { 
    LinkedSet<E> newSet = null; 
    Set<E> otherNewSet = newSet; 
    for(E e : that){ 
     if(!this.contains(e)){ 
      if(otherNewSet == null){ 
       LinkedNode<E> newNode = new LinkedNode<E>(e, null); 
       otherNewSet = new LinkedSet<E>(newNode); 
      } 
      else{ 

       otherNewSet = otherNewSet.adjoin(e); 
      } 

     } 
    } 

    return otherNewSet; 
     } 

    @Override 
    public Set<E> remove(E e) { 
     LinkedSet<E> newSet = null; 
     Set<E> otherNewSet = newSet; 
    if(!this.contains(e)) 
    return this; 
    else{ 
     for(E t : this){ 
      if(t != e){ 
       if(otherNewSet == null){ 
        LinkedNode<E> newNode = new LinkedNode<E>(e, null); 
        otherNewSet = new LinkedSet<E>(newNode); 
       } 
      } 
       else{ 

        otherNewSet = otherNewSet.adjoin(e); 
       } 
     } 
    } 
    return otherNewSet; 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public boolean equals(Object o) { 
    if (! (o instanceof Set)) { 
     return false; 
    } 
    Set<E> that = (Set<E>)o; 
    return this.isSubset(that) && that.isSubset(this); 
    } 

    @Override 
    public int hashCode() { 
    int result = 0; 
    for (E e : this) { 
     result += e.hashCode(); 
    } 
    return result; 
    } 
} 
+3

Wahrscheinlich eine gute Idee, ein Beispiel für einen fehlerhaften Testfall zu geben. – javanut13

+0

Ich schlage vor, dass Sie lernen, einen Debugger zu verwenden. Dies ist ein Tool, mit dem Sie jeweils eine Codezeile ausführen und die Werte von Variablen anzeigen können, um zu sehen, wie sich Ihr Programm von dem unterscheidet, was Sie erwarten. –

+0

Leider haben Sie nicht genügend Informationen zur Verfügung gestellt, damit wir Ihnen helfen können. Sie haben nicht erklärt, was passiert, wenn Ihr Testfall fehlschlägt (gibt es eine andere Zahl als 5? Gibt es eine Ausnahme? Etc), und Sie haben nicht genügend Code bereitgestellt, um das Problem zu reproduzieren (z. B. t habe den Code für LinkedSet). Ich kann einige Vermutungen anstellen, aber um eine richtige Antwort zu geben, brauchen wir mehr, um damit zu arbeiten. – Tim

Antwort

0

Das Problem ist nicht Ihr Iterator ist, Es ist Ihre adjoin Methode.

Wenn Sie einen neuen LinkedSet wie folgt konstruieren:

set1 = new LinkedSet<String>(); 

Es bedeutet, dass Sie diesen Konstruktor rufen:

// Constructors 
    public LinkedSet() { 
    } 

Aber das Konstruktor zuweisen nichts zu head, so hat es seine Standardwert:

private LinkedNode<E> head = null; 

S eit head beginnt als null ab und ist nicht immer zugewiesen, diese Methode hat nie etwas anderes als Rückkehr this:

@Override 
public Set<E> adjoin(E e) { 
    boolean alwaysEqual = true; 
    if (this.head == null) 
     return this; 
    for (E t : this) { 
     if (t != e) 
      alwaysEqual = false; 
    } 
    if (alwaysEqual == true) 
     return this; 
    LinkedNode<E> temp = this.head; 
    LinkedNode<E> newNode = new LinkedNode<E>(e, temp); 
    LinkedSet<E> newSet = new LinkedSet<E>(newNode); 
    Set<E> otherSet = newSet; 

    return otherSet; 
} 

So Ihr Iterator nicht über irgendetwas iteriert, weil Ihr Satz nichts in ihm hat.

+0

Danke, dass macht so viel Sinn –

+0

Kein Problem, aber wenn Sie die Antwort zu schätzen wissen, sollten Sie "akzeptieren", indem Sie auf das Häkchen auf der linken Seite oben in der Antwort klicken. – Tim

0
  1. Der Code garantiert eine NullPointerException, wenn curr Null ist.

    if (curr.getNext() == null || curr == null)

Die Ausführung wird links nach rechts. Testen Sie die Referenz auf Null, bevor Sie versuchen, den Wert zu dereferenzieren.