programing

Java에서 역순으로 목록 반복

prostudy 2022. 7. 5. 22:08
반응형

Java에서 역순으로 목록 반복

제네릭스를 이용하기 위해 코드를 마이그레이션하고 있습니다.그 이유 중 하나는 for 루프가 인덱스를 추적하거나 명시적 반복기를 사용하는 것보다 훨씬 깨끗하다는 것입니다.

약 절반의 경우 현재 인덱스를 사용하여 목록(ArrayList)을 역순으로 반복하고 있습니다.

더 해 주실 수 있나요?indexed for loop( ( ( ( ( ( ( ( ( ( ( (?

 for (int i = nodes.size() - 1; i >= 0; i--) {
    final Node each = (Node) nodes.get(i);
    ...
 }

주의: JDK 이외의 새로운 의존관계는 추가할 수 없습니다.

이것을 시험해 보세요.

// Substitute appropriate type.
ArrayList<...> a = new ArrayList<...>();

// Add elements to list.

// Generate an iterator. Start just after the last element.
ListIterator li = a.listIterator(a.size());

// Iterate in reverse.
while(li.hasPrevious()) {
  System.out.println(li.previous());
}

Guava는 and를 제공합니다.대부분의 경우처럼, 전자는 논쟁이 후자에 대한 위임입니다.ImmutableList모든 경우에 전자를 사용할 수 있습니다.목록의 새 복사본이 작성되지 않고 목록의 "역방향 보기"만 작성됩니다.

List reversed = ImmutableList.copyOf(myList).reverse();

for loop 구문을 사용하는 것은 불가능하다고 생각합니다.제가 제안할 수 있는 유일한 방법은 다음과 같은 것입니다.

Collections.reverse(list);
for (Object o : list) {
  ...
}

...하지만 효율이 떨어진다는 점을 고려할 때 "더 깨끗하다"고 말할 수는 없습니다.

옵션 1: 목록 with Collections #reverse()를 반전시킨 후 foreach를 사용하는 것에 대해 생각해 본 적이 있습니까?

물론 리스트가 올바르게 정렬되도록 코드를 리팩터링하여 리버스할 필요가 없도록 할 수도 있습니다.그 때문에, 여분의 스페이스/시간이 사용됩니다.


편집:

옵션 2: 또는 Array List 대신 Deque를 사용할 수 있습니까?앞뒤로 반복할 수 있습니다.


편집:

옵션 3: 다른 사용자가 제안했듯이 목록을 반대로 볼 수 있는 반복기를 작성할 수 있습니다.다음은 예를 제시하겠습니다.

import java.util.Iterator;
import java.util.List;

public class ReverseIterator<T> implements Iterator<T>, Iterable<T> {

    private final List<T> list;
    private int position;

    public ReverseIterator(List<T> list) {
        this.list = list;
        this.position = list.size() - 1;
    }

    @Override
    public Iterator<T> iterator() {
        return this;
    }

    @Override
    public boolean hasNext() {
        return position >= 0;
    }

    @Override
    public T next() {
        return list.get(position--);
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

}


List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");

for (String s : new ReverseIterator<String>(list)) {
    System.out.println(s);
}

인 클래스는 하실 수 있습니다.LinkedList interface " " " 대신 " " 가 " "List그리고 역방향으로 반복하기 위한 가 있습니다.

LinkedList<String > linkedList;
for( Iterator<String > it = linkedList.descendingIterator(); it.hasNext(); ) {
    String text = it.next();
}

없을까descendingIteratorArrayList

이것은 오래된 질문이지만, java8 친화적인 답변이 결여되어 있습니다.다음은 스트리밍 API를 사용하여 목록을 역반복하는 몇 가지 방법입니다.

List<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 3, 3, 7, 5));
list.stream().forEach(System.out::println); // 1 3 3 7 5

int size = list.size();

ListIterator<Integer> it = list.listIterator(size);
Stream.generate(it::previous).limit(size)
    .forEach(System.out::println); // 5 7 3 3 1

ListIterator<Integer> it2 = list.listIterator(size);
Stream.iterate(it2.previous(), i -> it2.previous()).limit(size)
    .forEach(System.out::println); // 5 7 3 3 1

// If list is RandomAccess (i.e. an ArrayList)
IntStream.range(0, size).map(i -> size - i - 1).map(list::get)
    .forEach(System.out::println); // 5 7 3 3 1

// If list is RandomAccess (i.e. an ArrayList), less efficient due to sorting
IntStream.range(0, size).boxed().sorted(Comparator.reverseOrder())
    .map(list::get).forEach(System.out::println); // 5 7 3 3 1

(않은) 의이 있습니다.ReverseIterable★★★★★★★★★★★★★★★★★.iterator()하는 것을 말합니다.ReverseIterator을 「」에 간단하게 할 수 있습니다.hasNext()로로 합니다.hasPrevious() 의 콜next() 있다previous() 말은 할 수 있다는 ArrayList다음과 같이 역방향으로 합니다.

ArrayList<String> l = ...
for (String s : new ReverseIterable(l)) {
  System.err.println(s);
}

클래스 정의

public class ReverseIterable<T> implements Iterable<T> {
  private static class ReverseIterator<T> implements Iterator {
    private final ListIterator<T> it;

    public boolean hasNext() {
      return it.hasPrevious();
    }

    public T next() {
      return it.previous();
    }

    public void remove() {
      it.remove();
    }
  }

  private final ArrayList<T> l;

  public ReverseIterable(ArrayList<T> l) {
    this.l = l;
  }

  public Iterator<T> iterator() {
    return new ReverseIterator(l.listIterator(l.size()));
  }
}

리스트가 매우 작기 때문에 퍼포먼스가 문제가 되지 않는 경우는,reverse- metod of the.Lists-클래스Google Guava·생산성이 좋다for-each-code, 원래 목록은 그대로 유지됩니다.또한 반전 리스트는 원래 리스트로 백업되므로 원래 리스트의 변경은 반전 리스트로 반영됩니다.

import com.google.common.collect.Lists;

[...]

final List<String> myList = Lists.newArrayList("one", "two", "three");
final List<String> myReverseList = Lists.reverse(myList);

System.out.println(myList);
System.out.println(myReverseList);

myList.add("four");

System.out.println(myList);
System.out.println(myReverseList);

다음과 같은 결과를 얻을 수 있습니다.

[one, two, three]
[three, two, one]
[one, two, three, four]
[four, three, two, one]

즉, myList의 역방향 반복은 다음과 같이 기술할 수 있습니다.

for (final String someString : Lists.reverse(myList)) {
    //do something
}

사용할 수 있습니다.ReverseListIteratorApache Commons-Collections:

https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/iterators/ReverseListIterator.html

매우 간단한 예:

List<String> list = new ArrayList<String>();

list.add("ravi");

list.add("kant");

list.add("soni");

// Iterate to disply : result will be as ---     ravi kant soni

for (String name : list) {
  ...
}

//Now call this method

Collections.reverse(list);

// iterate and print index wise : result will be as ---     soni kant ravi

for (String name : list) {
  ...
}

커스텀 작성reverseIterable.

구글 컬렉션의 역방향 메서드도 찾았습니다.

다음과 같은 코드를 가지려면:

List<Item> items;
...
for (Item item : In.reverse(items))
{
    ...
}

다음 코드를 "In.java"라는 파일에 넣습니다.

import java.util.*;

public enum In {;
    public static final <T> Iterable<T> reverse(final List<T> list) {
        return new ListReverseIterable<T>(list);
    }

    class ListReverseIterable<T> implements Iterable<T> {
        private final List<T> mList;

        public ListReverseIterable(final List<T> list) {
            mList = list;
        }

        public Iterator<T> iterator() {
            return new Iterator<T>() {
                final ListIterator<T> it = mList.listIterator(mList.size());

                public boolean hasNext() {
                    return it.hasPrevious();
                }
                public T next() {
                    return it.previous();
                }
                public void remove() {
                    it.remove();
                }
            };
        }
    }
}

적어도 두 번 제안되었듯이,descendingIterator와 함께Deque특히,LinkedList각 루프를 사용하는 경우(즉,Iterable)는 다음과 같은 wraper를 구축하여 사용할 수 있습니다.

import java.util.*;

public class Main {

    public static class ReverseIterating<T> implements Iterable<T> {
        private final LinkedList<T> list;

        public ReverseIterating(LinkedList<T> list) {
            this.list = list;
        }

        @Override
        public Iterator<T> iterator() {
            return list.descendingIterator();
        }
    }

    public static void main(String... args) {
        LinkedList<String> list = new LinkedList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        list.add("E");

        for (String s : new ReverseIterating<String>(list)) {
            System.out.println(s);
        }
    }
}
Valid for Java 9+

List<String> strList = List.of("a", "b", "c", "d", "e");

IntStream.iterate(strList.size() - 1, i -> i >= 0, i -> --i)
         .mapToObj(strList::get)
         .forEach(System.out::println);

이유: "Array List를 가진 내림차순 반복기가 없는 이유를 알 수 없습니다.."

배열 목록은 목록에 데이터가 추가된 순서와 동일한 순서로 목록을 유지하지 않기 때문입니다.따라서 Arraylist는 사용하지 마십시오.

Linked List는 ADD to 목록과 동일한 순서로 데이터를 유지합니다.

위의 예에서는 ArrayList()를 사용하여 사용자가 마음을 비뚤어지게 하고 사용자가 자신의 입장에서 무언가를 하도록 했습니다.

이것 대신에

List<String> list = new ArrayList<String>();

용도:

List<String> list = new LinkedList<String>();

list.add("ravi");

list.add("kant");

list.add("soni");

// Iterate to disply : result will be as ---     ravi kant soni

for (String name : list) {
  ...
}

//Now call this method

Collections.reverse(list);

// iterate and print index wise : result will be as ---     soni kant ravi

for (String name : list) {
  ...
}

언급URL : https://stackoverflow.com/questions/2102499/iterating-through-a-list-in-reverse-order-in-java

반응형