2015-03-07 4 views
-1

Здравствуйте моя программа не работает с ArrayIndexOutofBoundsExeption. Я получаю эту ошибку, когда я запускаю его:Моя программа не работает с ошибкой ArrayIndexOutofBoundsExeption

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -35 
at RoulleteChecker.main(RoulleteChecker.java:134) 

Вот мой код:

import javax.swing.JOptionPane; 
import javax.swing.JTextArea; 

public class RoulleteChecker { 

     public static void main(String args[]) 
     { 

      int a[] = new int[37]; 

      for (long roll = 1; roll <=99999999; roll++) {  
      a[0] = 1 + (int) (Math.random() * 34); 

      switch (a[0]) { 

       case 0: 
        ++a[1]; 
        break; 

       case 1: 
        ++a[2]; 
        break; 

       case 2: 
        ++a[3]; 
        break; 

       case 3: 
        ++a[4]; 
        break; 

       case 4: 
        ++a[5]; 
        break; 

       case 5: 
        ++a[6]; 
        break; 
       case 6: 
        ++a[7]; 
        break; 
       case 7: 
        ++a[8]; 
        break; 
       case 8: 
        ++a[9]; 
        break; 
       case 9: 
        ++a[10]; 
        break; 
       case 10: 
        ++a[11]; 
        break; 
       case 11: 
        ++a[12]; 
        break; 
       case 12: 
        ++a[13]; 
        break; 
       case 13: 
        ++a[14]; 
        break; 
       case 14: 
        ++a[15]; 
        break; 
       case 15: 
        ++a[16]; 
        break; 
       case 16: 
        ++a[17]; 
        break; 
       case 17: 
        ++a[18]; 
        break; 
       case 18: 
        ++a[19]; 
        break; 
       case 19: 
        ++a[20]; 
        break; 
       case 20: 
        ++a[21]; 
        break; 
       case 21: 
        ++a[22]; 
        break; 
       case 22: 
        ++a[23]; 
        break; 
       case 23: 
        ++a[24]; 
        break; 
       case 24: 
        ++a[25]; 
        break; 
       case 25: 
        ++a[26]; 
        break; 
       case 26: 
        ++a[27]; 
        break; 
       case 27: 
        ++a[28]; 
        break; 
       case 28: 
        ++a[29]; 
        break; 
       case 29: 
        ++a[30]; 
        break; 
       case 30: 
        ++a[31]; 
        break; 
       case 31: 
        ++a[32]; 
        break; 
       case 32: 
        ++a[33]; 
        break; 
       case 33: 
        ++a[34]; 
        break; 
       case 34: 
        ++a[35]; 
        break; 
      } 

     } 

     JTextArea outputArea = new JTextArea(); 

     outputArea.setText("Lets see: " + a[0-35]); 

     JOptionPane.showMessageDialog(null, outputArea, 
      "Searching for the frequency: 99999999 times", JOptionPane.INFORMATION_MESSAGE); 
     System.exit(1); 

    } 
} 

Пожалуйста, моя голова взорвется с этим. Я думаю, что моя ошибка находится на переменной a.

+7

Как вы думаете, это 'a [0-35]' делает? –

+3

Огромный блок переключателей можно изменить на 1-3 строки кода. –

+2

Распечатайте содержимое массива, итерации по нему. Удалите это 'a [0-35]'. –

ответ

1

Во-первых, все, что гигантский выключатель может быть заменен следующим образом:

++a[a[0] + 1]; 

Затем, как уже отмечали другие люди, a[0 - 35] не означает, что вы хотите, он не будет магически захватывать позиции от 0 до 35 от массива. Это всего лишь математический результат 0, вычитаемый до 35, который равен -35. В массиве нет позиции -35.

Для представления массива в виде строки, мы можем использовать Java 8 потоков:

IntStream.of(a).limit(36).boxed().collect(Collectors.toList()).toString().replace(", ", "\n") 

Что это делает:

  1. Это будет конвертировать int[] в IntStreamIntStream.of(a) части).
  2. Позволяет ограничить доступ только к первым 36 элементам (поскольку вам нужны элементы от 0 до 35). Это то, что делает .limit(36).
  3. Затем IntStream будет преобразован в Stream<Integer> (.boxed()).
  4. Затем он будет преобразован в часть List<Integer> (.collect(Collectors.toList())).
  5. Затем он будет преобразован в String (часть .toString()).
  6. С тех пор String будет слишком длинным, чтобы быть представленным на одной строке, это хорошая идея, чтобы добавить некоторые разрывы строк, это то, что делает .replace(", ", "\n").

И, наконец, вам не нужен System.exit(1);, здесь здесь нет никакой цели.

