【问题标题】:Strange output than my expected output using LinkedList奇怪的输出比我使用 LinkedList 的预期输出
【发布时间】:2013-10-31 07:49:25
【问题描述】:

当程序运行时,它输出 10 个随机数,每个数字存储到 LinkedList 列表中,然后显示此列表,仅显示 4-5 个数字,而不是原始数组中的 10 个。这是简单的代码:

import java.util.LinkedList;
import java.util.Random;

public class randomSum {
    private static Random rand = new Random();
    private static LinkedList<Integer> arr = new LinkedList<Integer>();

    public static void main(String[] args) {
        int num = 0;

        System.out.println("Original List");
        for(int i=0; i < 10; i++) {
            num = rand.nextInt(1000);
            arr.add(num);
            System.out.println(num);
        }

        System.out.println("\nLinkedList List");
        for(int j=0; j < arr.size(); j++)
            System.out.println(arr.remove(j));
    }
}

输出是这样的,这与我的预期不完全一样。他们都应该是一样的。为什么会这样?

Original List
693
239
33
999
862
965
994
884
127
977

LinkedList List
693
33
862
994
127

【问题讨论】:

  • System.out.println(arr.remove(j)); 你确定这是你想要的吗?
  • 在循环中更改列表会产生奇怪的结果。循环遍历列表时,您希望列表中的数据保持不变。至少在我能想到的每一种情况下......
  • 好吧,我原本以为它会在删除每个元素之前打印每个元素。

标签: java arrays loops linked-list


【解决方案1】:

因为在每次迭代中,您都会删除正在打印的元素。这将打破指数。例如,当您删除 index 0 处的元素时,index 1 处的元素现在移动到 index 0,但循环索引现在移动到 index 1。因此,刚刚转移到index 0 的元素从未被处理过。这将发生在每个备用元素上,因此您会得到该输出。

您需要使用get(j) 而不是remove(j)

for(int j=0; j < arr.size(); j++)
    System.out.println(arr.get(j));

或使用enhanced for loop:

for (int val: arr) {
    System.out.println(val);
}

【讨论】:

  • @Minhaj 自动拆箱。
  • @Minhaj 搜索增强的 for 循环。
【解决方案2】:

如果您真的想在打印LinkedList 时删除项目,您应该使用Iterator。像您一样删除元素会导致未定义的行为。做这样的事情:

Iterator<Integer> it = arr.iterator();
while(it.hasNext()) {
    int element = it.next();
    System.out.println(element);
    it.remove();
}

【讨论】:

    【解决方案3】:

    在这个答案中,我想说明实际发生的情况,以便您了解为什么 remove(j) 可能不是您想要的,就像 Rohit Jain 所说的那样。

    在开始时,您的列表如下所示:

    693 239 33 999 862 965 994 884 127 977
    

    在第一次迭代之后,您调用remove(0),它将看起来像这样

    239 33 999 862 965 994 884 127 977
    

    因此,当您在下一次迭代中调用 remove(1) 时,您将删除元素 33,它最初是第三个元素。因此,相对于原始列表,每次迭代实际上都向前推进了两个元素。

    【讨论】:

      【解决方案4】:

      你看到输出的规则了吗?它是原始列表中的所有其他数字。 每次使用 arr.remove(j) 时,列表 arr 都会缩小 1。因此循环在 j==5 时结束,同时 arr.size()=5。此外,您使用 arr.remove(j),然后删除第 j 个项目,在 j++ 之后,您跳过原始的第 (j+1) 个当前第 j 个项目。因此,规定每隔一个数字都来自原始列表。

      如果您替换 remove 来获得它,它将按您的预期工作。 并且,您可以将 remove(j) 替换为 remove(0) 并将循环结束条件更改为 j

      【讨论】:

        猜你喜欢
        • 2017-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-05
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 2015-02-18
        相关资源
        最近更新 更多