2014-12-05 59 views
1

我在ArrayList中有以下数据。为了方便起见,我们假设它是一个String ArrayList。移动ArrayList中的几个项目

Mokey 
MokeyBaby1 
MokeyBaby2 
MokeyBaby3 
Dog 
DogBaby1 
DogBaby2 
Cat 
CatBaby1 

我需要将相关的项目一起移动。

例如:Moving Monkey down。新的ArrayList看起来像这样。

Dog 
DogBaby1 
DogBaby2 
Mokey 
MokeyBaby1 
MokeyBaby2 
MokeyBaby3 
Cat 
CatBaby1 

我已经有一个方法告诉我哪个ArrayList索引是相关的。

例如:getRelatedIndexes("Monkey")将返回0,1,2,3作为原始列表。

我只需要知道是否有一种简单的方法将所有项目向上或向下移动ArrayList在一起。

谢谢。

+0

如果我很了解你,你希望为每种类型的动物获取一个'ArrayList'?像'monkeyList = animalsList.magicMethod(getRelatedIndexes(“Monkey”))''? – fxm 2014-12-05 13:57:56

+0

为什么不列出清单? – mkrakhin 2014-12-05 13:58:31

+1

嘿大家,只是要清楚,这不是一个字符串ArrayList,所以我无法排序它。 @fxm – john 2014-12-05 14:00:44

回答

1

你可以将你的列表包装在可重新订购的列表中,并通过它来实现你的重新排序 - 至少你不需要破解主列表。它会维护一系列整数的顺序,然后您可以随意移动。如果你愿意,你甚至可以用几种不同的顺序维护相同的数据。

public static class OrderedList<T> extends AbstractList<T> { 

    // The list I proxy. 
    private final List<T> it; 
    // The order. 
    private final int[] order; 

    public OrderedList(List<T> wrap) { 
     it = wrap; 
     order = new int[it.size()]; 
     // Initially the same order. 
     for (int i = 0; i < order.length; i++) { 
      order[i] = i; 
     } 
    } 

    @Override 
    public T get(int index) { 
     return it.get(order[index]); 
    } 

    @Override 
    public int size() { 
     return it.size(); 
    } 

    // TODO - Only moves up! Breaks on a down move. 
    public void move(int start, int length, int to) { 
     int[] move = new int[length]; 
     // Copy it out. 
     System.arraycopy(order, start, move, 0, length); 
     // Shift it down. 
     System.arraycopy(order, start + length, order, start, to - start); 
     // Pull it back in. 
     System.arraycopy(move, 0, order, to, length); 

    } 
} 

public void test() { 
    List<String> t = Arrays.asList("Zero", "One", "Two", "Three", "Four", "Five"); 
    OrderedList<String> ordered = new OrderedList(t); 
    System.out.println(ordered); 
    ordered.move(1, 2, 3); 
    System.out.println(ordered); 
} 

打印

[Zero, One, Two, Three, Four, Five] 
[Zero, Three, Four, One, Two, Five] 

或者 - 使用Collections.rotate,并制定出什么子列表应该旋转它的方式来实现你的举动。

0

或许这包含了你需要(swap和/或旋转/子表)的解决方案 - Moving items around in an ArrayList

+0

不是。这个问题是关于只上下移动1个项目。我想移动几个。 – john 2014-12-05 14:05:55

+0

更新:我正在研究旋转。我会尝试一下并更新这个问题。 – john 2014-12-05 14:06:45

0

块换挡策略可以通过

  • 服用这些元件,使用列表中的原始列表来实现.remove(index)并添加到一个新的临时数组中。请注意,这必须以相反的顺序完成,否则索引将随着项目被删除而改变。
  • 添加新的临时数组所需位置使用List.addAll(索引,集合)的情况下,克隆的索引
  • 列表它被在别处使用

public static void main(String[] args) { 
    List<Animal> animals = new ArrayList<Animal>(Arrays.asList(new Animal(
      "Mokey"), new Animal("MokeyBaby1"), new Animal("MokeyBaby2"), 
      new Animal("MokeyBaby3"), new Animal("Dog"), new Animal(
        "DogBaby1"), new Animal("DogBaby2"), new Animal("Cat"), 
      new Animal("CatBaby1"))); 

    int[] relatedIndexes= { 0, 1, 2, 3 }; 
    shift(animals, relatedIndexes, 3); 

    System.out.println(animals); 
} 

private static void shift(List<Animal> original, int[] indexes, int newIndex) { 
    int[] sorted = indexes.clone(); 
    Arrays.sort(sorted); 
    List<Animal> block = new ArrayList<Animal>(); 
    for (int i = sorted.length - 1; i >= 0; i--) { 
     block.add(original.get(sorted[i])); 
     original.remove(i); 
    } 
    original.addAll(newIndex, block); 
} 

输出

[Dog, DogBaby1, DogBaby2, Mokey, MokeyBaby1, MokeyBaby2, MokeyBaby3, Cat, CatBaby1] 
+0

感谢您抽出时间为此。我的意思是,在例子中我比较了字符串并按字母顺序排序。这不是实际情况。实际上,我想对不同的条件进行排序,这不是按字母顺序排列的(或者与字符串有关),(这部分由'getRelatedIndexes'方法处理)。我希望我已经说清楚了。 – john 2014-12-05 14:24:20

+0

@john更新了我的答案 – Adam 2014-12-05 14:25:59

+0

编辑 - 现在查看您的更新。 – john 2014-12-05 14:26:17

0

您可以搜索您的清单中的项目,满足您的标准ia并将其安全保存到另一个临时列表中。然后使用addAll(int index, Collection<? extends E> c)方法将这些元素再次添加到列表中。那么你不必为每个Element自己使用add(int index, E element)