# Array Index Out of Bounds



## Xerxes20 (8. Nov 2010)

Hallo,

ich bin gerade an der nächsten Übung dran. Leider verstehe ich nicht was ich hier falsch gemacht habe. Folgender Fehler tritt auf:

Array Index out of Bounds

Was ich da herausinterpretieren kann ist, dass mein Array zu klein sei. Das Problem ist, dass Array muss auf 10 Stellen begrenzt sein, da die Aufgabe lautet:

Schreiben Sie ein Programm, mit dem 10 eingegebene Integer-Zahlen aufsteigend sortiert werden können. Verwenden Sie dafür den MergeSort-Algorithmus, wie er unten beschrieben ist. Zuerst sollen 10 ganze Zahlen eingegeben werden können und in einem Array gespeichert werden. Der Benutzer soll solange zur Eingabe aufgefordert werden, bis er dem 10 gültige Zahlen eingegeben hat. Danach sollen alle Arraywerte ausgegeben werden, damit man einen Überblick bekommt, welche Zahlen der Reihe nach eingegeben wurden und zu sortieren sind.

Hier mein bisheriger Code:


```
public class sort
{
public static void main ( String[] args ) 
{
System.out.println ("");
System.out.println ("Dieses Programm Sortiert Zahlen!");
System.out.println ("");
int a,b,c,d,e,f,g,h,i,j;
do {
System.out.println("Geben sie bitte ganze Zahlen ein die > 0 sind:");
 a= In.readInt();
 b= In.readInt();
 c= In.readInt();
 d= In.readInt();
 e= In.readInt();
 f= In.readInt();
 g= In.readInt();
 h= In.readInt();
 i= In.readInt();
 j= In.readInt();
}
while (a<0 | b<0 |c<0|d<0|e<0|f<0|g<0|h<0|i<0|j<0);
int [] sorti ={ a,b,c,d,e,f,g,h,i,j};
for(int z=0; z<sorti.length; z++)
{
System.out.print(sorti[z]+" ");
}
if (sorti.length > 1) {
int center=sorti.length / 2;
int [] linkerTeil=new int [center];
int [] rechterTeil=new int [sorti.length-center];
for (int z=0;z<=center -1;z++){
linkerTeil[z]=sorti[z];
}
for (int z=center;z<=sorti.length;z++){
rechterTeil[z]=sorti[z];

}
}
System.out.println(sorti);
}
}
```


----------



## M4D-M4X (8. Nov 2010)

Ich kann dir jetzt zwar nicht die Ursache für den OutOfBounds liefern, aber mir sind zwei sachen aufgefallen:

1. In deiner do-While Schleife möchtest du ja nur Zahlen speichern die größer als null sind.
    Desswegen muss die while bedingung wie folgt heißen:

```
while (a<=0 | b<=0 |c<=0|d<=0|e<=0|f<=0|g<=0|h<=0|i<=0|j<=0);
```

2. Was ich ebenso ziemlich komische finde, ist, dass du dein Oder der While bedinung nur mit einem |      machst. Normalerweise nimmt man zwei. (Wenn ich falsch liege klärt mich bitte auf!) Also:

```
while (a<=0 || b<=0 ||c<=0 || d<=0 || e<=0 || f<=0 || g<=0 || h<=0 || i<=0 || j<=0);
```


edit:
Und poste mal (wenns überhaupt kompiliert) den Stacktrace mit.


----------



## Marcinek (8. Nov 2010)

Nicht das array ist zu klein, sondern der index auserhalb des arrays.

Kannst du bitte noch den Stacktrace posten, dann kann man sehen wo... und wieso.


----------



## Michael... (8. Nov 2010)

Warum liest Du die Eingabe nicht direkt ins Array ein? 
Außerdem ist nicht gerade schön, dass man bei einer Falscheingabe die komplette Eingabe wiederholen muss.

Die Fehlermeldung gibt auch an, in welcher Codezeile der Fehler auftritt und verweist Dich vermutlich auf die Zeile 36


Xerxes20 hat gesagt.:


