【问题标题】:Move element backward in a List using Collections.rotate() in Java在 Java 中使用 Collections.rotate() 在列表中向后移动元素
【发布时间】:2015-01-07 06:26:43
【问题描述】:

我有一个如下所述的 ArrayList(我的代码片段)。

我的列表元素最初按此顺序排列 - ("Periodic", "Multiple", "Single", "Subsequent", "Consecutive")。

在我的 List 元素上应用 Collections.rotate() 后,修改后的 List 应该看起来像 -

(“周期性”、“后续”、“多个”、“单个”、“连续”)

元素“Subsequent”需要向后移动到List中的第一个索引元素,即“Multiple”,这样第一个索引的元素在旋转后会被下推到第二个索引。

当我尝试使用 Collections.rotate() 时,它会引发异常。

IllegalArgumentException “fromIndex > toIndex”

我研究并理解了错误,toIndex应该总是大于或等于fromIndex,但我不知道如何修改我的代码sn-p为了实现我所需要的。

任何建议将不胜感激。

难道不能使用 rotate() 方法在 List 中向后移动元素吗?

List<String> list = new ArrayList<String>(Arrays.asList("Periodic", "Multiple", "Single", "Subsequent", "Consecutive"));
       for (int i = 0; i < list.size(); i++) {
            int indexOfSubName = 0;
            int indexOfMultipleName = 0;

            String name = list.get(i);

            if (name.equalsIgnoreCase("Subsequent")) {
                indexOfSubName = list.indexOf(name);

            }

            if (name.equalsIgnoreCase("Multiple")) {
                int indexOfMultipleName = list.indexOf(name);
            }
           Collections.rotate(list.subList(indexOfSubName , indexOfMultipleName ), 1);
        }

【问题讨论】:

  • 你的意思是用第一个元素交换 n-1 吗?
  • 很抱歉我已经编辑了我的问题。我不是说将 n-1 与第一个元素交换,我的意思是将 n-1 元素移动到第一个索引位置,以便在旋转后将第一个索引处的元素下推到第二个索引。

标签: java arraylist collections


【解决方案1】:

两个问题:

  • 您正在尝试将子列表从 3 变为 1,反之亦然。所以你可以检查最小值和最大值,然后尝试获取子列表。
  • 您的 sublist 调用将为您带来从索引 1 到 n-1 的元素,即如果您传递 3,您将只获得两个元素,即索引 1 和 2,而不是第三个。有关详细信息,请参阅此javadoc。你可以这样做:

    List<String> list = new ArrayList<String>(Arrays.asList("Periodic", "Multiple", "Single", "Subsequent", "Consecutive"));
    int indexOfSubName = 0;
    int indexOfMultipleName = 0;
    for (int i = 0; i < list.size(); i++) {
        String name = list.get(i);
        if (name.equalsIgnoreCase("Subsequent")) {
            indexOfSubName = list.indexOf(name);
        }
        if (name.equalsIgnoreCase("Multiple")) {
            indexOfMultipleName = list.indexOf(name);
        }
    }
    int min = Math.min(indexOfMultipleName, indexOfSubName);
    int max = Math.max(indexOfMultipleName, indexOfSubName);
    Collections.rotate(list.subList(min, max+1), 1);
    System.out.println(list);
    

如果你运行它,你会得到你需要的输出:

[Periodic, Subsequent, Multiple, Single, Consecutive]

【讨论】:

  • 完美!非常感谢您提供的有见地的信息。现在按预期工作。
  • 澄清一下,如果距离为正 (1),那么 max+1 处的元素将移动到 min 对吗?如果距离为负(-1),那么 min 处的元素将移动到 max+1 对吗?我不太了解 rotate() 方法,如果您能对此有所了解,将会有很大帮助。
  • 所以如果你的元素是 a,b,c 并且你的距离是 1,那么输出将是 c,a,b (右移),而如果是负数,那么它将是左移b,c,a。
【解决方案2】:

Almas 是正确的,但代码可以更简洁一些:

    List<String> list = new ArrayList<String>(Arrays.asList("Periodic", "Multiple", "Single", "Subsequent", "Consecutive"));
    System.out.format("Before: %s%n", list);
    int indexOfSubName = list.indexOf("Subsequent");
    int indexOfMultipleName = list.indexOf("Multiple");
    int min = Math.min(indexOfMultipleName, indexOfSubName);
    int max = Math.max(indexOfMultipleName, indexOfSubName);
    int distance = 1; // Can be 1 or -2
    Collections.rotate(list.subList(min, max + 1), distance);
    System.out.format("After: %s%n", list);

您可以将子列表向前旋转 1 距离或向后旋转 -2 距离以获得相同的效果。

【讨论】:

  • 对我来说它的距离是 1 向前和 -1 向后
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多