ArrayList를 되 돌리는 가장 간단한 방법은 무엇입니까?


333

이 ArrayList를 되 돌리는 가장 간단한 방법은 무엇입니까?

ArrayList<Integer> aList = new ArrayList<>();

//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");

while (aList.listIterator().hasPrevious())
  Log.d("reverse", "" + aList.listIterator().previous());

답변:


798
Collections.reverse(aList);

예 ( 참조 ) :

ArrayList aList = new ArrayList();
//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");
Collections.reverse(aList);
System.out.println("After Reverse Order, ArrayList Contains : " + aList);

2
@ AgarwalShankar 오류가 발생했습니다 ArrayList void를 발견했습니다. 내가 뭔가를 놓치고 있습니까?
Sagar Devanga

9
@SagarDevanga 목록이 제자리로 되돌려지고 반환되지 않습니다.
Carcigenicate

Collections.reverse (목록); 나는 안드로이드 프로젝트에서 그것을 사용했고, 잘 작동했다.
Damir Varevac

22

가장 간단한 방법은 아니지만 재귀의 팬이라면 ArrayList를 뒤집는 다음 방법에 관심이있을 수 있습니다.

public ArrayList<Object> reverse(ArrayList<Object> list) {
    if(list.size() > 1) {                   
        Object value = list.remove(0);
        reverse(list);
        list.add(value);
    }
    return list;
}

또는 비재 귀적으로 :

public ArrayList<Object> reverse(ArrayList<Object> list) {
    for(int i = 0, j = list.size() - 1; i < j; i++) {
        list.add(i, list.remove(j));
    }
    return list;
}

나는 틀릴 수도 있지만 비 재귀 적 인 예제에서 int j각 반복으로 업데이트되지 않습니까? 당신은 그것을 초기화 j = list.size() - 1하지만 각 반복마다 업데이트 섹션의 초기화 섹션 for loop이 업데이트 한다고 생각 하지 않습니까?
Tony Chan

@Turbo j는 반복 할 때마다 업데이트 할 필요가 없습니다. ArrayList의 마지막 인덱스로 초기화되며 마지막 요소에 액세스하는 데 사용됩니다. for 루프 내에서 마지막 요소가 제거되어 인덱스 i에 삽입됩니다. ArrayList에서 마지막 위치 옆에 도달 할 때까지 i가 증가합니다.
todd

1
예, 그러나 두 번째 반복에서는 IndexOutOfBoundsException액세스 j(원래 ArrayList의 마지막 인덱스)를 시도한 이후 에 해당 인덱스에서 객체를 이미 제거한 후에 얻을 수 있습니까?
Tony Chan

1
죄송합니다. 코드를 실행 한 것이 확실합니다. add()다른 요소를 배열 아래로 밀어내는 것을 잊어 버렸 으므로 배열은 기본적으로 일정한 크기를 유지합니다. 흥미로운 솔루션, 감사합니다!
Tony Chan

또한 호기심이 많지만 재귀 방법을 어떻게 생각해 냈습니까? 나는 그것이 일반적으로 생각할 것이라고 생각하지 않습니다.
Tony Chan

13

여기서의 요령은 "리버스"를 정의하는 것입니다. 목록을 제자리에서 수정하거나, 복사본을 역순으로 만들거나, 역순으로보기를 만들 수 있습니다.

직관적으로 말하면 가장 간단한 방법 은 Collections.reverse다음과 같습니다.

Collections.reverse(myList);

이 방법 은 목록을 수정합니다 . 즉, Collections.reverse목록을 가져 와서 요소를 덮어 쓰므 로 되돌릴 수없는 사본은 남기지 않습니다. 일부 사용 사례에는 적합하지만 다른 사용 사례에는 적합하지 않습니다. 또한 목록을 수정할 수 있다고 가정합니다. 이것이 받아 들여지면 좋다.


그렇지 않은 경우 사본을 역순으로 만들있습니다 .

static <T> List<T> reverse(final List<T> list) {
    final List<T> result = new ArrayList<>(list);
    Collections.reverse(result);
    return result;
}

이 방법은 효과가 있지만 목록을 두 번 반복해야합니다. 복사 생성자 ( new ArrayList<>(list))는 목록을 반복하며 Collections.reverse. 우리가 기울어지면이 방법을 한 번만 반복하도록 다시 작성할 수 있습니다.

static <T> List<T> reverse(final List<T> list) {
    final int size = list.size();
    final int last = size - 1;

    // create a new list, with exactly enough initial capacity to hold the (reversed) list
    final List<T> result = new ArrayList<>(size);

    // iterate through the list in reverse order and append to the result
    for (int i = last; i >= 0; --i) {
        final T element = list.get(i);
        result.add(element);
    }

    // result now holds a reversed copy of the original list
    return result;
}

이것은 더 효율적이지만 더 장황합니다.

