ZetCode

Java Collections.reverse 方法

上次修改时间:2025 年 4 月 20 日

Collections.reverse 方法是 Java Collections 框架中的一个实用函数。它反转指定列表中元素的顺序。此操作是就地执行的,会修改原始列表。

该方法是 java.util.Collections 类的一部分。它适用于任何 List 实现。时间复杂度是线性的 (O(n)),其中 n 是列表的大小。这是一种无需手动循环即可反转元素顺序的便捷方法。

Collections.reverse 概述

reverse 方法接受一个参数——要反转的列表。因为它会就地修改列表,所以它不返回任何内容。如果列表不可修改,该方法会抛出 UnsupportedOperationException

该方法通过交换两端的元素并向中心移动来实现。它对于像 ArrayList 这样的随机访问列表是有效的。对于链表,由于其顺序访问的性质,效率较低。

基本列表反转

本示例演示了 Collections.reverse 的基本用法。我们创建一个字符串 ArrayList 并反转其顺序。示例显示了反转前后的列表。

BasicReverseExample.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BasicReverseExample {

    public static void main(String[] args) {
        
        List<String> colors = new ArrayList<>();
        colors.add("Red");
        colors.add("Green");
        colors.add("Blue");
        colors.add("Yellow");
        
        System.out.println("Original list: " + colors);
        
        Collections.reverse(colors);
        
        System.out.println("Reversed list: " + colors);
    }
}

此代码创建一个颜色列表并打印它。然后,它使用 Collections.reverse 反转该列表并再次打印。输出显示了反转前后的元素顺序。

该方法修改原始列表,而不是返回一个新的反转列表。在使用共享列表引用时,记住这一点很重要。

反转不同的列表类型

Collections.reverse 适用于任何 List 实现。此示例演示了如何反转 ArrayList 和 LinkedList。尽管内部实现不同,但两者都显示了相同的行为。

DifferentListTypes.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class DifferentListTypes {

    public static void main(String[] args) {
        
        // ArrayList example
        List<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        
        System.out.println("ArrayList before: " + arrayList);
        Collections.reverse(arrayList);
        System.out.println("ArrayList after: " + arrayList);
        
        // LinkedList example
        List<Integer> linkedList = new LinkedList<>();
        linkedList.add(10);
        linkedList.add(20);
        linkedList.add(30);
        
        System.out.println("\nLinkedList before: " + linkedList);
        Collections.reverse(linkedList);
        System.out.println("LinkedList after: " + linkedList);
    }
}

此示例显示 Collections.reverse 在不同的 List 实现中表现一致。ArrayList 和 LinkedList 都是以相同的方式反转的,尽管它们的内部结构不同。

输出表明该方法对于两种列表类型的行为完全相同。反转操作对列表的实现细节是透明的。

反转子列表

我们可以通过首先获取子列表视图来反转列表的一部分。此示例显示了如何仅反转列表的一部分。子列表由原始列表支持,因此更改会影响它。

ReverseSublistExample.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ReverseSublistExample {

    public static void main(String[] args) {
        
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Cherry");
        fruits.add("Date");
        fruits.add("Elderberry");
        
        System.out.println("Original list: " + fruits);
        
        // Reverse elements from index 1 to 3 (exclusive)
        List<String> sublist = fruits.subList(1, 4);
        Collections.reverse(sublist);
        
        System.out.println("After reversing sublist: " + fruits);
    }
}

此示例演示了如何反转列表的一部分。我们从索引 1 到 3(包含开始,不包含结束)创建一个子列表并反转它。原始列表反映了这些更改。

输出显示只有列表的指定部分被反转。当您只需要反转较大集合的一部分时,此技术很有用。

反转不可修改的列表

尝试反转不可修改的列表会抛出异常。本示例显示了尝试反转使用 Collections.unmodifiableList 创建的列表时会发生什么。

