Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving items around in an ArrayList

Tags:

java

arraylist

I've been playing around with ArrayLists. What I'm trying to achieve is a method to do something like this:

Item 1
Item 2
Item 3
Item 4

I'm trying to be able to move items up in the list, unless it is already at the top in which case it will stay the same. For example, if item 3 was moved the list would be:

Item 1
Item 3
Item 2
Item 4

From my small understanding at the moment then I would want something along the lines of:

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

The part I'm struggling with is the "move up" part. Any tips or code samples of how this could be achieved are much appreciated.

like image 785
user319940 Avatar asked Feb 08 '11 21:02

user319940


People also ask

How do you rearrange ArrayList in Java?

Approach: An ArrayList can be Sorted by using the sort() method of the Collections Class in Java. This sort() method takes the collection to be sorted as the parameter and returns a Collection sorted in the Ascending Order by default.

How do you rearrange an element in a list in Java?

Use the JDK's swap method The JDK's Collections class contains a method just for this purpose called Collections. swap. According to the API documentation this method allows you to "swap the elements at the specified positions in the specified list."

Can ArrayList store different objects?

The Java collection classes, including ArrayList, have one major constraint: they can only store pointers to objects, not primitives. So an ArrayList can store pointers to String objects or Color objects, but an ArrayList cannot store a collection of primitives like int or double.

Does .equals work for ArrayLists?

Java provides a method for comparing two Array List. The ArrayList. equals() is the method used for comparing two Array List. It compares the Array lists as, both Array lists should have the same size, and all corresponding pairs of elements in the two Array lists are equal.


9 Answers

I came across this old question in my search for an answer, and I thought I would just post the solution I found in case someone else passes by here looking for the same.

For swapping 2 elements, Collections.swap is fine. But if we want to move more elements, there is a better solution that involves a creative use of Collections.sublist and Collections.rotate that I hadn't thought of until I saw it described here:

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

Here's a quote, but go there and read the whole thing for yourself too:

Note that this method can usefully be applied to sublists to move one or more elements within a list while preserving the order of the remaining elements. For example, the following idiom moves the element at index j forward to position k (which must be greater than or equal to j):

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

like image 171
Mikkel Avatar answered Oct 13 '22 06:10

Mikkel


A simple swap is far better for "moving something up" in an ArrayList:

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

Because an ArrayList uses an array, if you remove an item from an ArrayList, it has to "shift" all the elements after that item upward to fill in the gap in the array. If you insert an item, it has to shift all the elements after that item to make room to insert it. These shifts can get very expensive if your array is very big. Since you know that you want to end up with the same number of elements in the list, doing a swap like this allows you to "move" an element to another location in the list very efficiently.

As Chris Buckler and Michal Kreuzman point out, there is even a handy method in the Collections class to reduce these three lines of code to one:

Collections.swap(arrayList, i, i-1);
like image 23
StriplingWarrior Avatar answered Oct 13 '22 05:10

StriplingWarrior


you can try this simple code, Collections.swap(list, i, j) is what you looking for.

    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);
like image 29
michal.kreuzman Avatar answered Oct 13 '22 04:10

michal.kreuzman


To move up, remove and then add.

To remove - ArrayList.remove and assign the returned object to a variable
Then add this object back at the required index -ArrayList.add(int index, E element)

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

like image 41
Amol Katdare Avatar answered Oct 13 '22 04:10

Amol Katdare


As Mikkel posted before Collections.rotate is a simple way. I'm using this method for moving items up- and downward in a List.

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);
    }
}
like image 34
marwils Avatar answered Oct 13 '22 04:10

marwils


To Move item in list simply add:

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

To Swap two items in list simply add:

// swap item 10 with 20
Collections.swap(ObjectList,10,20);
like image 41
Amir Hossein Ghasemi Avatar answered Oct 13 '22 06:10

Amir Hossein Ghasemi


Applying recursion to reorder items in an 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);
                }
            }
    }
like image 44
Michel Durieux Avatar answered Oct 13 '22 04:10

Michel Durieux


Moving element with respect to each other is something I needed a lot in a project of mine. So I wrote a small util class that moves an element in an list to a position relative to another element. Feel free to use (and improve upon ;))

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;
        }
    }
like image 43
Rob Audenaerde Avatar answered Oct 13 '22 04:10

Rob Audenaerde


Start from toIndex and shift nearby elements until it reaches fromIndex. Finally set element at fromIndex to toIndex.

fun <E> ArrayList<E>.move(fromIndex: Int, toIndex: Int) {
    if (fromIndex >= size || fromIndex < 0) {
        throw IndexOutOfBoundsException(outOfBoundsMsg(fromIndex, size))
    }
    if (toIndex >= size || toIndex < 0) {
        throw IndexOutOfBoundsException(outOfBoundsMsg(toIndex, size))
    }
    if (fromIndex == toIndex) return
    var index = toIndex
    var item = get(index)
    if (fromIndex > toIndex) {
        while (index < fromIndex) {
            index++
            item = set(index, item)
        }
    } else {
        while (index > fromIndex) {
            index--
            item = set(index, item)
        }
    }
    set(toIndex, item)
}

private fun outOfBoundsMsg(index: Int, size: Int): String {
    return "Index: $index, Size: $size"
}
like image 22
UdaraWanasinghe Avatar answered Oct 13 '22 06:10

UdaraWanasinghe