2015-09-24 5 views
1

Сейчас я пытаюсь создать круговой список, где, когда я использую hasNext() из Iterator, он всегда должен возвращать true. Однако прямо сейчас он возвращает, что это не круговой список, и у меня также возникают проблемы с печатью значений (в этом примере строк) ArrayList. Вот класс CircularList я создал, который имеет внутренний класс Node для объектов, которые попали в список:У меня проблемы с моим CircularList

public class CircularList<E> implements Iterable{ 
private Node<E> first = null; 
private Node<E> last = null; 
private Node<E> temp; 
private int size = 0; 

//inner node class 
private static class Node<E>{ //In this case I am using String nodes 
    private E data; //matching the example in the book, this is the data of the node 
    private Node<E> next = null; //next value 
    //Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next  
    private Node(E data){ 
     this.data = data; 
    } 
} 
//end of inner node class 
public void addValue(E item){ 
    Node<E> n = new Node<E>(item); 
    if(emptyList() == true){ //if the list is empty 
     //only one value in the list 
     first = n; 
     last = n; 
    } 
    else{ //if the list has at least one value already 
     //store the old first value 
     temp = first; 
     //the new first is the input value 
     first = n; 
     //next value after first is the old first value 
     first.next = temp; 
     //if after this there will be only two values in the list once it is done 
     if(size == 1){ 
      last = temp; 
     } 
     //if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it 
     //creating the circular part of the list 
     last.next = first; 
    } 
    size++; 
} 

public boolean emptyList(){ 
    boolean result = false; 
    if(first == null && last == null){ //if there is no values at all 
     result = true; 
    } 
    return result; 
} 

@Override 
public Iterator<E> iterator() { 
    // TODO Auto-generated method stub 
    return new CircularIterator<E>(); //each time this method is called it will be creating a new instance of my Iterator 
} 
} 

Вот класс итератора творю:

public class CircularIterator<E> implements Iterator<E> { 

@Override 
public boolean hasNext() { 
    return false; 
} 

@Override 
public E next() { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public void remove() { 
    // TODO Auto-generated method stub 

} 

} 

и, наконец, Тест класс:

public class Test { 
static CircularList<String> c = new CircularList<String>(); //in this case it is a string list 
static Iterator it = c.iterator(); 

public static void main(String[]args){ 
    c.addValue("Bob"); 
    c.addValue("Joe"); 
    c.addValue("Jaina"); 
    c.addValue("Hannah"); 
    c.addValue("Kelly"); 
    Iterate(); 

    for(String val : c){ 
     System.out.println(val); 
    } 
} 

private static boolean Iterate(){ 
    boolean result = false; 
    if(!it.hasNext()){ 
     System.out.println("Not a circular list!"); 
    } 
    else{ 
     result = true; 
    } 
    return result; 
} 
} 

Опять я пытаюсь заставить его всегда возвращать так, я думаю, что проблема заключается в моем hasNext() метод, но я не совсем уверен.

+1

Все ваши 'hasNext' делает это' вернуть false'. –

+0

Итератор до сих пор является лишь обычным автогенерированным заглушкой, поэтому он вообще не работает. Кроме того, если список пуст, 'Iterate' вернет false, хотя список округлен – Paul

+0

@Paul Хорошо, не могу поверить, что я пропустил это. Что касается значений в списке, я могу добавить их правильно? Также было бы хорошим способом создать метод hasNext() без каких-либо параметров? – FyreeW

ответ

1

Основная проблема с вашим подходом заключается в том, что вы используете static внутренние классы - это не обязательно. Достаточно создать общий общий класс. Общий параметр затем наследуется внутренними классами, и исчезают всевозможные проблемы.

Выполнение Iterator должным образом является тонким.

public static class CircularList<E> implements Iterable<E> { 

    private Node first = null; 
    private Node last = null; 
    private int size = 0; 

    private class Node { 

     private E data; 
     private Node next = null; 

     private Node(E data) { 
      this.data = data; 
     } 
    } 

    public void addValue(E item) { 
     Node n = new Node(item); 
     if (emptyList()) { 
      //only one value in the list 
      first = n; 
      last = n; 
     } else { //if the list has at least one value already 
      //store the old first value 
      Node temp = first; 
      //the new first is the input value 
      first = n; 
      //next value after first is the old first value 
      first.next = temp; 
      //if after this there will be only two values in the list once it is done 
      if (size == 1) { 
       last = temp; 
      } 
      //if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it 
      //creating the circular part of the list 
      last.next = first; 
     } 
     size++; 
    } 

    public boolean emptyList() { 
     boolean result = false; 
     if (first == null && last == null) { //if there is no values at all 
      result = true; 
     } 
     return result; 
    } 

    @Override 
    public Iterator<E> iterator() { 
     return new CircularIterator(); //each time this method is called it will be creating a new instance of my Iterator 
    } 

    private class CircularIterator implements Iterator<E> { 

     // Start at first. 
     Node next = first; 

     public CircularIterator() { 
     } 

     @Override 
     public boolean hasNext() { 
      // Stop when back to first. 
      return next != null; 
     } 

     @Override 
     public E next() { 
      if (hasNext()) { 
       E n = next.data; 
       next = next.next; 
       if (next == first) { 
        // We're done. 
        next = null; 
       } 
       return n; 
      } else { 
       throw new NoSuchElementException("next called after end of iteration."); 
      } 
     } 
    } 
} 

public void test() { 
    CircularList<String> c = new CircularList<>(); 
    c.addValue("A"); 
    c.addValue("B"); 
    c.addValue("C"); 
    c.addValue("D"); 
    for (String s : c) { 
     System.out.println(s); 
    } 
} 

Ваш основной код был по существу правильно - все, что я делал, было удалить ненужные параметры дженерики из внутренних классов.

Обратите внимание, что способ добавления узла в список означает, что элементы возвращаются назад. Вы можете легко настроить это в своем методе addValue.

+0

Хорошо, спасибо за совет! Я реализую это и даю, что прочитал! – FyreeW

+0

@FyreeW - Похоже, что эта ссылка не в том месте - вы пытаетесь найти правильный вариант для вас. – OldCurmudgeon

+0

@OldCurmedgeon все еще говорит, что это не круговой список, и когда я пытаюсь выполнить расширенный цикл в конце, он говорит мне, что мне нужно изменить String s на String. – FyreeW

0

Вы можете просто использовать следующие для циклической итерации. Этот Циркулярный список ведет себя так же, как и другие java.util.List s. Но итерация изменена. Вам не нужно заботиться о его настройке производительности дополнительно. Потому что это суперкласс (LinkedList) уже хорошо протестирован и достаточно силен для использования.

`общественный класс CircularList распространяется LinkedList {

@Override 
public Iterator<E> iterator() { 
    return createIterator(); 
} 

//create new iterator for circular process 
private Iterator<E> createIterator() { 
    return new Iterator<E>() { 
     private int index = 0; 

     @Override 
     public boolean hasNext() { 
      //no elements when list is empty 
      return isEmpty(); 
     } 

     @Override 
     public E next() { 
      E node = get(index); 

      //rotate index 
      index++; 
      if (index == size()) { 
       index = 0; 
      } 

      return node; 
     } 
    }; 
} 

}`

+0

Метод hasNext() там только проверяет, пуст ли он.Дело в том, чтобы на самом деле проверить, правильно ли был составлен список кругов (всегда возвращаемый true из hasNext()). – FyreeW