What is the Simplest Way to Reverse an ArrayList?
反转此ArrayList的最简单方法是什么?
1 2 3 4 5 6 7 8 9 10 11 | ArrayList<Integer> aList = new ArrayList<>(); //Add elements to ArrayList object aList.add("1"); aList.add("2"); aList.add("3"); aList.add("4"); aList.add("5"); while (aList.listIterator().hasPrevious()) Log.d("reverse","" + aList.listIterator().previous()); |
1 |
示例(参考):
1 2 3 4 5 6 7 8 9 | ArrayList aList = new ArrayList(); //Add elements to ArrayList object aList.add("1"); aList.add("2"); aList.add("3"); aList.add("4"); aList.add("5"); Collections.reverse(aList); System.out.println("After Reverse Order, ArrayList Contains :" + aList); |
不是最简单的方法,但如果你是递归的粉丝,你可能会对以下方法感兴趣来反转ArrayList:
1 2 3 4 5 6 7 8 | public ArrayList<Object> reverse(ArrayList<Object> list) { if(list.size() > 1) { Object value = list.remove(0); reverse(list); list.add(value); } return list; } |
或非递归:
1 2 3 4 5 6 | public ArrayList<Object> reverse(ArrayList<Object> list) { for(int i = 0, j = list.size() - 1; i < j; i++) { list.add(i, list.remove(j)); } return list; } |
这里的诀窍是定义"反向"。可以在适当的位置修改列表,以相反的顺序创建副本,或者以相反的顺序创建视图。
直观地说,最简单的方法是
1 |
此方法可以修改列表。也就是说,
如果没有,可以按相反顺序创建副本:
1 2 3 4 5 | static < T > List< T > reverse(final List< T > list) { final List< T > result = new ArrayList<>(list); Collections.reverse(result); return result; } |
这种方法有效,但需要对列表进行两次迭代。复制构造函数(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | static < T > List< T > reverse(final List< T > list) { final int size = list.size(); final int last = size - 1; // create a new list, with exactly enough initial capacity to hold the (reversed) list final List< T > result = new ArrayList<>(size); // iterate through the list in reverse order and append to the result for (int i = last; i >= 0; --i) { final T element = list.get(i); result.add(element); } // result now holds a reversed copy of the original list return result; } |
这样更有效,但也更冗长。
或者,我们可以重写上面的内容以使用Java 8的
1 2 3 4 5 6 7 | static < T > List< T > reverse(final List< T > list) { final int last = list.size() - 1; return IntStream.rangeClosed(0, last) // a stream of all valid indexes into the list .map(i -> (last - i)) // reverse order .mapToObj(list::get) // map each index to a list element .collect(Collectors.toList()); // wrap them up in a list } |
NB。
第三种选择是以相反的顺序创建视图。这是一个更复杂的解决方案,值得进一步阅读/自己的问题。番石榴的名单#反向法是一个可行的起点。
选择"最简单"的实现仍然是读者的练习。
解决方案,无需使用额外的ArrayList或add()和remove()方法的组合。如果你必须撤销一个巨大的列表,两者都会产生负面影响。
1 2 3 4 5 6 7 8 9 10 | public ArrayList<Object> reverse(ArrayList<Object> list) { for (int i = 0; i < list.size() / 2; i++) { Object temp = list.get(i); list.set(i, list.get(list.size() - i - 1)); list.set(list.size() - i - 1, temp); } return list; } |
1 2 3 4 5 6 7 8 9 10 11 | ArrayList<Integer> myArray = new ArrayList<Integer>(); myArray.add(1); myArray.add(2); myArray.add(3); int reverseArrayCounter = myArray.size() - 1; for (int i = reverseArrayCounter; i >= 0; i--) { System.out.println(myArray.get(i)); } |
以递归方式反转ArrayList而不创建用于添加元素的新列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class ListUtil { public static void main(String[] args) { ArrayList<String> arrayList = new ArrayList<String>(); arrayList.add("1"); arrayList.add("2"); arrayList.add("3"); arrayList.add("4"); arrayList.add("5"); System.out.println("Reverse Order:" + reverse(arrayList)); } public static < T > List< T > reverse(List< T > arrayList) { return reverse(arrayList,0,arrayList.size()-1); } public static < T > List< T > reverse(List< T > arrayList,int startIndex,int lastIndex) { if(startIndex<lastIndex) { T t=arrayList.get(lastIndex); arrayList.set(lastIndex,arrayList.get(startIndex)); arrayList.set(startIndex,t); startIndex++; lastIndex--; reverse(arrayList,startIndex,lastIndex); } return arrayList; } } |
我们也可以使用java 8来做同样的事情。
1 2 3 4 5 6 7 8 9 10 | public static< T > List< T > reverseList(List< T > list) { List< T > reverse = new ArrayList<>(list.size()); list.stream() .collect(Collectors.toCollection(LinkedList::new)) .descendingIterator() .forEachRemaining(reverse::add); return reverse; } |
为了防止我们使用Java 8,我们可以使用Stream。 ArrayList是随机访问列表,我们可以按相反顺序获取元素流,然后将其收集到新的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public static void main(String[] args) { ArrayList<String> someDummyList = getDummyList(); System.out.println(someDummyList); int size = someDummyList.size() - 1; ArrayList<String> someDummyListRev = IntStream.rangeClosed(0,size).mapToObj(i->someDummyList.get(size-i)).collect(Collectors.toCollection(ArrayList::new)); System.out.println(someDummyListRev); } private static ArrayList<String> getDummyList() { ArrayList dummyList = new ArrayList(); //Add elements to ArrayList object dummyList.add("A"); dummyList.add("B"); dummyList.add("C"); dummyList.add("D"); return dummyList; } |
上述方法不适用于LinkedList,因为它不是随机访问。我们也可以使用
另一种递归解决方案
1 2 3 4 5 6 7 8 | public static String reverse(ArrayList<Float> list) { if (list.size() == 1) { return"" +list.get(0); } else { return""+ list.remove(list.size() - 1) + reverse(list); } } |
更可读:)
1 2 3 4 5 6 7 8 9 10 | public static < T > ArrayList< T > reverse(ArrayList< T > list) { int length = list.size(); ArrayList< T > result = new ArrayList< T >(length); for (int i = length - 1; i >= 0; i--) { result.add(list.get(i)); } return result; } |