UnmodifiableListReverse.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class UnmodifiableListReverse {

    public static void main(String[] args) {
        
        List<String> original = new ArrayList<>();
        original.add("One");
        original.add("Two");
        original.add("Three");
        
        List<String> unmodifiable = 
            Collections.unmodifiableList(original);
        
        System.out.println("Original: " + original);
        System.out.println("Unmodifiable: " + unmodifiable);
        
        try {
            Collections.reverse(unmodifiable);
        } catch (UnsupportedOperationException e) {
            System.out.println("\nException caught: " + e.getMessage());
        }
    }
}

此示例演示了不可修改的列表无法反转。我们创建了列表的不可修改视图并尝试反转它。这将抛出 UnsupportedOperationException

输出显示了异常消息。要反转此类列表,您需要首先创建一个新的可修改副本。这是不可修改集合的一个安全特性。

性能注意事项

本示例比较了反转不同列表类型的性能。由于随机访问,ArrayList 的反转性能通常优于 LinkedList。

ReversePerformance.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class ReversePerformance {

    public static void main(String[] args) {
        
        final int SIZE = 100000;
        
        // ArrayList test
        List<Integer> arrayList = new ArrayList<>(SIZE);
        for (int i = 0; i < SIZE; i++) {
            arrayList.add(i);
        }
        
        long start = System.currentTimeMillis();
        Collections.reverse(arrayList);
        long duration = System.currentTimeMillis() - start;
        System.out.println("ArrayList reverse time: " + duration + "ms");
        
        // LinkedList test
        List<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i < SIZE; i++) {
            linkedList.add(i);
        }
        
        start = System.currentTimeMillis();
        Collections.reverse(linkedList);
        duration = System.currentTimeMillis() - start;
        System.out.println("LinkedList reverse time: " + duration + "ms");
    }
}

此示例测量了反转大型 ArrayListLinkedList 实例所花费的时间。ArrayList 通常表现更好,因为它具有随机访问能力。

输出显示了反转两种列表类型之间的时间差。对于大多数应用程序,差异可以忽略不计,但了解性能特征是好的。

反转自定义对象的列表

Collections.reverse 适用于包含任何对象类型的列表。此示例演示了如何反转自定义 Person 对象的列表。

CustomObjectReverse.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

record Person(String name, int age) {}

public class CustomObjectReverse {

    public static void main(String[] args) {

        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 25));
        people.add(new Person("Bob", 30));
        people.add(new Person("Charlie", 35));

        System.out.println("Original order:");
        people.forEach(System.out::println);

        Collections.reverse(people);

        System.out.println("\nReversed order:");
        people.forEach(System.out::println);
    }
}

此示例显示 Collections.reverse 对自定义对象的处理方式与对基本类型包装器或字符串的处理方式相同。我们创建了一个 Person 对象列表并对其进行反转。

输出表明列表中 Person 对象的顺序被反转。该方法不关心对象的内容,只关心它们的位置。

将 reverse 与其他操作结合使用

此示例显示了如何将 Collections.reverse 与其他列表操作结合使用。我们对列表进行排序,然后对其进行反转以获得降序排列。

ReverseWithSort.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ReverseWithSort {

    public static void main(String[] args) {
        
        List<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(2);
        numbers.add(8);
        numbers.add(1);
        numbers.add(9);
        
        System.out.println("Original: " + numbers);
        
        Collections.sort(numbers);
        System.out.println("Sorted: " + numbers);
        
        Collections.reverse(numbers);
        System.out.println("Reversed: " + numbers);
    }
}

此示例演示了一种常见模式:排序后反转以获得降序排列。首先,我们按自然顺序对列表进行排序,然后对其进行反转。

输出显示了从原始到排序再到反转顺序的转换。这种技术通常比使用自定义比较器进行降序排序更有效。

来源

Java Collections.reverse 文档

在本文中,我们深入探讨了 Java Collections.reverse 方法。我们涵盖了基本用法、不同的列表类型、性能以及与其他操作的结合。此方法是列表操作的强大工具。

作者

我的名字是 Jan Bodnar,我是一位经验丰富的程序员,在这一领域拥有多年经验。我从 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和八本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程