2013-12-03 4 views
1

Есть ли итератор для циклического преобразования структуры данных в циклы?Создание структуры данных в Java

Допустим есть массив:

int[] arr = {-1,5,7,-1,-1,-1} 

Я хочу индекс находки первого, не значение -1 из этого массива и начинает поиска от случайной позиции (IDX = random.nextInt (arr.length)). Например idx = 4;

Итак, сначала проверьте, если arr [4] == -1, то если arr [5] == -1 и так далее. Если конец массива достигнут тогда, начните с позиции 0 и продолжайте до тех пор, пока не будет найдено -1. Гарантируется, что в массиве будет хотя бы одно значение, не равное -1.

Это можно сделать так:

int idx = -1; 
for (int i = random.nextInt(arr.length); ; i++) { 
    if (i == arr.length) { 
     /** start over */ 
     i = 0; 
    } 
    if (-1 != arr[i]) { 
     idx = i; 
     break; 
    } 
} 

Или так:

int idx = -1; 
int i = random.nextInt(arr.length); 

do { 
    if (-1 != arr[i]) { 
     idx = i; 
    }  
    i == arr.length ? i=0 : i++; 
} while (-1 == idx); 

Есть итератор, который поддерживает велосипедный (слово следующему(), если конец массива достигается автоматически начать от 0)?

Ограничения: 1) эффективность не учитывается; 2) стандартным Java API является предпочтительным.

+1

Можно построить такой итератор, но он будет менее понятным, менее эффективным и менее простым, чем использование уже существующих циклов. – Boann

ответ

2

В java API нет такого api, который удовлетворит вашу проблему, но вы можете сделать это самостоятельно.

что вы можете сделать, это использовать List для создания LinkedList. для решения вашей проблемы.

вы можете расширить List к классу (CircularLinkedList extends List) & затем переопределить метод hasNext() & getNext() Это все что вам нужно.

1

Я не думаю, что есть итераторы, которые сообщают вам об индексе элемента, как вы звоните next(), поэтому вам нужно будет отслеживать текущий индекс отдельно. Возможно, вы сможете создать итератор «обертки», используя Guava's Iterators.concat (или какой-либо другой сторонний класс), чтобы объединить итератор над конечной частью массива с итератором над ведущей частью. Тем не менее, я думаю, что код, вероятно, будет более сложным, чем простой цикл for или два.

1

Я считаю, что нет такого кругового итератора, который автоматически перейдет к началу массива после достижения конца. Я создал один из них ниже (не тестировался, а дизайн испорчен), для которого требуется совершенно новый класс кода, и он намного длиннее, чем ваш короткий цикл/while.

public class MyCircularIterator<E> implements Iterator<E> { 
    private List<E> list; 
    private int pos; 

    public MyCircularIterator(List<E> list) { 
     this(list, 0); 
    } 

    public MyCircularIterator(List<E> list, int start) { 
     this.list = list; 
     pos = start; 
    } 

    public boolean hasNext() { 
     if(list.get(pos) != -1) return false; 
      return true; 
    } 

    public E next() { 
     if(hasNext()) { 
      E obj = list.get(pos); 
      pos = (pos + 1) % list.size(); 
      return obj; 
     } 
    } 

    public void remove() { 
     list.remove(this.nextIndex); 
    } 
} 
Смежные вопросы