Java 迭代器循环一次,从中间开始



我有一个迭代器 - 放在我收藏中间的某个地方。

我想从那里循环访问集合,如果我找到它,则返回一个特殊元素。

如果我到达

!hasNext(),那么我想从头开始,但如果我到达我首先开始的地方,我想停止。

目前如何解决这个问题的最好主意似乎是保存"第一个"(迭代器在我开始时指向的任何地方)元素,然后在我再次找到那个元素时停止。

只要项目在我的集合中只能出现一次(即在 HasSet 中),这就可以工作。

有什么更好的想法如何做这样的事情吗?迭代器似乎没有向我提供我可以比较的指针/数字。

使用 Guava 迭代器 (Java 7):

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

使用 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();

如果集合是一个列表,那么可以使用以下代码来完成

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();
        }
    }
}

由于您要横向列表中的所有元素,因此我正在使用列表大小。并且在迭代过程中,如果找到特殊元素,则可以返回。

要开始从定义的值迭代 Set,我这样做:

    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
                }
            }
        }
    }

如果您:

  • 不要使用Iterator,这会让它更复杂
  • 使用List而不是Set Set不适合此用例

    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");
    }
    

最新更新