2017-02-07 5 views
6

Я практикуюсь для примеров более свежего интервью для Java. Я пытаюсь написать программу для поиска повторяющихся чисел между 1 до N, где N задается пользователем вместе с самими числами. Вот код:OutOfMemoryError: Java куча пространства при попытке прочитать 5 ints в массив

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, Неон:

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, как читать данные пользователя? –

+0

Нет, сэр, я не пытаюсь скопировать чей-то код. У меня просто есть список программ для практики, где я пытаюсь создать код самостоятельно, и когда у меня заканчиваются логика и терпение, я прошу о помощи. –

ответ

20

DataInputStream предназначен для двоичных файлов, а не для текста. Когда вы вводите 4 байта, это превращается в 32-разрядное значение int, например. 5, \ n, \ n, \ n - около 900 миллионов, поэтому он жалуется на память при создании массива. Вы можете проверить это, выполнив код в своем отладчике.

Что вам нужно текст вход, попробуйте использовать

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. 
+0

быстрое и отличное замечание :) – davidxxx

5

Начиная здесь:

DataInputStream in=new DataInputStream(System.in); 

Вы не должны использовать DataInputStream ... и я вижу, что вы уже получили разъяснения о что.

Но помимо этого:

for(int e=0; e<a; e++) 

Вы сразу же запустить в NUM [D] и Num [е] равных условиях. Поскольку ваш второй цикл фактически сравнивает num [0] с num [0], например. Итак: второй цикл должен работать только по индексам после внешнего!

Помимо этого, также неясно, хотите ли вы в 50 раз «дублировать», если вы ввели 50-кратное число. Я предпочел бы пойти и напечатать номер номер дубликатов для номера.

Другими словами: после исправления проблемы с входным потоком ваш код по-прежнему не будет делать правильную вещь.

И помимо этого: использование односимвольных имен делает почти невозможным легко понять, что делает этот код.

+0

да я исправил сбой «флаг-первый-матч», выполнив if (f> 1) –

+0

Конечно, это работает; но это неправильный подход. Не исправляйте «сломанные данные», ожидая этого - предотвратите появление «сломанных данных» в первую очередь! – GhostCat

+0

означает код планирования до ввода? не могли бы вы рассказать, сэр? Профессиональные программисты делают «Грубую работу» перед кодированием? Как происходит развитие в реальной жизни? Пожалуйста, скажи мне, чтобы я мог улучшить. –

2

Попробуйте использовать вместо этого Scanner.

Вот простой пример:

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(); 
    }