Reputation: 1747
I have the following data in an ArrayList. Let's say it's a String ArrayList for convenience sake.
Mokey
MokeyBaby1
MokeyBaby2
MokeyBaby3
Dog
DogBaby1
DogBaby2
Cat
CatBaby1
I need to move the items that are related, together.
For example: Moving Monkey down
. The new ArrayList would look like this.
Dog
DogBaby1
DogBaby2
Mokey
MokeyBaby1
MokeyBaby2
MokeyBaby3
Cat
CatBaby1
I already have a method that tells me which ArrayList indexes are related.
For example: getRelatedIndexes("Monkey")
would return 0,1,2,3
for the original list.
I just need to know if there is an easy way to move all the items up or down an ArrayList together.
Thanks.
Upvotes: 1
Views: 533
Reputation: 65811
You could wrap your list in a reorderable list and implement your reordering through that - at least you wouldn't need to hack the main list. It would maintain the order in an array of ints which you can then move around at will. You could even maintain the same data in several different orders if you like.
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);
}
prints
[Zero, One, Two, Three, Four, Five]
[Zero, Three, Four, One, Two, Five]
Alternatively - use Collections.rotate and work out what sub-list should be rotated which way to achieve your move.
Upvotes: 1
Reputation: 36703
The block shifting strategy can be achieved by
Example
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);
}
Output
[Dog, DogBaby1, DogBaby2, Mokey, MokeyBaby1, MokeyBaby2, MokeyBaby3, Cat, CatBaby1]
Upvotes: 0
Reputation: 1
You could search for items in your list, which fullfill your criteria and safe them into another temporary list. Then you use the addAll(int index, Collection<? extends E> c)
method to add these elements again to the list. Then you do not have to use add(int index, E element)
for every Element itsself.
Upvotes: 0
Reputation: 8628
Perhaps this contains the solution you need (swap and/or rotate/sublist) - Moving items around in an ArrayList
Upvotes: 0