我的程序因ArrayIndexOutofBoundsExeption错误而失败

时间:2015-03-07 17:57:50

标签: java swing indexoutofboundsexception

Hello我的程序无法与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变量上。

3 个答案:

答案 0 :(得分:2)

错误来自这一行:

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

-符号是算术减号运算符。所以,0 - 35是-35,当然,它不是有效的索引。我猜你想要打印0到35的范围,这可以通过Arrays.toString来完成:

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

答案 1 :(得分:1)

首先,所有这个巨大的开关都可以用这个代替:

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

然后,正如其他人已经指出的那样,a[0 - 35]并不意味着你想要的东西,它不会神奇地抓住阵列的0到35位置。只是将0的数学结果减去35,即-35。

在阵列上没有位置-35

要将数组表示为String,我们可以使用Java 8 Streams:

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")所做的。
  7. 最后,你不需要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();
        }
    }
    

    这里有一些不同之处:

    • 由于数组的第0个位置只是暂时保存新生成的数字,所以让它完全从数组中取出。这就是r变量。由于我删除了数组的第0个位置,因此我删除了+ 1上的++a[a[0] + 1]++a[r]只是1 +

    • 我将次数(99999999)移动到常量。这样可以在需要时更容易更改。

    • 同样,由于我删除了数组的第0个位置,我还从计算随机数的行中删除了asString。此外,我使它动态地获取数组的大小,因此您无需在创建数组时以及随机访问其中一个位置时跟踪数组大小。

    • i + 1方法应该非常简单明了。唯一的问题是+ 1,其中StringBuilder的目的是显示从1开始而不是0的索引。

    • asString方法中String构造函数的参数只是性能的总{{1}}大小估算值,并不重要。

答案 2 :(得分:0)

这是Java:

 a[0-35]

实际上意味着:

 a[-35]

是什么让你觉得-35是一个有效的索引?你看 - 你需要修复bug所需的所有信息 - 你只需要仔细阅读异常消息。它告诉你错误的位置,它会告诉你无效的索引!

顺便说一下:考虑一下你的switch语句。

你真的认为你需要记下一个或多或少的开关

case i:
  i++;