[java] arrayindexoutofboundsexception

Moderators: jkien, Xilvo

Gebruikersavatar
Berichten: 37

[java] arrayindexoutofboundsexception

Bij het maken van een oefening op arrays krijg ik ArrayIndexOutOfBoundsException-foutje.

De vraag: ( komt uit een VB.net leerboekje en ik probeer ze op te lossen in java )
Beschrijving

Maak een programma dat aan de gebruiker vraag hoeveel getallen er worden ingevoerd.

Creëer een array die net voldoende elementen heeft om dit aantal getallen te stockeren.

Vul de array op met de door de gebruiker ingevoerde getallen.

Breng de inhoud van de array op de console.

Verwissel nu alle twee opeenvolgende getallen van positie. In onderstaand programa-verloop ( waar we 5 elementen in de array hebben ) worden de elementen op indexen 0 en 1 en op de indexen 2 en 3 met elkaar verwisseld. Indien de array een oneven aantal elementen heeft, hoeft het laatste getal niet van positie te veranderen.

Breng nu opnieuw de inhoud van de array op de console.

Zorg ervoor dat je programma exact hetzelfde programma-verloop heeft, met dezelfde output, als hieronder is weergegeven.

Programma-verloop ( invoer van de gebruiker ) :



Count : 5

Number 1 : 11

Number 2 : 22

Number 3 : 33

Number 4 : 44

Number 5 : 55

Numbers Before Shift : 11 22 33 44 55

Numbers After Shift : 22 11 44 33 55
en mijn code :

Code: Selecteer alles

 public class SwitchInputNumbers {

 

public static void main(String[] args) {

/*int [] intArray;

  //declareer een array van integers

intArray = new int[10];		   //hang er een feitelijke array achter, waarin 10 elementen zitten ( zowel maximaal als minimaal, de grens is vast)

for(int i = 0; i < intArray.length; i ++)  //Loop de array door tot de maximale lengte, begin natuurlijk bij 0.

{

intArray[i] = i;

//Vul de array met nummers.

System.out.print(intArray[i] + " ");

}

 		System.out.println();*/

  Input l = new Input();

  System.out.print("Count : ");

  int aantalNum = l.readInt();

  int[] numbers;  // An array for storing the input values.

  int numCt;	  // The number of numbers saved in the array.

  int num;		// One of the numbers input by the user.

  

  numbers = new int[aantalNum];   // Space for x ints.

  int[] list = new int[aantalNum];

  numCt = 0;

// No numbers have been saved yet.

  

  while (true) {   // Get the numbers and put them in the array.

 System.out.print("Number "+(numCt+1)+" : ");

 num = l.readInt();

 

 numbers[numCt] = num;

 list[numCt] = num;

 numCt++;

 

 

 if (numCt == aantalNum)

break;

 

  } // end whilelus

  

  System.out.print("Numbers Before Shift : ");

  

  for (int i = 0; i <= numCt-1; i++) {

  System.out.print( " " + numbers[i] + " " );

  

  } // end forlus

  System.out.println("");

  System.out.print("Numbers After Shift : ");

  for (int i = -1; i <= numCt-1; i++) {

  i=i+1;

  int j=-1;

  j=i+1;

  

  int a;

  

  a=i;

  i=j;

  j=a;

  

  

System.out.print( " " + numbers[i] + " " );

  System.out.print( " " + list[j] + " " );

 i=a;

 j=i;

 

  

  } // end forlus

 

   

  System.out.println("");

} // end main();

 }  // end class SwitchInputNumbers
Bij het laatste deel moet ik een keer j=i+1 en een keer i=i+1 om respectievelijk 0de,2de,4de,.. en 1ste,3de,5de,.. getallen te hebben uit mijn array, maar omdat ik i+1 doe ga ik volgens mij buiten mijn array.

Ik heb nog een array bijgemaakt met range [aantalNum+1] en als ik de array [aantalNum] naar [aantalNum+1] kopieer en het afbeeld op het scherm krijg ik nullen te zien.

Btw.. mijn werkwijze is hoogstwaarschijnlijk allesbehalve de juiste. :D

Bestaat er een syntax om 2 getallen van een array van plaats te wisselen? Iemand suggestie?

Berichten: 7.068

Re: [java] arrayindexoutofboundsexception

