首页 文章

反转ArrayList的最简单方法是什么?

提问于
浏览
289

反转此ArrayList的最简单方法是什么?

ArrayList 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());

10 回答

  • 0
    Collections.reverse(aList);
    

    示例(Reference):

    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);
    
  • 0

    不是最简单的方法,但如果你是递归的粉丝,你可能会对以下方法感兴趣来反转ArrayList:

    public ArrayList<Object> reverse(ArrayList<Object> list) {
        if(list.size() > 1) {                   
            Object value = list.remove(0);
            reverse(list);
            list.add(value);
        }
        return list;
    }
    

    或非递归:

    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;
    }
    
  • 18

    这里的诀窍是定义“反向” . 可以在适当的位置修改列表,以相反的顺序创建副本,或者以相反的顺序创建视图 .

    直观地说,最简单的方法是 Collections.reverse

    Collections.reverse(myList);
    

    此方法会修改列表 . 也就是说, Collections.reverse 获取列表并覆盖其元素,不留下任何未反转的副本 . 这适用于某些用例,但不适用于其他用例;此外,它假定列表是可修改的 . 如果这是可以接受的,我们很好 .


    如果没有,可以按相反顺序创建副本:

    static <T> List<T> reverse(final List<T> list) {
        final List<T> result = new ArrayList<>(list);
        Collections.reverse(result);
        return result;
    }
    

    这种方法有效,但需要在列表上迭代两次 . 复制构造函数( new ArrayList<>(list) )遍历列表, Collections.reverse 也是如此 . 如果我们如此倾向,我们可以重写此方法只迭代一次:

    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的 stream API,有些人发现它比上面更简洁明了:

    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 . Collectors.toList() 对结果列表提供的保证很少 . 如果要确保结果以ArrayList形式返回,请改用 Collectors.toCollection(ArrayList::new) .


    第三种选择是以相反的顺序创建视图 . 这是一个更复杂的解决方案,值得进一步阅读/自己的问题 . Guava 的Lists#reverse方法是一个可行的起点 .

    选择“最简单”的实现留给读者练习 .

  • 0

    解决方案,无需使用额外的ArrayList或add()和remove()方法的组合 . 如果你必须撤销一个巨大的列表,两者都会产生负面影响 .

    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
    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));
    }
    
  • 5

    以递归方式反转ArrayList而不创建用于添加元素的新列表:

    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;
        }
    
    }
    
  • 704

    更可读:)

    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;
    }
    
  • 3

    另一种递归解决方案

    public static String reverse(ArrayList<Float> list) {
       if (list.size() == 1) {
           return " " +list.get(0);
       }
       else {
           return " "+ list.remove(list.size() - 1) + reverse(list);
       } 
     }
    
  • 0

    为了防止我们使用 Java 8 ,我们可以使用Stream . ArrayList是随机访问列表,我们可以按相反顺序获取元素流,然后将其收集到新的 ArrayList 中 .

    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,因为它不是随机访问 . 我们也可以使用 instanceof 进行检查 .

  • 9

    我们也可以使用java 8来做同样的事情 .

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

相关问题