Java Collections.rotate 方法
上次修改时间:2025 年 4 月 20 日
Collections.rotate
方法是一个用于旋转 List 中元素的实用工具。旋转操作根据指定的距离将元素在列表中向前或向后移动。此操作对于循环移位和重新排列非常有用。
该方法是 Java 集合框架的一部分。它适用于任何 List 实现。旋转可以在原地执行,而无需创建新的列表。负距离向后旋转,而正距离向前旋转。
Collections.rotate 概述
rotate
方法接受一个 List 和一个距离参数。它通过将每个元素移动到位置 (index + distance) % list.size() 来旋转元素。此操作效率很高,通常在线性时间内运行。
关键特性包括支持向前和向后旋转。该方法修改原始列表,而不是返回一个新列表。它适用于任何 List 实现,包括 ArrayList 和 LinkedList。
基本向前旋转
此示例演示了列表的基本向前旋转。我们创建一个整数 ArrayList,并将其旋转 2 个位置。旋转将元素移动到更高的索引,并在需要时环绕到开头。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BasicForwardRotation { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); Collections.addAll(numbers, 1, 2, 3, 4, 5); System.out.println("Original list: " + numbers); // Rotate forward by 2 positions Collections.rotate(numbers, 2); System.out.println("After rotation: " + numbers); } }
此代码显示了简单的向前旋转。原始列表 [1, 2, 3, 4, 5] 在旋转后变为 [4, 5, 1, 2, 3]。当元素到达列表的末尾时,它们会环绕到开头。
旋转距离 (2) 决定了每个元素向前移动多少个位置。该操作在原地执行,修改原始列表。
基本向后旋转
此示例演示了使用负距离的向后旋转。我们将一个字符串列表向后旋转 1 个位置。负距离将元素移动到较低的索引。
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.List; public class BasicBackwardRotation { public static void main(String[] args) { List<String> colors = Arrays.asList("Red", "Green", "Blue", "Yellow"); System.out.println("Original list: " + colors); // Rotate backward by 1 position Collections.rotate(colors, -1); System.out.println("After rotation: " + colors); } }
此代码将列表向后旋转 1 个位置。原始列表 [Red, Green, Blue, Yellow] 变为 [Green, Blue, Yellow, Red]。第一个元素环绕到末尾。
负旋转距离与正旋转距离类似,但在相反的方向上。绝对值决定了要移动多少个位置。
旋转距离大于列表大小
当旋转距离超过列表大小时,它实际上会取模列表大小。此示例显示了按大于列表长度的距离旋转。结果等同于按余数旋转。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class LargeRotationDistance { public static void main(String[] args) { List<Character> letters = new ArrayList<>(); Collections.addAll(letters, 'A', 'B', 'C', 'D'); System.out.println("Original list: " + letters); // Rotate by distance larger than list size Collections.rotate(letters, 5); System.out.println("After rotation: " + letters); } }
此示例将一个 4 元素的列表旋转 5 个位置。由于 5 mod 4 等于 1,因此结果等同于旋转 1 个位置。列表 [A, B, C, D] 变为 [D, A, B, C]。
取模运算确保距离始终在范围内。这使得该方法可以安全地用于任何整数距离值。
旋转子列表
rotate
方法可与子列表视图一起使用,以仅旋转列表的一部分。此示例演示了在更大的列表中旋转一个 3 元素的片段。列表的其余部分保持不变。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class SublistRotation { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); Collections.addAll(numbers, 1, 2, 3, 4, 5, 6, 7); System.out.println("Original list: " + numbers); // Rotate elements 2-4 (inclusive) by 1 position Collections.rotate(numbers.subList(2, 5), 1); System.out.println("After sublist rotation: " + numbers); } }
此代码旋转索引 2-4 (3, 4, 5) 处的元素 1 个位置。原始列表 [1, 2, 3, 4, 5, 6, 7] 变为 [1, 2, 5, 3, 4, 6, 7]。仅影响指定的子列表。
子列表旋转对于操作较大列表的片段很有用。此操作保持子列表外部元素的相对顺序。
旋转 LinkedList
rotate
方法适用于不同的 List 实现。此示例演示了旋转 LinkedList。对于某些操作,LinkedLists 的旋转效率可能高于 ArrayLists。
package com.zetcode; import java.util.Collections; import java.util.LinkedList; import java.util.List; public class LinkedListRotation { public static void main(String[] args) { List<String> words = new LinkedList<>(); Collections.addAll(words, "apple", "banana", "cherry", "date"); System.out.println("Original list: " + words); // Rotate LinkedList by 3 positions Collections.rotate(words, 3); System.out.println("After rotation: " + words); } }
此示例将一个字符串 LinkedList 旋转 3 个位置。原始列表 [apple, banana, cherry, date] 变为 [banana, cherry, date, apple]。该操作的运行方式与 List 实现无关。
LinkedList 旋转可能具有与 ArrayList 旋转不同的性能特征。该方法会自动适应列表类型。
多次旋转
可以链接多次旋转以实现复杂的重新排列。此示例显示了顺序旋转如何影响列表。每次旋转都应用于列表的当前状态。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MultipleRotations { public static void main(String[] args) { List<Integer> nums = new ArrayList<>(); Collections.addAll(nums, 1, 2, 3, 4, 5, 6); System.out.println("Original list: " + nums); // First rotation Collections.rotate(nums, 2); System.out.println("After first rotation: " + nums); // Second rotation Collections.rotate(nums, -3); System.out.println("After second rotation: " + nums); // Third rotation Collections.rotate(nums, 4); System.out.println("After third rotation: " + nums); } }
此示例对一个整数列表执行三次旋转。第一次向前旋转 2 个位置,第二次向后旋转 3 个位置,第三次向前旋转 4 个位置。每次旋转都基于前一个结果。
输出显示了每次旋转后列表的状态。可以组合多次旋转以实现特定的元素排列。
实际用例:旋转一副牌
此示例演示了旋转的实际应用 - 模拟洗牌。我们旋转一副牌以将某些牌移到顶部。这模仿了真实世界的扑克牌处理技术。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CardDeckRotation { public static void main(String[] args) { List<String> deck = new ArrayList<>(); Collections.addAll(deck, "A♠", "K♠", "Q♠", "J♠", "10♠", "9♠", "A♥", "K♥", "Q♥", "J♥", "10♥", "9♥"); System.out.println("Original deck: " + deck); // Simulate cutting the deck at position 5 Collections.rotate(deck, -5); System.out.println("After cut: " + deck); // Bring the top card to the middle Collections.rotate(deck, deck.size()/2); System.out.println("After middle rotation: " + deck); } }
此示例使用旋转来模拟扑克牌操作。首先,我们通过向后旋转 5 个位置来“切”牌。然后,我们旋转牌堆的一半大小以将顶牌移到中间。
旋转是此类循环排列的理想选择。该示例展示了 Collections.rotate 如何模拟现实世界的旋转场景。
来源
在本文中,我们深入探讨了 Java Collections.rotate 方法。我们涵盖了基本旋转、子列表旋转和实际应用。了解旋转对于许多列表操作任务很有价值。
作者
列出所有Java教程。