Btw.. mijn werkwijze is hoogstwaarschijnlijk allesbehalve de juiste. :D
Het probleem is dat je werkwijze slordig is, waardoor je het overzicht verliest en het jezelf moeilijker maakt dan het daadwerkelijk is. Dit leidt tot het soort fouten die je nu tegenkomt.

Code: Selecteer alles

while (true) {   // Get the numbers and put them in the array.
Je weet al hoeveel nummers je gaat krijgen. Gebruik dus een for-lus.

Code: Selecteer alles

for (int i = 0; i < aantalNum; i++) {

  System.out.print("Number "+(numCt+1)+" : ");

  num = l.readInt();

  numbers[i] = num;

}
Het volgende:

Code: Selecteer alles

for (int i = 0; i <= numCt-1; i++)
is equivalent met:

Code: Selecteer alles

for (int i = 0; i < aantalNum; i++)
Dit laatste geeft weer wat je wil doen (in tegenstelling tot het eerste wat 'toevallig' hetzelfde doet).

Code: Selecteer alles

for (int i = -1; i <= numCt-1; i++) {

  i=i+1;

  int j=-1;

  j=i+1;
Wederom vaag. Vermoedelijk verzin je wat je wilt doen terwijl je aan het tikken bent. Dit is niet handig. Stapje terug doen. Even afstand bewaren en je ziet:

Code: Selecteer alles

for (int i = 0; i < aantalNum; i++) {

  int j= i+1;
Dan zie je ook dat even later de volgende code helemaal niks zinnigs doet:

Code: Selecteer alles

i=a;

j=i;
Zie je waarom? (Edit: ik geloof dat ik me hier vergist heb. De code is noodzakelijk omdat je de zonde begaat dat je je loop-variabele aanpast. Dat is een erg slecht idee, want dat leidt tot onoverzichtelijke code.)



De tip die ik geef is dus dat je het geheel abstracter aanpakt. Probeer deeltaken te zien. Je begint dus met:

* lees hoeveel getallen er gelezen moeten worden.

* lees zoveel getallen.

* print deze getallen.

* verwissel de paartjes getallen van positie.

* print de nieuwe volgorde.

Eventueel kun je deze deeltaken nog verder opsplitsen. Ook is het gebruik van methodes aan te raden (deeltaak = een methode). Hierdoor bewaar je ook beter overzicht over wat je wilt bereiken met een stukje code.

Gebruikersavatar
Berichten: 4.810

Re: [java] arrayindexoutofboundsexception

Ik heb nog een array bijgemaakt met range [aantalNum+1] en als ik de array [aantalNum] naar [aantalNum+1] kopieer en het afbeeld op het scherm krijg ik nullen te zien.


Wat versta je onder kopiëren? Alle waardes 1 voor 1 kopiëren? Enkel gelijk stellen aan mekaar (referenties dus uitwisselen)? Of hoe doe je dit precies?

Berichten: 7.068

Re: [java] arrayindexoutofboundsexception

Ik heb je code wat opgeschoond. Ik heb deze code niet getest, dus er zouden best wat fouten in kunnen zitten. Hopelijk verduidelijkt deze code dat een systematische aanpak een duidelijker programma oplevert.

Code: Selecteer alles

public class SwitchInputNumbers {

  public static void main(String[] args) {

Input l = new Input();

System.out.print("Count : ");

int aantalNum = l.readInt();

int[] numbers = new int[aantalNum];  // An array for storing the input values.

for (int numCt = 0; numCt < aantalNum; numCt++) {

 System.out.print("Number " + (numCt+1) +" : ");

 numbers[numCt] = l.readInt();

}

System.out.print("Numbers Before Shift : ");

printNumbers(numbers);

  

numbers = swapNumbers(numbers);

System.out.print("Numbers After Shift : ");

printNumbers(numbers);

  } // end main();

  // prints all numbers in the array with a space between them, ending with a newline.

  public static void printNumbers(int[] nums) {

for (int i = 0; i < nums.length; i++) {

  System.out.print( " " + nums[i] + " " );

}

System.out.println("");

  }

  // swap the value at the uneven position in the array with the value preceding it.

  public static int[] swapNumbers(int[] nums) {

for (int i = 1; i < nums.length; i = i + 2) {

int temp = nums[i-1];

nums[i-1] = nums[i];

nums[i] = temp;

}

return nums;

  }

}  // end class SwitchInputNumbers

Re: [java] arrayindexoutofboundsexception

Merk ook de plaats waar Evilbro zijn commentaren plaatst.

Je code ziet er mede rommelig uit vanwege de plaats en overbodigheid van veel commentaren.

V.b. intArray = i; //Vul de array met nummers.

Dat zie ik ook wel. Ik zie zelfs met welke getallen.

Het enige wat ik in Evilbro's code minder geslaagd vind is de letter I (of staat er l, in ieder geval is het teken gelijk aan het teken voor 1) in

Input l = new Input();

Gebruikersavatar
Berichten: 37

Re: [java] arrayindexoutofboundsexception

Ik begin het stillekes aan te snappen. Bedankt heren!
Wat versta je onder kopiëren? Alle waardes 1 voor 1 kopiëren? Enkel gelijk stellen aan mekaar (referenties dus uitwisselen)? Of hoe doe je dit precies?
Ja, ik had het enkel gelijk gesteld aan mekaar, 'klein'-foutje. :/
PeterPan schreef:Het enige wat ik in Evilbro's code minder geslaagd vind is de letter I (of staat er l, in ieder geval is het teken gelijk aan het teken voor 1) in

Input l = new Input();
Mijn fout. Er staat inderdaad een l. Ik had beter 'keyboard' moeten gebruiken..

EvilBro, ik heb je code doorgenomen en ik snap het volledig. Nogmaals bedankt.

Ik heb nog veel werk voor de boeg éh?

Gebruikersavatar
Berichten: 1.623

Re: [java] arrayindexoutofboundsexception

Mijn fout. Er staat inderdaad een l. Ik had beter 'keyboard' moeten gebruiken..
Nee, da's ook geen goede naam. Waarom gebruik je niet gewoon:

Code: Selecteer alles

Input input = new Input();
Beter kaal als geen haar want een kip snurkt

Gebruikersavatar
Berichten: 2.902

Re: [java] arrayindexoutofboundsexception

zpidermen schreef:Nee, da's ook geen goede naam. Waarom gebruik je niet gewoon:

Code: Selecteer alles

Input input = new Input();
Ik begrijp niet waarom l geen goede naam is ?

Het is misschien een klein beetje onduidelijk het verschil tussen de l en de i maar wanneer je iets zelf schrijft dan weet je toch duidelijk wat je gebruikt !

Ik gebruik persoonlijk ook altijd l omdat men dat zo heeft aangeleerd, in mijn cursus gebruiken ze altijd Input inp = ...

maar waarom meerdere letters typen als je veel sneller kan werken door het gebruik van 1 letter.

Berichten: 7.068

Re: [java] arrayindexoutofboundsexception

Het is misschien een klein beetje onduidelijk het verschil tussen de l en de i maar wanneer je iets zelf schrijft dan weet je toch duidelijk wat je gebruikt !
Nu denk je misschien dat het duidelijk is wat je schrijft, maar als je je code over een paar maanden terug ziet dan weet je het niet meer.
Ik gebruik persoonlijk ook altijd l omdat men dat zo heeft aangeleerd, in mijn cursus gebruiken ze altijd Input inp = ...
Dit laatste is veel beter.
maar waarom meerdere letters typen als je veel sneller kan werken door het gebruik van 1 letter.
Dit is een vorm van kortzichtigheid. Het 'extra' werk dat je nu creeert (de twee extra letters) besparen je veel meer werk in de toekomst.

Daar komt nog bij dat het nu gaat om een klein programma. Op het moment dat je echte programma's gaat schrijven, kom je er wel achter dat je methode voor naamgeving niet prettig werkt. Maar ja, dan is het al te laat, want je hebt het jezelf immers zo aangeleerd...

Gebruikersavatar
Berichten: 2.902

Re: [java] arrayindexoutofboundsexception

Ik kan begrijpen dat wanneer je werkt in grotere programma's dat het inderdaad voor problemen kan beginnen zorgen.

Jij weet hierover veel meer als mij dus ga ik bij mijn volgende programma overschakelen denk ik naar Input inp = new Input().

Input keyboard = new Input() dat is er nu net iets over dus zal ikzelf nooit gebruiken.

Berichten: 7.068

Re: [java] arrayindexoutofboundsexception

Ik kan begrijpen dat wanneer je werkt in grotere programma's dat het inderdaad voor problemen kan beginnen zorgen.
Het wordt helemaal leuk als anderen met je code verder moeten gaan. :D

Gebruikersavatar
Berichten: 37

Re: [java] arrayindexoutofboundsexception

Input input = new Input();
Dit zou ik zelf nooit gebruiken, ik vind het verwarrend.
Input l = new Input();

Input inp = new Input();
Die twee gebruik(t)en we ook op school.
Input keyboard = new Input();
Nu en dan gebruik ik deze, omdat het direct naar het input verwijst. Duidelijker, maar ik weet niet of in java functies ofzo zijn die met 'keyboard' beginnen.

Magoed, ik zal voortaan inp gebruiken :P

Klein extraatje toegevoegd. 'reverse' numbers :D

Code: Selecteer alles

public class SwitchInputNumbers {

  public static void main(String[] args) {

Input inp = new Input();

System.out.print("Count : ");

int aantalNum = inp.readInt();

int[] numbers = new int[aantalNum];  // An array for storing the input values.

for (int numCt = 0; numCt < aantalNum; numCt++) {

 System.out.print("Number " + (numCt+1) +" : ");

 numbers[numCt] = inp.readInt();

 

}

System.out.print("Numbers In Reverse Order : ");

reverseNumbers(numbers);

System.out.print("Numbers Before Shift : ");

printNumbers(numbers);

  

numbers = swapNumbers(numbers);

System.out.print("Numbers After Shift : ");

printNumbers(numbers);

  } // end main();

  // prints all numbers in the array in reverse order with a space between them, ending with a newline.

  public static void reverseNumbers(int[] nums) {

for (int i = nums.length-1; i >= 0; i--) {

  System.out.print( " " + nums[i] + " " );

}

System.out.println("");

  }

  // prints all numbers in the array with a space between them, ending with a newline.

  public static void printNumbers(int[] nums) {

for (int i = 0; i < nums.length; i++) {

  System.out.print( " " + nums[i] + " " );

}

System.out.println("");

  }

  // swap the value at the uneven position in the array with the value preceding it.

  public static int[]  swapNumbers(int[] nums) {

for (int i = 1; i < nums.length; i = i + 2) {

int temp = nums[i-1];

nums[i-1] = nums[i];

nums[i] = temp;

}

return nums;

  }

}  // end class SwitchInputNumbers
Ik vroeg me ook af waarom er static bij die methodes moest staan. Ik heb ze verwijderd, gecompiled en ik zag dat je niets van methoden kunt terugroepen via je main. Ooit las ik ergens van klasse- en instantie variabele maar ik weet het niet meer. Is dit de reden?

Berichten: 7.068

Re: [java] arrayindexoutofboundsexception

Ik vroeg me ook af waarom er static bij die methodes moest staan.
Methodes horen normaal gesproken bij een object. Als dat object er niet is dan zijn die methodes er ook niet. Op het moment dat je een methode static maakt dan bestaat de methode los van alle mogelijke objecten van die klasse.

In het programma dat je runt maak je helemaal geen object. Als de methodes niet static zouden zijn, zouden ze dan dus niet bestaan. Ze zijn dan ook niet aan te roepen. Doordat de methodes static zijn bestaan ze los van eventuele objecten. Daardoor zijn ze wel aan te roepen (want ze bestaan).

Gebruikersavatar
Berichten: 4.810

Re: [java] arrayindexoutofboundsexception

Die static staat er zodanig dat je geen object moet aanmaken van je klasse. Als je die static weghaalt moet je dat uiteraard wel doen en dan krijg je dit als main:

Code: Selecteer alles

  public static void main(String[] args) {

Input inp = new Input();

SwitchInputNumbers sin = new SwitchInputNumbers();

System.out.print("Count : ");

int aantalNum = inp.readInt();

int[] numbers = new int[aantalNum];  // An array for storing the input values.

for (int numCt = 0; numCt < aantalNum; numCt++) {

 System.out.print("Number " + (numCt+1) +" : ");

 numbers[numCt] = inp.readInt();

}

System.out.print("Numbers In Reverse Order : ");

sin.reverseNumbers(numbers);

System.out.print("Numbers Before Shift : ");

sin.printNumbers(numbers);

  

numbers = sin.swapNumbers(numbers);

System.out.print("Numbers After Shift : ");

sin.printNumbers(numbers);

  } // end main();

Gebruikersavatar
Berichten: 37

Re: [java] arrayindexoutofboundsexception

Ik begrijp het. Bedankt voor de uitleg, heren.

Reageer