또는 Java 8의 streamAPI 를 사용하기 위해 위의 내용을 다시 작성할 수 있습니다. 일부 사람들 은 위의 것보다 간결하고 읽기 쉽습니다.

static <T> List<T> reverse(final List<T> list) {
    final int last = list.size() - 1;
    return IntStream.rangeClosed(0, last) // a stream of all valid indexes into the list
        .map(i -> (last - i))             // reverse order
        .mapToObj(list::get)              // map each index to a list element
        .collect(Collectors.toList());    // wrap them up in a list
}

nb. 그 Collectors.toList()결과 목록에 대한 거의 보장한다. 결과가 ArrayList로 돌아 오도록하려면 Collectors.toCollection(ArrayList::new)대신 사용하십시오.


세 번째 옵션은 역순으로보기만드는 것 입니다. 이것은 더 복잡한 해결책이며, 더 읽을 거리 / 자신의 질문에 합당합니다. 구아바의 Lists # reverse 방법은 실행 가능한 출발점입니다.

"가장 간단한"구현을 선택하는 것은 독자를위한 연습으로 남아 있습니다.


6

추가 ArrayList 또는 add () 및 remove () 메소드 조합을 사용하지 않는 솔루션. 큰 목록을 뒤집어 야하는 경우 둘 다 부정적인 영향을 줄 수 있습니다.

 public ArrayList<Object> reverse(ArrayList<Object> list) {

   for (int i = 0; i < list.size() / 2; i++) {
     Object temp = list.get(i);
     list.set(i, list.get(list.size() - i - 1));
     list.set(list.size() - i - 1, temp);
   }

   return list;
 }

5
ArrayList<Integer> myArray = new ArrayList<Integer>();

myArray.add(1);
myArray.add(2);
myArray.add(3);

int reverseArrayCounter = myArray.size() - 1;

for (int i = reverseArrayCounter; i >= 0; i--) {
    System.out.println(myArray.get(i));
}

2

요소를 추가하기 위해 새 목록을 만들지 않고 재귀 방식으로 ArrayList를 뒤집습니다.

   public class ListUtil {

    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("1");
        arrayList.add("2");
        arrayList.add("3");
        arrayList.add("4");
        arrayList.add("5");
        System.out.println("Reverse Order: " + reverse(arrayList));

    }

    public static <T> List<T> reverse(List<T> arrayList) {
        return reverse(arrayList,0,arrayList.size()-1);
    }
    public static <T> List<T> reverse(List<T> arrayList,int startIndex,int lastIndex) {

        if(startIndex<lastIndex) {
            T t=arrayList.get(lastIndex);
            arrayList.set(lastIndex,arrayList.get(startIndex));
            arrayList.set(startIndex,t);
            startIndex++;
            lastIndex--;
            reverse(arrayList,startIndex,lastIndex);
        }
        return arrayList;
    }

}

1

그냥 우리가 사용하는 경우 자바 (8) , 우리는 스트림의 사용을 할 수 있습니다. ArrayList는 랜덤 액세스 목록이며, 요소 스트림을 역순으로 가져 와서 새로운 것으로 수집 할 수 ArrayList있습니다.

public static void main(String[] args) {
        ArrayList<String> someDummyList = getDummyList();
        System.out.println(someDummyList);
        int size = someDummyList.size() - 1;
        ArrayList<String> someDummyListRev = IntStream.rangeClosed(0,size).mapToObj(i->someDummyList.get(size-i)).collect(Collectors.toCollection(ArrayList::new));
        System.out.println(someDummyListRev);
    }

    private static ArrayList<String> getDummyList() {
        ArrayList dummyList = new ArrayList();
        //Add elements to ArrayList object
        dummyList.add("A");
        dummyList.add("B");
        dummyList.add("C");
        dummyList.add("D");
        return dummyList;
    }

위의 방법은 임의 액세스가 아니므로 LinkedList에 적합하지 않습니다. instanceof확인 에도 사용할 수 있습니다 .


1

Java 8을 사용하여 동일한 작업을 수행 할 수도 있습니다.

public static<T> List<T> reverseList(List<T> list) {
        List<T> reverse = new ArrayList<>(list.size());

        list.stream()
                .collect(Collectors.toCollection(LinkedList::new))
                .descendingIterator()
                .forEachRemaining(reverse::add);

        return reverse;
    }

0

조금 더 읽기 :)

public static <T> ArrayList<T> reverse(ArrayList<T> list) {
    int length = list.size();
    ArrayList<T> result = new ArrayList<T>(length);

    for (int i = length - 1; i >= 0; i--) {
        result.add(list.get(i));
    }

    return result;
}

0

또 다른 재귀 솔루션

 public static String reverse(ArrayList<Float> list) {
   if (list.size() == 1) {
       return " " +list.get(0);
   }
   else {
       return " "+ list.remove(list.size() - 1) + reverse(list);
   } 
 }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.