【问题标题】:What is the Simplest Way to Reverse an ArrayList?反转 ArrayList 的最简单方法是什么?
【发布时间】:2012-06-01 17:58:37
【问题描述】:

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

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

【问题讨论】:

    标签: java android arraylist collections


    【解决方案1】:
    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);
    

    【讨论】:

    • @AgarwalShankar 我收到一个错误,需要 ArrayList 发现无效。我错过了什么吗?
    • @SagarDevanga 列表原地反转,没有返回。
    • Collections.reverse(List);我在一个Android项目中使用它,效果很好。
    【解决方案2】:

    这不是最简单的方法,但如果您是递归爱好者,您可能会对以下反转 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;
    }
    

    【讨论】:

    • 我可能错了,但在您的非递归示例中,int j 不是每次迭代都不会更新吗?您将其初始化为j = list.size() - 1,但我认为for loop 的initialization 部分不会随着每次迭代而更新吗?
    • @Turbo j 不需要在每次迭代中更新。它被初始化为 ArrayList 的最后一个索引,用于访问最后一个元素。在 for 循环中,最后一个元素被移除并插入到索引 i 中; i 递增,直到它到达 ArrayList 中的倒数第二个位置。
    • 是的,但是在第二次迭代中,您不会得到IndexOutOfBoundsException,因为您正在尝试访问j(原始ArrayList 的最后一个索引)但您已经删除了该对象在那个索引处?
    • 抱歉,刚刚运行了代码,绝对可以。我忘记了add() 将其他元素向下推到数组中,因此数组基本上保持恒定大小。有趣的解决方案,谢谢!
    • @LukeUsherwood 我同意它效率不高,但这不是问题所在。问题是最简单的方法,递归方法与自己实现一样简单。
    【解决方案3】:

    更具可读性:)

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

    【讨论】:

      【解决方案4】:

      解决方案不使用额外的 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;
       }
      

      【讨论】:

        【解决方案5】:

        另一种递归解决方案

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

        【讨论】:

          【解决方案6】:

          如果我们使用 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 进行检查。

          【讨论】:

            【解决方案7】:

            这里的技巧是定义“反向”。可以就地修改列表,以相反的顺序创建副本,或以相反的顺序创建视图。

            最简单的方法,直观地说,是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&lt;&gt;(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
            }
            

            注意。 Collectors.toList() 对结果列表的保证很少。如果要确保结果以 ArrayList 的形式返回,请改用 Collectors.toCollection(ArrayList::new)。


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

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

            【讨论】:

              【解决方案8】:
              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));
              }
              

              【讨论】:

                【解决方案9】:

                以递归方式反转 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;
                    }
                
                }
                

                【讨论】:

                  【解决方案10】:

                  我们也可以使用 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;
                      }
                  

                  【讨论】:

                    【解决方案11】:

                    简单的方法是你在 Java 中有“Collections”。你只需要调用它并使用它的“reverse()”方法。

                    使用示例:

                    ArrayList<Integer> yourArrayList = new ArrayList<>();
                        yourArrayList.add(1);
                        yourArrayList.add(2);
                        yourArrayList.add(3);
                        //yourArrayList is: 1,2,3
                    
                    Collections.reverse(yourArrayList); 
                        // Now, yourArrayList is: 3,2,1
                    

                    【讨论】:

                      【解决方案12】:

                      Kotlin 用户

                      val reverse: List<Int> = list.reversed();
                      

                      编码愉快!

                      Reference

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2011-04-10
                        • 2022-01-24
                        • 2020-05-22
                        • 2021-03-16
                        • 1970-01-01
                        • 2010-11-06
                        • 2014-01-03
                        • 1970-01-01
                        相关资源
                        最近更新 更多