Dr. Azrael Tod
Dr. Azrael Tod

Reputation: 579

Java Iterator Loop once, start in middle

I have an Iterator - placed somewhere in the middle of my collection.

I want to loop over the collection from there on, returning a special element if I find it.

If I reach !hasNext() then I want to start at the begining, but I want to stop if I reach the place where I started first.

The best Idea how to solve that seems currently to save the "first" (wherever the iterator pointed when I started) element and then stop if I find that one again.

And that works as long as items can occure only once in my collection (i.e. in a HasSet).

Any better ideas how to do such thing? Iterator doesn't seem to supply a pointer/number back to me that I could compare.

Upvotes: 3

Views: 2385

Answers (4)

Etienne Savary
Etienne Savary

Reputation: 19

To start to iterate a Set from a definedValue I do :

    public void iterate(Set<Sample> set, Sample definedValue){
        Iterator<Sample> iterator = set.iterator();
        while(iterator.hasNext()){
            Sample currentSample = iterator.next();
            if(currentSample.equals(definedValue)){
                while(iterator.hasNext()){
                Sample sampleToConsider = iterator.next();
                //Then do anything
                }
            }
        }
    }

Upvotes: 0

VidhyaRani
VidhyaRani

Reputation: 33

If the collection is a list, then it can be done with below code

private void Object traverseList(List namesList, int startIndex ) {
    int index = 0;
    Iterator iterator = namesList.listIterator(startIndex);
    while (iterator.hasNext() && index < namesList.size()){
        Object element = iterator.next();
        /*if(element.isSpecialElement()){
         return element;
         }
        */
        index++;
        System.out.println(element);
        if(!iterator.hasNext()){
            iterator = namesList.iterator();
        }
    }
}

Since you want to transverse all the elements in the list, I am making use of list size. And during iteration, if the special element is found, it can be returned.

Upvotes: 0

Sync
Sync

Reputation: 3777

The solution becomes more simple if you:

  • Don't use Iterator, it makes it more complicated
  • Use a List instead of Set as Set is ill-suited for this use case

    public static void main(String[] args) {
        Set<String> yourStartingCollection = new HashSet<>();
        List<String> fooList = new ArrayList<>(yourStartingCollection);
    
        Optional<String> specialElement = findSpecialElementStartingFromMiddle(fooList);
        if (specialElement.isPresent()) {
            // found it!
        }
    }
    
    private static Optional<String> findSpecialElementStartingFromMiddle(List<String> elements) {
        int middleIndex = elements.size() / 2;
        Optional<String> result = Optional.empty();
    
        for (int i = middleIndex; i < elements.size(); i++) {
            String element = elements.get(i);
            if (isSpecial(element)) {
                result = Optional.of(element);
                break;
            }
        }
    
        if (result.isPresent()) {
            return result;
        }
    
        for (int i = 0; i < middleIndex; i++) {
            String element = elements.get(i);
            if (isSpecial(element)) {
                result = Optional.of(element);
                break;
            }
        }
    
        return result;
    }
    
    private static boolean isSpecial(String element) {
        return element.equals("I'm special");
    }
    

Upvotes: -1

smac89
smac89

Reputation: 43078

With Guava Iterators (Java 7):

Iterator<YourType> iterator = Iterators.concat(yourIteratorPlaceSomewhereInMiddle, Iterators.limit(yourCollection.iterator(), positionOfSomewhereInMiddle));

With Streams (Java 8):

Optional<YourType> theAnswer = IntStream.iterate(positionOfSomewhereInMiddle, pos -> ++pos)
                                        .map(pos -> pos % sizeOfCollection)
                                        .mapToObj(yourCollection::get)
                                        .limit(sizeOfCollection)
                                        .filter(element -> element is 42)
                                        .findFirst();

Upvotes: 2

Related Questions