【问题标题】:Infinite iteration using self-writed LinkedList iterator使用自写的 LinkedList 迭代器进行无限迭代
【发布时间】:2014-03-26 11:30:55
【问题描述】:

我的自写双链表有问题。我有测试程序,它测试我的想法并且它可以无限运行。问题出在 WyswietlListe() 方法中,其中条件 !isDone() 始终为真。我的 isDome() 方法有什么问题?我在它们附近添加了星星,以便您更容易找到:)

public class Lista implements List {
private Element head = new Element(null); //wartownik
private int size; 
public Lista(){
    clear();
}

public void clear(){
    head.setPrevious(head);
    head.setNext(head);
    size=0;
}

public void insert(int index, Object value) throws IndexOutOfBoundsException {
   if (index<0 || index>size) throw new IndexOutOfBoundsException();
   Element element = new Element(value);
   element.wstawPrzed(getElement(index));
   ++size;
}

public Element getElement(int index) {
   Element szukany = head.getNext();
   for (int i=index; i>0; --i) 
       szukany = szukany.getNext();   
   return szukany;
}


 public Object get(int index) throws IndexOutOfBoundsException{
    if(index<0 || index>size) throw new IndexOutOfBoundsException();
    Element particular = head.getNext();
    for(int i=0; i <= index; i++)
        particular = particular.getNext();
    return particular.getValue();
}  

public boolean delete(Object o){
    if(head.getNext() == null) return false;
    if(head.getNext().getValue().equals(o)){
        head.setNext(head.getNext().getNext());
        size--;
        return true;
    }

    Element delete = head.getNext();
    while(delete != null && delete.getNext() != null){
        if(delete.getNext().getValue().equals(o)){
            delete.setNext(delete.getNext().getNext());
                            size--;
            return true;
        }
        delete = delete.getNext();
    }
    return false;
}

public int size(){
    return size;
}

public boolean isEmpty(){
    return size == 0;
}

 public void infoOStanie() {
    if (isEmpty()) {
      System.out.println("Lista pusta.");
  }
  else
  {
      System.out.println("Lista zawiera " + size() + " elementow.");
  }

}

public IteratorListowy iterator() {
    return new IteratorListowy();
}

**public void wyswietlListe() {
    IteratorListowy iterator = iterator();
    for (iterator.first(); !iterator.isDone(); iterator.next())
    {
        System.out.println(iterator.current());
    }
    System.out.println();
 }**

 private static final class Element{
    private Object value; 
    private Element next; //Referencja do kolejnego obiektu
    private Element previous; //Referencja do elementu poprzedniego

    public Element(Object value){ 
        setValue(value); 
      }

    public void setValue(Object value) {
        this.value = value;
    }

    public Object getValue() {
        return value;
    }

    //ustawia referencję this.next na obiekt next podany w atgumencie
    public void setNext(Element next) {
        if (next != null)
        this.next = next;
    }

    public Element getNext(){
        return next;
    }

    public void setPrevious(Element previous) {
        if (previous != null)
        this.previous = previous;
    }

    public Element getPrevious() {
        return previous;
    }

    public void wstawPrzed(Element next) {
        Element previous = next.getPrevious();
        setNext(next);
        setPrevious(previous);
        next.setPrevious(this);
        previous.setNext(this);
    } 

    public void delete() {
        previous.setNext(next);
        next.setPrevious(previous);
    }

}

private class IteratorListowy implements Iterator{
private Element current;

public IteratorListowy() {
   current = head;
} 

public void next() {
   current = current.next;
}   

public void previous() {
   current = current.previous;
}

**public boolean isDone() {
   return current.next == null;**
} 
public Object current() {
   return current.value;
}

public void first() {
   current = head.getNext();
}
}
}

和测试:

public class Program {

public static void main(String[] args) {
  Lista lista = new Lista();
  Iterator iterator = lista.iterator();
  Student s1 = new Student("Kowalski", 3523);
  Student s2 = new Student("Polański", 45612);
  Student s3 = new Student("Karzeł", 8795);
  Student s4 = new Student("Pałka", 3218);
  Student s5 = new Student("Konowałek", 8432);
  Student s6 = new Student("Kłopotek", 6743);
  Student s7 = new Student("Ciołek", 14124);
  lista.insert(0, s1);
  lista.insert(0, s2);
  lista.insert(0, s3);
  lista.insert(0, s4);
  lista.insert(0, s5);
  lista.wyswietlListe();


  lista.infoOStanie();

  lista.clear();

  lista.infoOStanie();

}
}

【问题讨论】:

    标签: java list loops iterator infinite-loop


    【解决方案1】:

    问题在于您如何创建List。在您的构造函数中,您调用clear(),您可以在其中执行此操作:

    head.setPrevious(head);
    head.setNext(head);
    

    因此,之后您的列表将是:

    head |-next-> head
         |-previous-> head
    

    之后,您将插入一个新元素(我们称之为 ele1),并调用element.wstawPrzed(getElement(index));,这样可以:

    setNext(next);
    setPrevious(previous);
    next.setPrevious(this);
    previous.setNext(this); 
    

    因此,之后您的列表将是:

    head |-next-> ele1
         |-previous-> ele1
    
    ele1 |-next-> head
         |-previous-> head
    

    让我们插入ele2:

    head |-next-> ele1
         |-previous-> ele2
    
    ele1 |-next-> ele2
         |-previous-> head
    
    ele2 |-next-> head
         |-previous-> ele1
    

    等等……

    如您所见,next 对于您的任何元素都不会是null,因此,条件current.next == null 永远不会是true,您的循环将永远不会停止。

    你可以做什么:

    • 将条件改为current == head

    • 更改构建列表的方式,使nextprevious 可以指向null

    【讨论】:

    • 哦,是的,伙计!这就是我需要的:) 我试图将 isDone() 更改为 current == current.next.value == null 。它解决了无穷大的问题,但列表打印不正确。现在一切正常。谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 2015-08-09
    • 2019-04-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多