2011-02-08 15 views
50

Więc nadal jestem całkiem nowy, Java i byłem zabawy z ArrayList firmy - co próbuję osiągnąć to sposób zrobić coś takiego:Przenoszenie pozycji wokół w ArrayList

Item 1 
Item 2 
Item 3 
Item 4 

Próbuję więc przenieść elementy na liście, chyba że jest już na górze, w takim przypadku pozostanie taka sama. Na przykład, jeśli pozycja 3 został przeniesiony lista będzie:

Item 1 
Item 3 
Item 2 
Item 4 

Z mojego małego zrozumienia w tej chwili to bym chciał coś wzdłuż linii:

IF arrayname index is not equal to 0 
THEN move up 
ELSE do nothing 

Część I zmagam with jest częścią "przesuń się". Wszelkie wskazówki lub przykłady kodu, jak można to osiągnąć, są doceniane.

Odpowiedz

94

natknąłem tym starym pytanie w moim poszukiwaniu odpowiedzi, a ja myślałem, że po prostu zakładać rozwiązanie znalazłem w przypadku gdy ktoś inny przechodzi tu w poszukiwaniu samo.

Do zamiany 2 elementów, Collections.swap jest w porządku. Ale jeśli chcemy, aby przenieść więcej elementów, jest to lepsze rozwiązanie, które polega na twórcze wykorzystanie Collections.sublist i Collections.rotate, że nie miał na myśli, dopóki nie zobaczyłem to opisane tutaj:

http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#rotate%28java.util.List,%20int%29

Oto cytat, ale tam i przeczytać całość dla siebie zbyt:

należy zauważyć, że metoda ta może być z powodzeniem stosowany do podlist przenieść jeden lub więcej elementów w obrębie listy zachowując kolejność pozostały elementy.Na przykład, następujące idiom przesuwa element o indeksie j do przodu do pozycji k (która musi być większa lub równa do j):

Collections.rotate(list.subList(j, k+1), -1);

+2

W mojej aplikacji ten obrót podrzędny wydawał się wolniejszy niż opisana tutaj metoda usuwania/wstawiania: http://stackoverflow.com/a/4938696/1025391 – moooeeeep

+2

'większy niż lub równy (> =)'? a co z '<='? – user25

15

Aby przejść do góry, usuń, a następnie dodaj.

Aby usunąć - ArrayList.remove i przypisać zwrócony obiekt do zmiennej
Następnie dodać ten obiekt z powrotem na wymaganym Główna - ArrayList.add(int index, E element)

http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html#add(int, E)

+2

To jedyne rozwiązanie, które faktycznie działa, aby zmienić kolejność elementy w ArrayList. Dzięki! – mpemburn

+1

Bardzo elegancko! – geekQ

+0

z usunięciem nie porusza się, zmienia położenie dwóch obiektów (zamiana), przesuwa się - przesuwa jeden obiekt między dwoma innymi obiektami – user25

52

Prosta zamiana jest znacznie lepiej " przesuwając coś”w ArrayList:

if(i > 0) { 
    Item toMove = arrayList.get(i); 
    arrayList.set(i, arrayList.get(i-1)); 
    arrayList.set(i-1, toMove); 
} 

Ponieważ ArrayList wykorzystuje tablicę, jeśli usunąć element z ArrayList, musi "przesunąć" wszystkie elementy po tym obiekcie w górę, aby wypełnić lukę w tablicy. Jeśli wstawisz przedmiot, musi on przesunąć wszystkie elementy po tym elemencie, aby zrobić miejsce na jego wstawienie. Te przesunięcia mogą stać się bardzo kosztowne, jeśli twoja macierz jest bardzo duża. Ponieważ wiesz, że chcesz skończyć z taką samą liczbą elementów na liście, wykonanie takiej zamiany pozwala "bardzo skutecznie" przenieść element do innej lokalizacji na liście.

Jako Chris Buckler i Michał Kreuzman podkreślić, nie jest nawet przydatna metoda w zbiorach klasy w celu zmniejszenia tych trzech linijek kodu do jednego:

Collections.swap(arrayList, i, i-1); 
+0

