[java] Java의 각 루프마다 역순으로 할 수 있습니까?

Java를 사용하여 List를 역순으로 실행해야합니다.

그래서 이것이 전달되는 곳 :

for(String string: stringList){
//...do something
}

구문 에 대해 를 사용하여 stringList를 역순으로 반복하는 방법이 있습니까?

명확성을 위해 : 목록을 역순으로 반복하는 방법을 알고 있지만 (호기심을 위해) 스타일 에 대해 목록을 수행하는 방법을 알고 싶습니다 .



답변

Collections.reverse 메소드는 실제로 원래 목록의 요소가 역순으로 복사 된 새 목록을 리턴하므로 원래 목록의 크기와 관련하여 O (n) 성능을 갖습니다.

보다 효율적인 솔루션으로 목록의 반전 된보기를 반복 가능으로 표시하는 데코레이터를 작성할 수 있습니다. 데코레이터가 반환 한 반복자는 데코 레이팅 된 목록의 ListIterator를 사용하여 요소를 역순으로 살펴 봅니다.

예를 들면 다음과 같습니다.

public class Reversed<T> implements Iterable<T> {
    private final List<T> original;

    public Reversed(List<T> original) {
        this.original = original;
    }

    public Iterator<T> iterator() {
        final ListIterator<T> i = original.listIterator(original.size());

        return new Iterator<T>() {
            public boolean hasNext() { return i.hasPrevious(); }
            public T next() { return i.previous(); }
            public void remove() { i.remove(); }
        };
    }

    public static <T> Reversed<T> reversed(List<T> original) {
        return new Reversed<T>(original);
    }
}

그리고 당신은 그것을 다음과 같이 사용할 것입니다 :

import static Reversed.reversed;

...

List<String> someStrings = getSomeStrings();
for (String s : reversed(someStrings)) {
    doSomethingWith(s);
}


답변

목록을 보려면 Google Guava Library를 사용할 수 있습니다 .

for (String item : Lists.reverse(stringList))
{
    // ...
}

즉 참고 하지 않습니다Lists.reverse 전체 수집을 반대하거나 같은 것을 할 수는 – 그냥 역순으로, 반복 및 랜덤 액세스 할 수 있습니다. 이것은 컬렉션을 먼저 되 돌리는 것보다 효율적입니다.

임의의 이터 러블을 뒤집으려면, 모든 것을 읽고 나서 거꾸로 “재생”해야합니다.

(당신이 이미 그것을 사용하지 않는 경우, 나는 것 철저하게 당신이 한 번 봐 가지고 추천 구아바를 . 그것은 좋은 물건입니다.)


답변

목록 (집합과 달리)은 순서가 지정된 모음이며이 목록을 반복하면 계약에 따라 주문이 유지됩니다. 스택이 역순으로 반복 될 것으로 예상했지만 불행히도 그렇지 않습니다. 그래서 내가 생각할 수있는 가장 간단한 해결책은 다음과 같습니다.

for (int i = stack.size() - 1; i >= 0; i--) {
    System.out.println(stack.get(i));
}

이것이 “각”루프 솔루션이 아니라는 것을 알고 있습니다. Google 컬렉션과 같은 새로운 라이브러리를 도입하는 것보다 for 루프를 사용하고 싶습니다.

Collections.reverse ()도 작업을 수행하지만 복사본을 역순으로 반환하는 대신 목록을 업데이트합니다.


답변

이것은 원래 목록을 망칠 것이고 루프 외부에서 호출해야합니다. 또한 루프 할 때마다 역전을 수행하고 싶지 않습니다 Iterables.reverse ideas.

Collections.reverse(stringList);

for(String string: stringList){
//...do something
}


답변

AFAIK 표준 라이브러리에는 이미 언어에 늦게 도입 된 구문 설탕 인 for-each 구문을 지원하는 표준 “reverse_iterator”종류가 없습니다.

for (Item 요소 : myList.clone (). reverse ())와 같은 작업을 수행하고 관련 가격을 지불 할 수 있습니다.

이것은 값 비싼 작업을 수행하는 편리한 방법을 제공하지 않는 명백한 현상과 상당히 일치하는 것으로 보입니다. 반복은 O (N ^ 2)가 될 수 있습니다. 물론 ArrayList가 있으면 그 가격을 지불하지 않습니다.


답변

이것은 옵션 일 수 있습니다. while 루프에서 끝까지 마지막 요소부터 시작하는 더 좋은 방법이 있기를 바랍니다.

public static void main(String[] args) {
    List<String> a = new ArrayList<String>();
    a.add("1");a.add("2");a.add("3");a.add("4");a.add("5");

    ListIterator<String> aIter=a.listIterator();
    while(aIter.hasNext()) aIter.next();

    for (;aIter.hasPrevious();)
    {
        String aVal = aIter.previous();
        System.out.println(aVal);
    }
}


답변

현재 주석 : 당신은 아파치 코 몬즈를 사용할 수 있어야합니다ReverseListIterator

Iterable<String> reverse
    = new IteratorIterable(new ReverseListIterator(stringList));

for(String string: reverse ){
    //...do something
}

으로 @rogerdpack 말했다 , 당신은 포장 할 필요가 ReverseListIteratorint로서 Iterable.