title: Binary Search, Array Index Out of Bounds Java
body: <p>Firstly, I would like to say I am not asking for an answer more so advice so I can learn from this problem. Every time I run my code I get Array Index Out of Bounds on Line 254 of the ArrayOperations java file.</p>
  
  <pre><code>if (SearchKey == tempArray[middle])
  </code></pre>
  
  <p>I have added as many checks as I possibly can to this code and also have commented it as much as possible for your ease. Once again I am looking for advice on this not just a direct answer if possible. The Error always seems to give me the negative version of 1/2 of my data items 
  ex: 100,000 data items, Array Index Out of Bounds: -49,999. </p>
  
  <pre><code>import javax.swing.*;
  // File-related imports
  
  import java.io.IOException;
  import java.util.Scanner;
  import java.io.File;
  
  
  public class ArrayOperations
  {
  // File Parameters
  String DataFilePath;
  String DataFileName;
  
  String KeysFilePath;
  String KeysFileName;
  
  int NumberOfDataItems;
  int NumberOfKeys;
  int N;
  int BucketHashArraySize;
  int NoBuckets;
  //Array
  
  int[] OriginalArray = new int[1000000];
  int[] SortedArray = new int[1000000];
  int[] HashedArray = new int[2000000];
  int[] BucketHashedArray = new int[2000000];
  int[] KeysArray   = new int[1000000];
  
  long SSAverageAccessTime;
  long SSAverageCompSuc;
  long SSAverageCompFailed;
  long SSNumberKeysSuc;
  long SSNumberKeysFailed ;
  
  long BSAverageAccessTime;
  long BSAverageCompSuc   ;
  long BSAverageCompFailed;
  long BSNumberKeysSuc    ;
  long BSNumberKeysFailed ;
  
  long HSAverageAccessTime;
  long HSAverageCompSuc   ;
  long HSAverageCompFailed;
  long HSNumberKeysSuc    ;
  long HSNumberKeysFailed ;
  
  public ArrayOperations()
  {   
  // File Parameters
  DataFilePath = null;
  DataFileName = null;
  
  KeysFilePath = null;
  KeysFileName = null;
  
  NumberOfDataItems=0;
  NumberOfKeys     =0;
  N                =0;
  BucketHashArraySize = 0;
  NoBuckets =0;
  // Statistics
  
  SSAverageAccessTime       = 0;
  SSAverageCompSuc          = 0;
  SSAverageCompFailed       = 0;
  SSNumberKeysSuc           = 0;
  SSNumberKeysFailed        = 0;
  
  }   
  
  
  public void ReadDataFile() throws IOException
  {
  JFileChooser chooser = new JFileChooser();
  chooser.setDialogType(JFileChooser.OPEN_DIALOG );
  chooser.setDialogTitle("Open Data File");
  
  int returnVal = chooser.showOpenDialog(null);
  if( returnVal == JFileChooser.APPROVE_OPTION) 
      {
         DataFilePath = chooser.getSelectedFile().getPath();
         DataFileName = chooser.getSelectedFile().getName();
      }
  
      // read data file and copy it to original array
  if (DataFilePath != null)
  {
      try
      {
  
        int index = 0;
        Scanner integerTextFile = new Scanner(new File(DataFilePath));     
        while (integerTextFile.hasNext())
        {
              // read the next integer
          OriginalArray[index] = integerTextFile.nextInt();
          index++;
        }
          //  end of file detected
        integerTextFile.close();
        NumberOfDataItems = index;
      }
          catch (IOException ioe)
      {
          System.exit(0); 
      }     
  
  }
  else
      NumberOfDataItems = 0;
  }
  public void ReadKeysFile() throws IOException
  {
  JFileChooser chooser = new JFileChooser();
  chooser.setDialogType(JFileChooser.OPEN_DIALOG );
  chooser.setDialogTitle("Open Keys File");
  
  int returnVal = chooser.showOpenDialog(null);
  if( returnVal == JFileChooser.APPROVE_OPTION) 
      {
          KeysFilePath = chooser.getSelectedFile().getPath();
          KeysFileName = chooser.getSelectedFile().getName();
      }
      // read data file and copy it to original array
  if (KeysFilePath != null)
  {
      try
      {
        int index = 0;
        Scanner integerTextFile = new Scanner(new File(KeysFilePath));     
        while (integerTextFile.hasNext())
        {
              // read the next integer
          KeysArray[index]= integerTextFile.nextInt();
          index++;
        }
          //  end of file detected
        integerTextFile.close();
        NumberOfKeys = index;
      }
          catch (IOException ioe)
      {
          System.exit(0); 
      }     
  
  }
  else
      NumberOfKeys = 0;
  }
  public void SequentialSearch() 
  {
  SSAverageAccessTime     = 0;
  SSAverageCompSuc        = 0;
  SSAverageCompFailed     = 0;
  SSNumberKeysSuc         = 0;
  SSNumberKeysFailed      = 0;
  int SearchKey;
  int TotalNumberOfComparisons;
  long startTime = System.nanoTime();
  boolean found = false;
  
  for (int k=0; k&lt;NumberOfKeys; k++)
  {
      found = false;
      SearchKey = KeysArray[k];
      TotalNumberOfComparisons = 0;
      for (int d=0; d&lt;NumberOfDataItems; d++)
      {
          TotalNumberOfComparisons++;
          if (SearchKey == OriginalArray[d])
          {
              found = true;
          }
          if (found)break;
      }
      if(found)
      {
          SSAverageCompSuc = SSAverageCompSuc + TotalNumberOfComparisons;
          SSNumberKeysSuc ++;
      }
      else
      {
          SSAverageCompFailed = SSAverageCompFailed + TotalNumberOfComparisons;
          SSNumberKeysFailed ++;
      }
  }
  long estimatedTime = System.nanoTime() - startTime;
  
  if (NumberOfKeys != 0)
      SSAverageAccessTime = Math.round((estimatedTime/NumberOfKeys));
  else
      SSAverageAccessTime = 0;
  if(SSNumberKeysSuc != 0)
      SSAverageCompSuc        = Math.round (SSAverageCompSuc / SSNumberKeysSuc) ;
  else
      SSAverageCompSuc        = 0;
  if (SSNumberKeysFailed != 0)
      SSAverageCompFailed     = Math.round (SSAverageCompFailed / SSNumberKeysFailed) ;
  else
      SSNumberKeysFailed = 0;
  return;
  }
  public void BinarySearch() 
  {
  // makes a temporary array the length of the number of data items we gave it int[] tempArray = new int[NumberOfDataItems];
  // copies a portion of the original array (origionalArray = new int[1000000] above) that has the data inputs
  // we are copying only the portion of the original array the was given the data inputs when we opened the data item .txt
  for (int i = 0; i &lt; NumberOfDataItems; i ++)
  {
      tempArray[i]=OriginalArray[i];
  }
  // takes the temporary array and sorts it
  java.util.Arrays.sort(tempArray);
  
  BSAverageAccessTime     = 0;
  BSAverageCompSuc        = 0;
  BSAverageCompFailed     = 0;
  BSNumberKeysSuc         = 0;
  BSNumberKeysFailed      = 0;
  
  int SearchKey;
  int TotalNumberOfComparisons;
  long startTime = System.nanoTime();
  boolean found = false;
  int low = 0;
  int high = tempArray.length-1;
  // sets the midpoint
  int middle = (low-high)/2;
  
  for(int k = 0; k&lt;NumberOfKeys; k++)
  {
      SearchKey = KeysArray[k];
      TotalNumberOfComparisons = 0;
  
      for (int d=0; d&lt; Math.log(tempArray.length -1); d++)
      {
          TotalNumberOfComparisons++;
          // makes sure low doesn't go out of bounds
          if (low &lt; 0)
          {
              low = 0;
          }
          // make sure high doesn't go out of bounds
          if(high &gt;= tempArray.length)
          {
              high = tempArray.length-1;
          }
          // checks the midpoint against the key we are using
          if (SearchKey == tempArray[middle])
          {
              found = true;
          }
          // makes sure that if the midpoint doesn't equal the key we get false
          else
          if (low == high &amp;&amp; SearchKey != tempArray[middle])
          {
              found = false;
          }
          // if the key is greater than the middle we check the upper portion
          else
          if (SearchKey &gt; tempArray[middle])
          {
              low = (middle +1);
          }
          // if the key is less than the middle we check the lower portion
          else
          if (SearchKey &lt; tempArray[middle])
              high = (middle -1);
          if (found)break;
      }
      if(found)
      {
          BSAverageCompSuc = BSAverageCompSuc + TotalNumberOfComparisons;
          BSNumberKeysSuc ++;
      }
      else
      {
          BSAverageCompFailed = BSAverageCompFailed + TotalNumberOfComparisons;
          BSNumberKeysFailed ++;
      }
  }
  long estimatedTime = System.nanoTime() - startTime;
  
  if (NumberOfKeys != 0)
      BSAverageAccessTime = Math.round((estimatedTime/NumberOfKeys));
  else
      BSAverageAccessTime = 0;
  if(BSNumberKeysSuc != 0)
      BSAverageCompSuc        = Math.round (BSAverageCompSuc / BSNumberKeysSuc) ;
  else
      BSAverageCompSuc        = 0;
  if (BSNumberKeysFailed != 0)
      BSAverageCompFailed     = Math.round (BSAverageCompFailed / BSNumberKeysFailed) ;
  else
      BSNumberKeysFailed = 0;
  return;
  }
  
  public void HashedSearch() 
  {
  HSAverageAccessTime     = 0;
  HSAverageCompSuc        = 0;
  HSAverageCompFailed     = 0;
  HSNumberKeysSuc         = 0;
  HSNumberKeysFailed      = 0;
  int SearchKey;
  int TotalNumberOfComparisons;
  long startTime = System.nanoTime();
  boolean found = false;
  }
  public int FindPrime()
  {
  return 0;
  }
  public void Initialize()
  {
  
  
  
  }
  public void BHSearch()
  {
  
  
  }
  
  }   
  </code></pre>
  
  <p>Here is the Java GUI Code:</p>
  
  <pre><code>// GUI-related imports
  
  import java.awt.*;
  import java.awt.event.*;
  
  
  // File-related imports
  
  import java.io.IOException;
  
  
  public class Project04 extends Frame implements ActionListener
  {
  
  ArrayOperations arr = new ArrayOperations();
  
  String command = "";
  
  public static void main(String[] args)
  {
      Frame frame = new Project04();
  
  
      frame.setResizable(false);
      frame.setSize(900,620);
      frame.setVisible(true);
  
  }
  
  public Project04()
  {
      setTitle("Search Routines");
  
      // Create Menu Bar and menu items
      MenuBar mb = new MenuBar();
      setMenuBar(mb);
  
      // Create Menu Group Labeled "File"
  
      Menu FileMenu = new Menu("File");
  
      // Add it to Menu Bar
  
      mb.add(FileMenu);
  
      // Create Menu Items
      // Add action Listener 
      // Add to "File" Menu Group
  
      MenuItem miOpen = new MenuItem("Open");
      miOpen.addActionListener(this);
      FileMenu.add(miOpen);
  
      MenuItem miExit = new MenuItem("Exit");
      miExit.addActionListener(this);
      FileMenu.add(miExit);
  
      // Create Menu Group Labeled "File"
  
      Menu SearchMenu = new Menu("Search");
  
      // Add it to Menu Bar
  
      mb.add(SearchMenu);
  
      // Create Menu Items
      // Add action Listener 
      // Add to "Search" Menu Group
  
      MenuItem miSequentialSearch = new MenuItem("Sequential Search");
      miSequentialSearch.addActionListener(this);
      SearchMenu.add(miSequentialSearch);
  
      MenuItem miBinarySearch = new MenuItem("Binary Search");
      miBinarySearch.addActionListener(this);
      SearchMenu.add(miBinarySearch);
  
      MenuItem miHashedSearch = new MenuItem("Hashed Search");
      miHashedSearch.addActionListener(this);
      SearchMenu.add(miHashedSearch);
  
  
  
      WindowListener l = new WindowAdapter()
      {
  
          public void windowClosing(WindowEvent ev)
          {
              System.exit(0);
          }
  
          public void windowActivated(WindowEvent ev)
          {
              repaint();
          }
  
          public void windowStateChanged(WindowEvent ev)
          {
              repaint();
          }
  
      };
  
      ComponentListener k = new ComponentAdapter()
      {
          public void componentResized(ComponentEvent e) 
          {
              repaint();           
          }
      };
  
      // register listeners
  
      this.addWindowListener(l);
      this.addComponentListener(k);
  
  }
  
  //******************************************************************************
  //  called by windows manager whenever the application window performs an action
  //  (select a menu item, close, resize, ....
  //******************************************************************************
  
  public void actionPerformed (ActionEvent ev)
      {
          // figure out which command was issued
  
          command = ev.getActionCommand();
  
          // take action accordingly
  
          if("Open".equals(command))
          {
              try
              {
              arr.ReadDataFile();
              arr.ReadKeysFile();
              }
              catch (IOException ioe)
              {
                  System.exit(0); 
              }   
              repaint();      
          }
  
          else
          if("Exit".equals(command))
          {
              System.exit(0);
          }
          else
          if("Sequential Search".equals(command))
          {
              arr.SequentialSearch();
              repaint();
          }
          if("Binary Search".equals(command))
          {
              arr.BinarySearch();     
              repaint();
          }
          if("Hashed Search".equals(command))
          {
              arr.HashedSearch();         
              repaint();
          }
          if("Bucket Hashed Search".equals(command))
          {
              arr.BHSearch();         
              repaint();
          }
      }
  //********************************************************
  // called by repaint() to redraw the screen
  //********************************************************
  
      public void paint(Graphics g)
      {
  
          if("Open".equals(command))
          {
              // Acknowledge that file was opened
              if (arr.DataFileName != null)
              {
                  g.drawString("File --  "+arr.DataFileName+"  -- was successfully opened", 300, 200);
                  g.drawString("Number of Data Items = "+Integer.toString(arr.NumberOfDataItems), 330, 250);
              }
              else
              {
                  g.drawString("NO Data File is Open", 300, 200);
              }
              if (arr.KeysFileName != null)
              {
                  g.drawString("File --  "+arr.KeysFileName+"  -- was successfully opened", 300, 300);
                  g.drawString("Number of Keys = "+Integer.toString(arr.NumberOfKeys), 330, 350);
              }
              else
              {
                  g.drawString("NO Keys File is Open", 300, 300);
              }
              return; 
          }
  
          if("Sequential Search".equals(command) || "Binary Search".equals(command)|| 
                  "Hashed Search".equals(command) || "Bucket Hashed Search".equals(command) )
          {
              g.drawRect(100, 100, 700, 420);
              g.drawString("Experiment", 135, 200);
              g.drawLine(250,100,250,520);
              g.drawString("Data File Attributes -- "+Integer.toString(arr.NumberOfDataItems)+" Data Items", 450, 130);
              g.drawString("Key File Attributes -- "+Integer.toString(arr.NumberOfKeys)+" Keys", 450, 155);
              g.drawLine(250,175,800,175);
              g.drawString("Measured Criteria", 475,190 );
              g.drawLine(250,215,800,215);
              g.drawString("Successful Search", 410, 230);
              g.drawString("Unccessful Search", 640, 230);
              g.drawLine(360,245,800,245);
  
  
              g.drawLine(100,310,800,310);
              g.drawString("Sequential Search", 110, 325);
              g.drawLine(100,340,800,340);
  
              g.drawString("Average", 285, 260);
              g.drawString("Access", 285, 275);
              g.drawString("Time", 290, 290);
  
              g.drawLine(360,215,360,520);
              g.drawString("#", 400, 260);
              g.drawString("Keys", 400, 275);
              g.drawString("Found", 390, 290);
  
              g.drawLine(470,245,470,520);
              g.drawString("Average", 500, 260);
              g.drawString("No. Of", 500, 275);
              g.drawString("Comparisons", 485, 290);
  
              g.drawLine(580,215,580,520);
              g.drawString("# ", 620, 260);
              g.drawString("Keys", 620, 275);
              g.drawString("Not Found", 600, 290);
  
              g.drawLine(690,245,690,520);
              g.drawString("Average", 720, 260);
              g.drawString("No. Of", 720, 275);
              g.drawString("Comparisons", 700, 290);
  
              g.drawString(Long.toString(arr.SSAverageAccessTime), 255, 325);
              g.drawString(Long.toString(arr.SSNumberKeysSuc), 365, 325);
              g.drawString(Long.toString(arr.SSAverageCompSuc), 475, 325);
              g.drawString(Long.toString(arr.SSNumberKeysFailed), 585, 325);
              g.drawString(Long.toString(arr.SSAverageCompFailed), 695, 325);
  
              g.drawString("Binary Search", 110, 355);
              g.drawLine(100,370,800,370);
  
              g.drawString(Long.toString(arr.BSAverageAccessTime), 255, 355);
              g.drawString(Long.toString(arr.BSNumberKeysSuc), 365, 355);
              g.drawString(Long.toString(arr.BSAverageCompSuc), 475, 355);
              g.drawString(Long.toString(arr.BSNumberKeysFailed), 585, 355);
              g.drawString(Long.toString(arr.BSAverageCompFailed), 695, 355);
  
              g.drawString("Hashed Search", 110, 385);
              g.drawLine(100,400,800,400);
  
              g.drawString(Long.toString(arr.HSAverageAccessTime), 255, 385);
              g.drawString(Long.toString(arr.HSNumberKeysSuc), 365, 385);
              g.drawString(Long.toString(arr.HSAverageCompSuc), 475, 385);
              g.drawString(Long.toString(arr.HSNumberKeysFailed), 585, 385);
              g.drawString(Long.toString(arr.HSAverageCompFailed), 695, 385);
  
              // add code to display results for other searches   
          }
  
      }
  
  
  }   
  </code></pre>