При том, что это ваш результирующий код:

import java.util.stream.Collectors; 
import java.util.stream.IntStream; 
import javax.swing.JOptionPane; 
import javax.swing.JTextArea; 

public class RoulleteChecker { 

    public static void main(String args[]) { 

     int a[] = new int[37]; 

     for (long roll = 1; roll <= 99999999; roll++) { 
      a[0] = 1 + (int) (Math.random() * 34); 
      ++a[a[0] + 1]; 
     } 

     JTextArea outputArea = new JTextArea(); 

     outputArea.setText("Lets see: " + IntStream.of(a).limit(36).boxed().collect(Collectors.toList()).toString().replace(", ", "\n")); 

     JOptionPane.showMessageDialog(null, outputArea, 
       "Searching for the frequency: 99999999 times", JOptionPane.INFORMATION_MESSAGE); 

    } 
} 

Новый улучшенный ответ:

Чтобы показать номер строки, я думаю, что в Stream сек подход не будет работать или будет слишком сложный. Таким образом, позволяет использовать специализированный метод вместо:

import javax.swing.JOptionPane; 
import javax.swing.JTextArea; 

public class RoulleteChecker { 

    private static final int TIMES = 99999999; 

    public static void main(String args[]) { 

     int a[] = new int[36]; 

     for (long roll = 1; roll <= TIMES; roll++) { 
      int r = (int) (Math.random() * a.length); 
      ++a[r]; 
     } 

     JTextArea outputArea = new JTextArea(); 

     outputArea.setText("Lets see:\n" + asString(a)); 

     JOptionPane.showMessageDialog(null, outputArea, 
       "Searching for the frequency: " + TIMES + " times", JOptionPane.INFORMATION_MESSAGE); 
    } 

    private static String asString(int[] s) { 
     StringBuilder sb = new StringBuilder(8 * s.length); 
     for (int i = 0; i < s.length; i++) { 
      sb.append(i + 1).append(": ").append(s[i]).append("\n"); 
     } 
     return sb.toString(); 
    } 
} 

Там есть несколько различий больше:

  • Поскольку 0th позиция массива только для временного хранения вновь сгенерированный номер, позволяет получить его из массива полностью. Это переменная r. И так как я удалил 0-ю позицию массива, я удалил + 1 на ++a[a[0] + 1], который стал просто ++a[r].

  • Я переместил число раз (99999999) на константу. Это облегчает его смену при необходимости.

  • Опять же, поскольку я удалил 0-ю позицию массива, я также удалил 1 + из строки, которая рассчитала случайное число. Кроме того, я заставил его динамически массировать размер массива, поэтому вам не нужно отслеживать размер массива при создании и случайном доступе к одной из своих позиций.

  • Метод asString должен быть довольно простым. Только Гоча является i + 1, где + 1 имеет целью показать индексы, начиная с 1 вместо 0.

  • параметра на конструктору StringBuilder «ы в методе asString просто в общей сложности String размера оценочный для выполнения , это не важно.

+0

Спасибо :) Я меняю его прямо сейчас! – NicktehPro

+0

Можете ли вы рассказать мне что-то еще, я хочу, чтобы каждая строка начиналась с числа.Но я хочу, чтобы это число было другим в других строках, таких как 1: \ n 2: \ n 3 и т. Д. От 0 до 34 вы можете мне помочь? Спасибо – NicktehPro

+0

@NicktehPro Я отредактировал мой ответ. :) –

0

Это Java:

a[0-35] 

на самом деле означает:

a[-35] 

Что заставляет вас думать, -35 является допустимым индексом? Вы видите --- вся информация, которая вам нужна для исправления ошибки, есть - вам просто нужно внимательно прочитать сообщение об исключении. Он сообщает вам об ошибке, и он сообщает вам неверный индекс!

И btw: рассмотрите инструкцию switch.

Вы действительно думаете, что вам нужно записать переключатель, который более или менее делает

case i: 
    i++; 

?

+0

Почему это -34? – ReneS

+1

Опечатка, опечатка; Я имел в виду -35 (из-за 0-35). – GhostCat

+0

Спасибо, мой друг :) – NicktehPro

2

Ошибка этой линии:

outputArea.setText("Lets see: " + a[0-35]); 

- знак арифметического минус оператор. Итак, 0 - 35 - -35, что, конечно, не является допустимым индексом. Я предполагаю, что вы хотите, чтобы напечатать диапазон от 0 до 35, что может быть сделано с Arrays.toString:

outputArea.setText("Lets see: " + Arrays.toString(a)); 
+0

Действительно благодарю вас :) – NicktehPro

Смежные вопросы