2011-02-08 6 views
50

の周りのアイテムを移動するので、私はまだJavaへかなり新しいだと私は、ArrayListのので遊んでてきた - 私は何を達成しようとしていることは、このような何かを行うための方法である:ArrayListの

Item 1 
Item 2 
Item 3 
Item 4 

私はリスト内の項目を上に移動できるようにしようとしています。項目3が移動された場合例えば、リストは次のようになります。私は苦労してる

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

一部:

Item 1 
Item 3 
Item 2 
Item 4 

を現時点での私の小さな理解から、私はの線に沿って何かをしたいと思いますと一緒に "上に移動する"部分です。どのようにこれを達成することができるかのヒントやコードサンプルは高く評価されています。

答えて

94

私は答えのための私の検索では、この古い質問に出くわした、と私はちょうど他の誰かが同じを探してここを通過する場合には私が見つけた解決策を投稿するだろうと思いました。

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

ここで引用だが、そこに行くと、あまりにも自分のために全体をお読みください。この方法が有効残り の順序を維持しながら、リスト内1つの 以上の要素を移動するためにサブリストに適用することができることを

注意を要素。例えば、次の慣用法は、(より大きいまたはJに 等しくなければならない)の位置kにフォワードインデックスjにある要素 を移動:

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

+2

私のアプリケーションでは、このサブリストのローテーションはここに記載されているremove/insert-approachよりも遅いようです:http://stackoverflow.com/a/4938696/1025391 – moooeeeep

+2

'greater than or equal(> =)'? '<='についてはどうですか? – user25

15

上に移動するには、削除してから追加します。 ArrayList.add(int index, E element)

​​、E)

+2

をこれは実際の順序を変更するには働く唯一のソリューションですArrayList内のアイテムありがとう! – mpemburn

+1

本当にエレガント! – geekQ

+0

それを取り除くと、2つのオブジェクトの位置が変わります(スワップ) - 移動すると、他の2つのオブジェクト間で1つのオブジェクトが移動します – user25

52

シンプルスワップ "のためにはるかに優れている - そして、必要なインデックスでは、このオブジェクトを再度追加ArrayList.removeを、変数
に返されたオブジェクトを割り当てる -

を削除するにはArrayList内のアイテムを移動する場合:

ArrayListは配列を使用するため、ArrayListから項目を削除すると、その項目の後ろのすべての要素を配列のギャップを埋めるように「シフト」しなければなりません。アイテムを挿入する場合は、そのアイテムの後にあるすべてのエレメントを移動して挿入するスペースを確保する必要があります。配列が非常に大きい場合、これらのシフトは非常に高価になることがあります。リスト内の要素の数が同じになることがわかっているので、このようなスワップを実行すると、リスト内の別の場所に要素を非常に効率的に移動することができます。

クリス・バックラーとミハルKreuzmanが指摘するように、1に次の3行のコードを削減するコレクションクラスでも、便利な方法があります:

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

これは素晴らしいです、collections.swapは完璧と思われます。 1つのわずかな問題は、リストの一番上にあるものを使用すると、範囲外の例外が発生するということです。境界線の例外をスローするのを止める方法はありますか? – user319940

+1

@ user319940こんにちはStriplingWarriorが最初のコードサンプルで示しました。インデックス私は0よりも大きくなければならない 'if(i> 0)' –

+0

heh、愚かな私、それの代わりにしようとしていた - 感謝、再び、みんな。うまくいけば、このポストは将来他の人にも役立つでしょう。 – user319940

23

あなたはこの単純なコード、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); 
+2

+1一般的なアプローチを使用しています。 – Sid

0

互いに対して移動要素ものです私のプロジェクトでは多くのことが必要でした。そこで、リスト内の要素を別の要素との相対位置に移動する小さなutilクラスを作成しました。 Collections.rotateは簡単な方法である前に、ミッケルが掲載され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); 
       } 
      } 
    } 
3

を、(とを改善)を使用して自由に感じます。私はリスト内でアイテムを上下に移動するためにこのメソッドを使用しています。

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); 
    } 
} 
2

内の項目を並べ替えるには再帰を適用)

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; 
     } 
    } 
1

リストでMove項目に簡単に追加:リストで

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

Swapするために、2つの項目は、単純に追加します。

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