反转这个数组列表最简单的方法是什么?

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

当前回答

这里的诀窍在于如何定义“反向”。可以就地修改列表,以相反的顺序创建副本,或以相反的顺序创建视图。

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

Collections.reverse(myList);

此方法将就地修改列表。那就是集合。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的流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。collections . tolist()对结果列表的保证很少。如果你想确保返回的结果是一个数组列表,请使用collections . tocollection (ArrayList::new)。


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

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

其他回答

如果我们使用的是Java 8,那么我们可以使用Stream。数组列表是一个随机访问列表,我们可以得到一个倒序的元素流,然后把它收集到一个新的数组列表中。

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进行检查。

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

芬兰湾的科特林用户

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

编码快乐!

参考

可读性更强一点:)

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

这里的诀窍在于如何定义“反向”。可以就地修改列表,以相反的顺序创建副本,或以相反的顺序创建视图。

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

Collections.reverse(myList);

此方法将就地修改列表。那就是集合。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的流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。collections . tolist()对结果列表的保证很少。如果你想确保返回的结果是一个数组列表,请使用collections . tocollection (ArrayList::new)。


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

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