> [JAVA=35]for (int z=center;z<=sorti.length;z++){
> rechterTeil[z]=sorti[z];[/code]


----------



## bone2 (8. Nov 2010)

```
for (int z=center;z<=sorti.length;z++){
```

zeile 35 ist ein <= statt <
und bitte rücke den code ein, is ja ein krampf das zu lesen, das geht schon mit notepad++ dem man sagen kan ndas es statt tab 4 leerzeichen macht. einfach und schön


----------



## Marco13 (8. Nov 2010)

Mir ist noch was aufgefallen: Wenn du 100 Zahlen auf diese Weise eingeben wollest, hättest du ein Problem. 

Ansonsten...

```
int [] linkerTeil=new int [center];
...
for (int z=0;z<=center -1;z++){
linkerTeil[z]=sorti[z];
```
"linkerTeil" hat Elemente 0 bis center-1...


----------



## Marcinek (8. Nov 2010)

M4D-M4X hat gesagt.:


> Ich kann dir jetzt zwar nicht die Ursache für den OutOfBounds liefern, aber mir sind zwei sachen aufgefallen:
> 
> 1. In deiner do-While Schleife möchtest du ja nur Zahlen speichern die größer als null sind.
> Desswegen muss die while bedingung wie folgt heißen:
> ...



Das eine ist ein Unärer und das andere ein Binärer Operator.

bei || wird, sobald das erste true ist die anderen nicht evluiert.

Bei | werden immer alle evaluiert.


----------



## M4D-M4X (8. Nov 2010)

Aber dann wäre | ja nichts anderes wie ein && oder seh ich das auch falsch?


----------



## Marcinek (8. Nov 2010)

M4D-M4X hat gesagt.:


> Aber dann wäre | ja nichts anderes wie ein && oder seh ich das auch falsch?



Nein

genau umgekehrt

bei einm & würden alle Ausdrücke evaluiert

Bei && beim ersten *false *nicht weiter evauiert, weil das gesamte dadurch nie true werden kann.


----------



## Xerxes20 (8. Nov 2010)

Hallo nochmal,

ersteinmal danke an euch alle! Bin wirklich gerührt, dass mir so viele helfen möchten 

Tut mir leid, dass ich den Code nicht eingerückt habe (Anfänger )

Der Fehler tritt in Zeile 38 auf :


----------



## nrg (8. Nov 2010)

oha. heute geht das ja schnell . Erstmal würde ich Michaels... Ratschlag Folge leisten.

Hier ein kleines Beispiel:


```
import java.io.*;
import java.math.BigInteger;

public class Test {
	public static void main(String[] args) throws IOException {
		BufferedReader bisr = new BufferedReader(new InputStreamReader(System.in));
		BigInteger max = new BigInteger(String.valueOf(Integer.MAX_VALUE));
		int[] array = new int[10];
		for (int i = 0; i < array.length; i++) {
			System.out.print("Bitte geben Sie die " + (i + 1) + "te Zahl ein> ");
			String eingabe = bisr.readLine();
			if (!eingabe.matches("[0-9]+")) {
				System.out.println("Die Eingabe war keine gültige Zahl!");
				i--;
			} else if (new BigInteger(eingabe).compareTo(max) > 0) {
				System.out.println("Die Zahl darf maximal " + Integer.MAX_VALUE + " groß sein!");
				i--;
			} else {
				array[i] = Integer.parseInt(eingabe);
			}
		}
		
		// Testausgabe
		System.out.println("\n----------");
		for (int i : array)
			System.out.println(i);
	}
}
```

Wenn dir Eingaben > Integer.MAX_VALUE egal sind kannste den else if rauslassen (und auch oben das BigInteger Objekt max). Kannst auch einfach bei 1mio kappen und die Stringlänge im else if überprüfen.

edit: die Antwort wollte ich schreiben, als ca. 3 geantwortet hatten. Nachdem ich jetzt Feierabend mache und wenig Lust habe alles durchzulesen, lasse ich das einfach mal so stehen. Vielleicht hilft es dir ja immernoch. Ansonsten einfach ignorieren


----------



## bone2 (8. Nov 2010)

Xerxes20 hat gesagt.:


> Hallo nochmal,
> 
> ersteinmal danke an euch alle! Bin wirklich gerührt, dass mir so viele helfen möchten
> 
> ...



ich les auf dem screenshot 36^^

udn wie schon gesagt ist der eigentliche fehler wohl das <= statt < in zeile 35


----------



## Xerxes20 (8. Nov 2010)

Hallo nrg,

das Problem ist wir sind totale Anfänger und der Code den du zugeschickt hast, sieht ziemlich komplex aus (für mich).
In der Aufgabe steht ja, dass der Benutzer solange Aufgefordert wird bis er der Eingabe von gültigen Zahlen nachgegangen ist.
Deswegen denke ich, dass wir den Teil überspringen können.

@bone2:

Lese-schreibfehler kann mal passieren


----------



## Michael... (8. Nov 2010)

Xerxes20 hat gesagt.:


> Der Fehler tritt in Zeile 38 auf :


Und wie schaut der Code in Zeile 38 aus? (eventuell ist auch noch die Zeile drüber interessant. Initialisierung der for-Schleife?)


----------



## bone2 (8. Nov 2010)

Funktioniert es denn wenn du das <= in < änderst?


----------



## Xerxes20 (8. Nov 2010)

Nein leider nicht


----------



## bone2 (8. Nov 2010)

```
if (sorti.length > 1) {
            int center = sorti.length / 2;
            int [] linkerTeil=new int [center];
            int [] rechterTeil=new int [sorti.length-center];

            for (int z=0; z < center; z++){
                linkerTeil[z] = sorti[z];
            }

            for (int z=0; z < rechterTeil.length; z++){
                rechterTeil[z] = sorti[z+center];
            }
        }
```

ergibt zwar inhaltlich wenig sinn, außer das er das sorti array auf 2 arrays aufteilt, aber out of bounds ist weg. schau es dir an und denk drüber nach^^ du kansnt nicht ein center langes array bei center starten udn dann noch höher gehen


----------



## tuttle64 (8. Nov 2010)

bone2 hat gesagt.:


> ```
> if (sorti.length > 1) {
> int center = sorti.length / 2;
> int [] linkerTeil=new int [center];
> ...




Oder anders ausgedrückt: Der Array rechterTeil ist mit sorti.length - center deklariert worden (im Beispiel mit Wert = 5) wird aber in der for-Schleife mit der vollen Länge von sorti durchlaufen. Klar, dass hier eine ArrayIndexOutOfBoundsException geworfen wird.


----------



## Xerxes20 (8. Nov 2010)

Okay das macht Sinn,

nur habe ich jetzt folgendes Problem:


----------



## tuttle64 (8. Nov 2010)

Xerxes20 hat gesagt.:


> Okay das macht Sinn,
> 
> nur habe ich jetzt folgendes Problem:




Gemäss mergeSort-Algorithmus sollten die Werte in deinem ursprünglichen Array sorti sortiert drinstehen, so dass Du sie mit  

for(int z=0; z<sorti.length; z++) {
System.out.print(sorti[z]+" "); }

ausgeben kannst. Abgesehen davon, funktioniert der Plus Operator in println nicht für die Datentypen int[].


----------



## XHelp (8. Nov 2010)

Bei dir stand mal:
[JAVA=40]
System.out.println(sorti);
[/code]
Ist das noch aktuell? So kannst du dein Array nicht ausgeben, musst es also mit einer Schleife machen.


----------



## Xerxes20 (8. Nov 2010)

hmm normalerweise sollte ich ja return benutzen aber der compiler schimpft dann, dass es zusammen mit void nicht klappt.

Wie gebe ich den am besten sorti ausgeben, also was müsste ich genau hinschreiben?


----------



## nrg (8. Nov 2010)

for (int i : sorti) {
System.out.println(i);
}

oder mit , verbunden. wie du magst


----------



## Xerxes20 (8. Nov 2010)

hmm irgendetwas scheine ich da noch falsch zu machen:


----------



## nrg (8. Nov 2010)

kein wunder bei der formation. fang vielleicht erstmal an den Code anständig einzurücken. da würd ich auch nicht mehr durchblicken...


----------



## Xerxes20 (8. Nov 2010)

Tut nir echt leid, hier ein eingerückjter Code:


```
public class sort
{
	public static void main ( String[] args ) 
	{
		System.out.println ();
		System.out.println ("Dieses Programm Sortiert Zahlen!");
		System.out.println ();
		int a,b,c,d,e,f,g,h,i,j;
			do {
			System.out.println("Geben sie bitte ganze Zahlen ein die > 0 sind:");
			a= In.readInt();
			b= In.readInt();
			c= In.readInt();
			d= In.readInt();
			e= In.readInt();
			f= In.readInt();
			g= In.readInt();
			h= In.readInt();
			i= In.readInt();
			j= In.readInt();
			} while (a<0 | b<0 |c<0|d<0|e<0|f<0|g<0|h<0|i<0|j<0);
				int [] sorti ={ a,b,c,d,e,f,g,h,i,j};
				for(int z=0; z<sorti.length; z++){
				System.out.print(sorti[z]+" ");
				}
					if (sorti.length > 1) 
					{
						int center=sorti.length / 2;
						int [] linkerTeil=new int [center];
						int [] rechterTeil=new int [sorti.length-center];
							for (int z=0;z<center -1;z++)
							{
							linkerTeil[z]=sorti[z];
							}
							for (int z=0;z<rechterTeil.length;z++)
							{
							rechterTeil[z]=sorti[z+center];
						}
					}
				for (int L : sorti) 
			{
			System.out.print(L);
		}
	}
}
```


----------



## nrg (9. Nov 2010)

ist immernoch miserabel formatiert. mir ist das doch egal, wie du den code hier postest. im zweifelsfall kopier ich das ins eclipse und drück strg+i. es geht hier eher um eine deutlich vereinfachte Fehleranalyse und einem besseren Überblick für *dich*


----------



## bone2 (9. Nov 2010)

das programm macht haargenau was du ihm sagst, in deinem fall:
-10 zahlen einlesen
-die 10 zahlen + " " mit print nebeneinander ausgeben
-das array mit den 10 zahlen in 2 neue arrays genau hälfte hälfte aufteilen
-dann alle 10 zahlen im sorti array mit print in je einer zeile ausgeben

genau das passiert auch, dein programm funktioniert.


----------



## nrg (9. Nov 2010)

Hier mal dein Code in normaler Formation, damit du vllt mal siehst, wie es aussehen sollte:

```
public static void main(String[] args) {
		System.out.println();
		System.out.println("Dieses Programm Sortiert Zahlen!");
		System.out.println();
		int a,b,c,d,e,f,g,h,i,j;
		do {
			System.out.println("Geben sie bitte ganze Zahlen ein die > 0 sind:");
			a= In.readInt();
			b= In.readInt();
			c= In.readInt();
			d= In.readInt();
			e= In.readInt();
			f= In.readInt();
			g= In.readInt();
			h= In.readInt();
			i= In.readInt();
			j= In.readInt();
		} while (a<0 | b<0 | c<0 | d<0 | e<0 | f<0 | g<0 | h<0 | i<0 | j<0);

		int [] sorti = {a,b,c,d,e,f,g,h,i,j};
		for(int z = 0; z < sorti.length; z++) {
			System.out.print(sorti[z] + " ");
		}

		if (sorti.length > 1) {
			int center = sorti.length / 2;
			int [] linkerTeil = new int [center];
			int [] rechterTeil = new int [sorti.length-center];
			for (int z = 0; z < center -1; z++) {
				linkerTeil[z] = sorti[z];
			}
			for (int z = 0; z < rechterTeil.length; z++) {
				rechterTeil[z] = sorti[z+center];
			}
		}
		for (int l : sorti) {  // Variablen sind lowerCamelCase
			System.out.print(l);
		}
	}[/Java]

zudem solltest du dir einheitliche persönliche Konventionen überlegen und dich, was noch viel wichtiger ist, an die allgemeinen Konventionen halten.

z.B.
schreibst du einmal [code]doIt( blabla );
```
ein ander mal 
	
	
	
	





```
doIt(blabla);
```

einmal

```
for (bla;bla;bla) {
```
ein ander mal

```
for (bla;bla;bla)
{
```

Allgemeine Konventionen hast du ja überwiegend eingehalten. Abgesehn von deinem int L


----------



## Xerxes20 (9. Nov 2010)

Alles klar, werde eure Tips befolgen.

War es dann nicht total Sinnlos, alles aufzuteilen in zwei Arrays abzuspeichern und dann wiederzugeben? Das macht doch auch die do While schleife ganz oben. 

Ich muss mich halt an folgendem Pseudotext orientieren:


----------



## Andi_CH (9. Nov 2010)

Ich meine mich an einen Sortieralgorithmus zu erinnern bei dem mit Hälften gearbeitet wird - ist es das :

Mahlzeit

EDIT: mergesort super dargestellt


----------



## bone2 (9. Nov 2010)

naja du hast bisher nur den anfang gebaut, quasi das aus der mergesort methode. das merge fehlt noch
das merge sort ruft sich ja rekursiv immer wieder selber auf bis nur noch ein ein element in der liste ist


----------



## Xerxes20 (9. Nov 2010)

ja stimmt, leider verstehe ich den Anfang des Pseudotextes schlecht.

Was ist denn hier mit "Das Array Result" wird zunächst mit Nullen befüllt" gemeint?

Und wie schreibe ich denn "die aktuelle Zahl"

Ich finde das sehr verwirrend mit dem Pseudo Text


----------



## Michael... (9. Nov 2010)

Xerxes20 hat gesagt.:


> Was ist denn hier mit "Das Array Result" wird zunächst mit Nullen befüllt" gemeint?


ein int Array wird bei der Initialisierung automatisch mit 0en befüllt. Kannst aber auch nochmal darüber iterieren und alle Felder explizit auf 0 setzen.


Xerxes20 hat gesagt.:


> Und wie schreibe ich denn "die aktuelle Zahl"


Du sollst ja die beiden Teil-Arrays mit einer Schleife durchlaufen, die aktuelle Zahlen sind dabei die Werte aus den beiden Teil-Arrays mit dem momentenen Schleifenindex


----------



## Xerxes20 (9. Nov 2010)

also auf anhieb hätte ich zwei while schleifen gemacht,aber dafür würde man zwei Variablen benötigen:

while rechterTeil<linkerTeil;
resulta=rechterTeil
while linkerTeil < rechterTeil;
resultb=linkerTeil

und dan am ende dann :

result [resulta,resultb]

ausgeben, aber das würde in sofern ja nicht funktionieren, weil er ja dann alle zusammen addieren und gucken würde ob diese größer als resulta oder resultb sind oder?


----------



## Michael... (9. Nov 2010)

Wie es aussieht hast Du den Mechanismus von MergeSort noch nicht so ganz verstanden. Schau Dir mal den Link von Andi_CH an. Hier wird neben dem PseudoCode die Funktionsweise auch recht anschaulich im Beispiel dargestellt.

Spiel das Beispiel mal mit Buchstabenkärtchen durch - sowas hilft oft beim Verständnis.


----------



## Xerxes20 (9. Nov 2010)

Den Mechanismus habe ich ja schon verstanden. Nur ich weiß halt nicht welche Schleife ich immer nutzen soll bzw. wie ich in dem Fall an die einzelnen Zahlen komme. 

Ich sage euch mal wie ich es gemacht hätte:

Ein Array mit 10 Plätzen(?) wird unterteilt in 2 Arrays mit jeweils 5 Plätzen und diese wiederum in einzelne Arrays, die miteinander verglichen und ausgegeben werden.

Das ganze könnte man sich doch gleich sparen und sagen, dass man direkt sich die einzelnen zahlen anguckt, miteinander vergleicht und dann ausgibt. Es würde zwar einen langen monotonen Text geben, aber es würde funktionieren und vom verständniss her auch besser sein, als das man immer und immer wieder unterteilt.

zurück zum Vergleichen der Inhalte:

1.liege ich richtig, dass linkerTeil und rechterTeil miteinander verglichen werden müssen?

könnte man es folgendermaßen ausdrücken:

if (linkerTeil[z] <= rechterTeil[z]);
result=linkerTeil[z]
linkerTeil[z]=linkerTeil[z+1]

else
result=rechterTeil[z]
rechterTeil[z]=rechterTeil[z+1]

hab mir jetzt echt mühe damit gegeben, hoffe mein Ansatz ist wenigstens ein wenig richtig ^^


----------



## Andi_CH (9. Nov 2010)

mergesort super dargestellt

Schau hier - ist doch ein super Darstellung


----------



## xXDasFischXx (26. Okt 2022)

public static String[][] EingabeDerVornamen(String[][]namenslistegefülltewerte, int anzahlnamen) {
    Scanner scanner = new Scanner(System.in);
    String eingabevornamen = "";
    int counter = 1;

    for (int i = 0; i < anzahlnamen; i++) {
        System.out.println(counter + ".Vorname: ");
        counter++;
        eingabevornamen = scanner.next();
        namenslistegefülltewerte[0]_ = eingabevornamen;
    }
    return namenslistegefülltewerte;
}

Warum ist hier ein Index out of bounds bei "namenslistegefülltewerte[0] = eingabevornamen;"?_


----------



## KonradN (26. Okt 2022)

a) bitte mach für Deine Probleme ein eigenen Thread auf.
b) Poste Code bitte immer in Code Tags - das geht am einfachsten über den Knopf </> links oberhalb des Eingabebereiches.

Und wenn Du da eine solche Exception bekommst, dann hat das Array, das du übergibst, die Länge 0 und damit gibt es kein Element an index 0.


----------

