尝试将5个整数读入数组时,出现了“OutOfMemoryError:Java堆空间”错误。

6

我正在练习Java新手面试编程例题。 我正在尝试编写一个程序来查找在1N之间的重复数字,其中N由用户提供,同时还有这些数字本身。 以下是代码:

import java.io.DataInputStream;
import java.io.IOException;

public class DuplicateNumbers {

    public static void main(String[] args) throws IOException {
        DataInputStream in = new DataInputStream(System.in);

        System.out.println(" Enter the number of numbers ");

        int a = in.readInt();
        int[] num = new int[a];
        System.out.println(" Enter the ints one by one ");
        for (int b = 0; b < a; b++) {
            System.out.println(" Enter no "+(b+1));
            num[b]=in.readInt();
        }
        int c = 0;
        for (int d = 0; d < a; d++) {
            int f = 0;
            c = num[d];
            for (int e=0; e<a; e++) {
                if (c==num[e]) {
                    f++;
                }
            }

            if(f > 1)
                System.out.println(" Duplicate number "+c);
        }
    }

}

但是我在Eclipse Neon中遇到了以下错误:
Enter the number of numbers 
5

Exception in thread "main" java.lang.OutOfMemoryError: 
Java heap space at DuplicateNumbers.main(DuplicateNumbers.java:14)

什么出了问题?为什么会出现JVM堆空间错误?代码编译和运行都没有问题。

3
好的,它并不“运行良好”,这就是你在这里询问异常的原因... 它是否在int[] num=new int[a];这一行崩溃了?你尝试过添加断点并调试代码吗? - luk2302
4
你从哪里学会了使用DataInputStream来读取用户输入? - OneCricketeer
不,我并不想抄袭任何人的代码。我只是有一个编程练习列表,在上面努力自己编写代码,但当我遇到逻辑和耐心的瓶颈时,就会寻求帮助。 - user6708255
只是为了记录:您仍然可以接受其中一个答案;如果您认为它们足够有帮助的话;-) - GhostCat
3个回答

19

DataInputStream适用于二进制而不是文本。当您键入4个字节时,这会转换为32位int值,例如5、\n、\n、\n约为9亿,这就是为什么在创建数组时它抱怨内存问题。您可以通过在调试器中单步执行代码来检查此内容。

您需要的是文本输入,请尝试使用

Scanner in = new Scanner(System.in);
System.out.println("Enter the number of numbers");
int a = in.nextInt();
in.nextLine(); // discard the rest of the line.

快速而优秀的备注 :) - davidxxx

4

Starting here:

DataInputStream in=new DataInputStream(System.in);

你不应该使用 DataInputStream...我看到你已经得到了有关此事的解释。
但除此之外:
for(int e=0; e<a; e++)

你将立即遇到num[d]和num[e]相等的情况。因为你的第二个循环实际上是比较例如num[0]和num[0]。所以:第二个循环需要仅在外部循环后运行索引!
除此之外,如果您输入了50次相同的数字,您是否真的想要50次“复制”?我更愿意去打印一个数字的重复次数。
换句话说:在解决输入流问题之后,您的代码仍然无法完成正确的事情。
此外,您对单字符名称的使用使人几乎不可能轻松理解该代码正在执行什么操作。

是的,我通过添加 if(f>1) 语句来纠正“第一次匹配后标志”的故障。 - user6708255
当然,那样做可行;但是那是错误的方法。不要期望通过修复“损坏的数据”来解决问题 - 首先要防止“损坏的数据”产生! - GhostCat
计划编码前的含义是什么?您能详细说明一下吗,先生?专业程序员在编码之前会进行“草稿工作”吗?现实生活中的开发是如何进行的?请告诉我,以便我可以改进。 - user6708255
我的意思是,你将 if() 语句中的条件改为了检查是否大于1。这是“修复错误结果”。我的解决方案是防止 num[0] 与其自身进行比较。换句话说:不要检查 f > 1;而是确保只有在数组的不同位置找到重复数字时才增加 f 的值。 - GhostCat
好的,我应该使用更好的标记技术。 - user6708255

1

建议您使用扫描仪来代替您的类。

以下是一个基本示例:

public static void main(String[] args) throws IOException 
    {
        System.out.println("Enter a number: ");
        Scanner sc = new Scanner(System.in);
        String item = sc.next();
        System.out.println("Your item is: " + item);
        sc.close();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接