To jest świetne, collections.swap wydaje się być idealny. Jednym drobnym problemem, na który zwróciłem uwagę, jest to, że użycie tego jednego na początku listy powoduje wyjątek poza zakresem - nadal działa tak, jak chciałem, ale czy jest jakiś sposób, aby powstrzymać go przed wyrzuceniem wyjątku poza granice? – user319940

+1

@ user319940 Hi StriplingWarrior pokazał go w pierwszym przykładzie kodu. Indeks musi być większy niż 0 'if (i> 0)' –

+0

hej, głupi mnie, próbowałem go, zamiast zamiast - jeśli jeszcze raz dziękuję wszystkim. Mam nadzieję, że ten post pomoże również innym w przyszłości. – user319940

23

można spróbować tego prostego kodu, Collections.swap (lista, i, j) jest tym, czego szukasz.

List<String> list = new ArrayList<String>(); 
    list.add("1"); 
    list.add("2"); 
    list.add("3"); 
    list.add("4"); 

    String toMoveUp = "3"; 
    while (list.indexOf(toMoveUp) != 0) { 
     int i = list.indexOf(toMoveUp); 
     Collections.swap(list, i, i - 1); 
    } 

    System.out.println(list); 
+2

+1 za użycie podejścia Ogólnego. – Sid

0

Przenoszenie elementu w stosunku do siebie jest czymś Wiele potrzebowałem w moim projekcie. Napisałem więc małą klasę util, która przenosi element na liście do pozycji względem innego elementu. Zapraszam do korzystania (i ulepszyć;))

import java.util.List; 

public class ListMoveUtil 
{ 
    enum Position 
    { 
     BEFORE, AFTER 
    }; 

    /** 
    * Moves element `elementToMove` to be just before or just after `targetElement`. 
    * 
    * @param list 
    * @param elementToMove 
    * @param targetElement 
    * @param pos 
    */ 
    public static <T> void moveElementTo(List<T> list, T elementToMove, T targetElement, Position pos) 
    { 
     if (elementToMove.equals(targetElement)) 
     { 
      return; 
     } 
     int srcIndex = list.indexOf(elementToMove); 
     int targetIndex = list.indexOf(targetElement); 
     if (srcIndex < 0) 
     { 
      throw new IllegalArgumentException("Element: " + elementToMove + " not in the list!"); 
     } 
     if (targetIndex < 0) 
     { 
      throw new IllegalArgumentException("Element: " + targetElement + " not in the list!"); 
     } 
     list.remove(elementToMove); 

     // if the element to move is after the targetelement in the list, just remove it 
     // else the element to move is before the targetelement. When we removed it, the targetindex should be decreased by one 
     if (srcIndex < targetIndex) 
     { 
      targetIndex -= 1; 
     } 
     switch (pos) 
     { 
      case AFTER: 
       list.add(targetIndex + 1, elementToMove); 
       break; 
      case BEFORE: 
       list.add(targetIndex, elementToMove); 
       break; 
     } 
    } 
3

Zastosowanie rekurencji, aby zmienić kolejność elementów w arraylist

public class ArrayListUtils { 
      public static <T> void reArrange(List<T> list,int from, int to){ 
       if(from != to){ 
        if(from > to) 
         reArrange(list,from -1, to); 
         else 
         reArrange(list,from +1, to); 

        Collections.swap(list, from, to); 
       } 
      } 
    } 
2

Jak Mikkel pisał przed Collections.rotate to prosty sposób. Używam tej metody do przenoszenia przedmiotów w górę i w dół na liście.

public static <T> void moveItem(int sourceIndex, int targetIndex, List<T> list) { 
    if (sourceIndex <= targetIndex) { 
     Collections.rotate(list.subList(sourceIndex, targetIndex + 1), -1); 
    } else { 
     Collections.rotate(list.subList(targetIndex, sourceIndex + 1), 1); 
    } 
} 
1

Aby Move pozycji na liście wystarczy dodać:

// move item to index 0 
Object object = ObjectList.get(index); 
ObjectList.remove(index); 
ObjectList.add(0,object); 

Do Swap dwie pozycje w liście wystarczy dodać:

// swap item 10 with 20 
Collections.swap(ObjectList,10,20);