Перемещение элементов в ArrayList - PullRequest
66 голосов
/ 09 февраля 2011

Так что я все еще довольно новичок в Java и играю с ArrayList - я пытаюсь добиться метода, который делает что-то вроде этого:

Item 1
Item 2
Item 3
Item 4

Так что я 'Я пытаюсь иметь возможность перемещать элементы вверх в списке, если только он не находится наверху, и в этом случае он останется прежним.Например, если бы пункт 3 был перемещен, список был бы:

Item 1
Item 3
Item 2
Item 4

Из моего небольшого понимания на данный момент, я бы хотел что-то вроде:

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

ЧастьЯ борюсь с тем, чтобы "двигаться вверх".Любые советы или примеры кода того, как этого можно достичь, очень ценятся.

Ответы [ 8 ]

115 голосов
/ 24 января 2012

Я наткнулся на этот старый вопрос, пытаясь найти ответ, и подумал, что просто опубликую найденное мной решение на тот случай, если кто-то другой пройдет здесь и ищет то же самое.

Для обмена 2-мя элементами подойдет Collections.swap. Но если мы хотим переместить больше элементов, есть лучшее решение, предусматривающее творческое использование Collections.sublist и Collections.rotate, о котором я не думал, пока не увидел его описанным здесь:

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

Вот цитата, но зайдите туда и прочитайте все для себя тоже:

Обратите внимание, что этот метод может быть с пользой применен к подспискам, чтобы переместить один или более элементов в списке, сохраняя при этом порядок остальные элементы. Например, следующая идиома перемещает элемент по индексу j вперед на позицию k (которая должна быть больше или равна к j):

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

61 голосов
/ 09 февраля 2011

Простой своп гораздо лучше для «перемещения чего-либо» в ArrayList:

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

Поскольку ArrayList использует массив, если вы удаляете элемент из ArrayList, он должен «сдвигаться»все элементы после этого элемента вверх, чтобы заполнить пробел в массиве.Если вы вставляете элемент, он должен сдвинуть все элементы после этого элемента, чтобы освободить место для его вставки.Эти сдвиги могут быть очень дорогими, если ваш массив очень большой.Поскольку вы знаете, что хотите получить одинаковое количество элементов в списке, такой обмен позволяет вам очень эффективно «переместить» элемент в другое место в списке.

Как Крис Баклери Михал Кройцман отмечают, что в классе Collections есть даже удобный метод для сокращения этих трех строк кода до одной:

Collections.swap(arrayList, i, i-1);
29 голосов
/ 09 февраля 2011

вы можете попробовать этот простой код, Collections.swap (list, i, j) - это то, что вы ищете.

    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);
21 голосов
/ 09 февраля 2011

Чтобы переместиться вверх, удалите, а затем добавьте.

Чтобы удалить - ArrayList.remove и присвоить возвращаемый объект переменной
Затем добавьте этот объект обратно с нужным индексом - ArrayList.add(int index, E element)

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

6 голосов
/ 16 августа 2016

Как писал Миккель перед Collections.rotate, это простой способ.Я использую этот метод для перемещения элементов вверх и вниз в списке.

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);
    }
}
4 голосов
/ 27 октября 2017

К Move элемент в списке просто добавьте:

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

К Swap два элемента в списке просто добавьте:

// swap item 10 with 20
Collections.swap(ObjectList,10,20);
4 голосов
/ 22 декабря 2015

Применение рекурсии для изменения порядка элементов в массиве

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);
                }
            }
    }
0 голосов
/ 11 июня 2015

Перемещение элемента по отношению друг к другу - это то, что мне очень нужно в моем проекте.Поэтому я написал небольшой класс утилит, который перемещает элемент в списке на позицию относительно другого элемента.Не стесняйтесь использовать (и улучшать;))

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;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...