Permalänk

Java IndexOutOfBoundsException

Hej
Jag vill att säga ursäkta med språket(Jag är invandrare)

Jag har skapat ett egen ordspel i Java(Mitt första minispel som jag skapar ensam)
Regler är så:
Först man skriver ett ord. Till exempel Sweclockers
Nästa ord som man skriver, måste börja med samma bokstav som förra ordets sista bokstav. Till exempel Sverige.
Efter det emotion. Ord ska ha bara bokstäver och man får inte skriva samma ord två gånger. Spel ska försättas tills när man bryter mot regeln.(eller tusen gångar)

Min kod ses ut så här:

package SelfTest; import java.awt.*; import javax.swing.*; import java.util.List; import java.util.LinkedList; public class WordGame extends JFrame{ public static JTextArea ja = new JTextArea(100,100); public WordGame(){ add(ja); setSize(500,500); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } public static void main (String [] args){ List <String> wg = new LinkedList<String>(); String s = ""; while(s!=null){ for(int i = 0; i<=1000;i++){ s = JOptionPane.showInputDialog("Skriv ord"); s.toLowerCase(); if(s.matches("[a-zA-Z]+")&&(i==0)){ ja.setText(s); wg.add(s); } if(i>0&&s.matches("[a-zA-Z]+")&&!wg.contains(s)) { if (wg.get(wg.size()).charAt(s.length())==s.charAt(0)){ wg.add(s); } } if(!s.matches("[a-zA-Z]+")){ JOptionPane.showMessageDialog(ja, "Ord kan bestå bara av bokstäver"); break; } if(i>0&&wg.contains(s)){ JOptionPane.showMessageDialog(ja, "Du kan inte skriva samma ord två gånger"); break; } if(i>0&&wg.get(wg.size()-1).charAt(s.length())!=s.charAt(0)){ JOptionPane.showMessageDialog(ja, "Ordets första bokstav måste ha samma bokstav som förra ordets sista bokstav"); break; } } } } }

Jag har två problem de break satserna ligger i while satsen. Men, de fungerar inte. Man försätter visa dialogruta. Varför är det?(Inte viktig fråga)
(Viktig fråga) När man skriver två ord rätt till exempel (han - näsa) programmet visar IndexOutOfBoundsException på raden

if (wg.get(wg.size()).charAt(s.length())==s.charAt(0))

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.LinkedList.checkElementIndex(LinkedList.java:555) at java.util.LinkedList.get(LinkedList.java:476) at SelfTest.WordGame.main(WordGame.java:36) C:\Users\Secret\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1 BUILD FAILED (total time: 5 seconds)

Men jag förstår inte varför?? man räknar ut listans size och sista index. Med hjälp av charAt vi räknar ut sista indexets sista bokstav och jämför om är det lika med ordets första index som jag skrev nu. Om de är lika, det ord ska adderas till listan.

Förstår jag någonting fel???

JFrame, list och JTextArea jag har inte klarat och jag kan klara det med ingen problem. Jag har skrivit logiska algoritmer först

Permalänk

@ProgrammeringElev:

Jag har kollat min kod en gång till och jag har märkt att problem var att jag skrev s!=null. Jag tog bort själv while sats och problem med break sats är löst. Men andra problem är fortfarande irriterande.. Jag har provat att byta plats s.charAt(0) och wg.get bla bla men det fungerar inte.

Permalänk
Medlem

wg.get(wg.size()).charAt(s.length())==s.charAt(0))

Här hämtar du sista elementet från den länkade listan men du använder den inmatade strängens längd och försöker indexera i strängen i listan.
Något sånt här borde fungera.

String l = wg.getLast();
if (l.charAt(l.length()) !=s.charAt(0)) {
...
}

Visa signatur

flippy @ Quakenet

Permalänk
Skrivet av ante84:

wg.get(wg.size()).charAt(s.length())==s.charAt(0))

Här hämtar du sista elementet från den länkade listan men du använder den inmatade strängens längd och försöker indexera i strängen i listan.
Något sånt här borde fungera.

String l = wg.getLast();
if (l.charAt(l.length()) !=s.charAt(0)) {
...
}

Tack för svar! Men min netbeans visar att jag inte har metoden getLast()

Permalänk
Medlem

@ProgrammeringElev: Om du ännu har problem så tänk på att både listor och strings använder nollindexering (d.v.s. precis som array så är först värdet på plats 0, inte 1).

Säg att din lista har två värden: "han", "näsa"
Då finns "han" på plats 0, och "näsa" på plats 1
list.size() returnerar 2.
Försöker du ta list.get(list.size()) får du IndexOutOfBounds, för inget element finns på plats 2. Du bör därför ta list.get(list.size()-1) för att få sista. Precis samma sak gäller för en String, someString.charAt(someString.length()-1) för att få sista.

Vet inte om metoden getLast() du pratar om hör till List eller String, men den löser säkert problemet för den åtminstone.

Permalänk
Skrivet av Tazavoo:

@ProgrammeringElev: Om du ännu har problem så tänk på att både listor och strings använder nollindexering (d.v.s. precis som array så är först värdet på plats 0, inte 1).

Säg att din lista har två värden: "han", "näsa"
Då finns "han" på plats 0, och "näsa" på plats 1
list.size() returnerar 2.
Försöker du ta list.get(list.size()) får du IndexOutOfBounds, för inget element finns på plats 2. Du bör därför ta list.get(list.size()-1) för att få sista. Precis samma sak gäller för en String, someString.charAt(someString.length()-1) för att få sista.

Vet inte om metoden getLast() du pratar om hör till List eller String, men den löser säkert problemet för den åtminstone.

Tack för ditt svar!
Jag har redigerat mitt kod som du har sagt.

Men efter det, när man skriver ett lång ord, man får StringOutOfBoundsException på samma rad

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at java.lang.String.charAt(String.java:658) at SelfTest.WordGame.main(WordGame.java:38) C:\Users\Secret\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1 BUILD FAILED (total time: 7 seconds)

jag får error på charAt. Men, i raden
if (s.charAt(0)== wg.get(wg.size()-1).charAt(s.length()-1))
finns två charAt. Vilket charAt måste man tänka?

Permalänk
Medlem

Vet inte om du fått svar men här är mina spontana kommentarer(ursäkta om jag låter vresig ):

Du undrade varför dina breaks inte fungerade? Det är för att du försöker bryta dig ur if statementet efter att du redan visat dialogen. Break fyller ingen funktion här.

I dina if's kollar du även alltid om i>0 och ja det är det ju alltid så länge loopen körs, så det behöver du inte kolla.

Du har en konstruktor som aldrig kallas vad vi kan se, så den kan du ta bort.

Jag förstår inte vad for loopen är till för, den loopar 1000 gånger? Till vilken mening?

IndexOutOfBounds kastas när du, mycket riktigt, försöker använda ett index som inte ligger i intervallet. Tänk på nollindexeringen.

Förstår inte riktigt varför du ska lagra input strängen i en lista, blir det inte onödigt komplext när du egentligen bara ska jämföra två strängar åt gången?

Rent allmänt är koden ganska svårläst, försök skriv om den så blir det enklare att felsöka. Gör inte för mycket på samma rad, har tydligare variabel namn etc.

Här är mitt försök:

import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextArea; public class WordGame extends JFrame { public static JTextArea tA = new JTextArea(100, 100); public static void main(String[] args) { String first = ""; String second = ""; while (true) { // Input first = JOptionPane.showInputDialog("Skriv första ordet:"); second = JOptionPane.showInputDialog("Skriv andra ordet:"); if (first == null || second == null) { JOptionPane.showMessageDialog(tA, "Du måste ange två ord, spelet är slut!"); break; } // Error checking if (!first.matches("[a-zA-Z]+") || !second.matches("[a-zA-Z]+")) JOptionPane.showMessageDialog(tA, "Ord kan bestå bara av bokstäver!"); else if (first.equals(second)) JOptionPane.showMessageDialog(tA, "Du kan inte mata in samma ord två gånger!"); else if (first.charAt(first.length() - 1) != second.charAt(0)) JOptionPane.showMessageDialog(tA, "Ordets första bokstav måste ha samma bokstav som förra ordets sista bokstav"); else JOptionPane.showMessageDialog(tA, "Yay, ordet " + first + " sista bokstav matchar ordet " + second + " första bokstav!"); } } }

Har inte testat så noga, men tror den gör det du vill.

Permalänk
Medlem

@ProgrammeringElev: Som nämnts tidigare i tråden är det säkert för att du använder s.length. Är du säkert på att det är s du skall använda?

Permalänk
Medlem
Skrivet av Baxtex:

Vet inte om du fått svar men här är mina spontana kommentarer(ursäkta om jag låter vresig ):

Du undrade varför dina breaks inte fungerade? Det är för att du försöker bryta dig ur if statementet efter att du redan visat dialogen. Break fyller ingen funktion här.

Break-statements har ingen effekt på if-satser, han försöker bryta sig ur sin for-loop vilket han också gör, men eftersom han hade en onödig yttre while-loop i början så fortsatte programmet ändå.

Citat:

I dina if's kollar du även alltid om i>0 och ja det är det ju alltid så länge loopen körs, så det behöver du inte kolla.

i > 0 är falskt under första iterationen, och gör så att ingen jämförelse görs då, så det fyller sin funktion.

Citat:

Jag förstår inte vad for loopen är till för, den loopar 1000 gånger? Till vilken mening?

Han nämner i inlägget att det skall spelas tills man har matat in 1000 ord.

Permalänk
Skrivet av Tazavoo:

@ProgrammeringElev: Som nämnts tidigare i tråden är det säkert för att du använder s.length. Är du säkert på att det är s du skall använda?

Tyvärr jag är inte så säkert.
Min plan är att program ska jämföra ord som jag skrev nu med ord som ligger i listans sista platsen. Jag tänkte att skapa ett temporär värde och varje gång när man lägger ett ord till listan, det ord blir temporärt. Men jag har aldrig använt och aldrig sett i boken att man använder temporär värde när man använder lista i for-satsen . (När man gör det med array, jag såg det massa gånger. Till exempel när man gör sortering)

Det var bara min tanke. Jag vet inte om det är rätt väg..

Permalänk
Skrivet av Baxtex:

Vet inte om du fått svar men här är mina spontana kommentarer(ursäkta om jag låter vresig ):

Du undrade varför dina breaks inte fungerade? Det är för att du försöker bryta dig ur if statementet efter att du redan visat dialogen. Break fyller ingen funktion här.

I dina if's kollar du även alltid om i>0 och ja det är det ju alltid så länge loopen körs, så det behöver du inte kolla.

Du har en konstruktor som aldrig kallas vad vi kan se, så den kan du ta bort.

Jag förstår inte vad for loopen är till för, den loopar 1000 gånger? Till vilken mening?

IndexOutOfBounds kastas när du, mycket riktigt, försöker använda ett index som inte ligger i intervallet. Tänk på nollindexeringen.

Förstår inte riktigt varför du ska lagra input strängen i en lista, blir det inte onödigt komplext när du egentligen bara ska jämföra två strängar åt gången?

Rent allmänt är koden ganska svårläst, försök skriv om den så blir det enklare att felsöka. Gör inte för mycket på samma rad, har tydligare variabel namn etc.

Här är mitt försök:

import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextArea; public class WordGame extends JFrame { public static JTextArea tA = new JTextArea(100, 100); public static void main(String[] args) { String first = ""; String second = ""; while (true) { // Input first = JOptionPane.showInputDialog("Skriv första ordet:"); second = JOptionPane.showInputDialog("Skriv andra ordet:"); if (first == null || second == null) { JOptionPane.showMessageDialog(tA, "Du måste ange två ord, spelet är slut!"); break; } // Error checking if (!first.matches("[a-zA-Z]+") || !second.matches("[a-zA-Z]+")) JOptionPane.showMessageDialog(tA, "Ord kan bestå bara av bokstäver!"); else if (first.equals(second)) JOptionPane.showMessageDialog(tA, "Du kan inte mata in samma ord två gånger!"); else if (first.charAt(first.length() - 1) != second.charAt(0)) JOptionPane.showMessageDialog(tA, "Ordets första bokstav måste ha samma bokstav som förra ordets sista bokstav"); else JOptionPane.showMessageDialog(tA, "Yay, ordet " + first + " sista bokstav matchar ordet " + second + " första bokstav!"); } } }

Har inte testat så noga, men tror den gör det du vill.

Tack för ditt svar! Men jag har en fråga. Hur kan programmet komma ihåg ordet om man inte lägger det till någon array eller lista? Jag vill att program ska komma ihåg alla order som jag har mattat in och jämföra..

Permalänk
Medlem
Skrivet av ProgrammeringElev:

Tack för ditt svar! Men jag har en fråga. Hur kan programmet komma ihåg ordet om man inte lägger det till någon array eller lista? Jag vill att program ska komma ihåg alla order som jag har mattat in och jämföra..

Det stämmer att du behöver spara undan använda ord i någon sorts lista om ett ord ska vara tillåtet en gång som mest.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av ProgrammeringElev:

Tyvärr jag är inte så säkert.
Min plan är att program ska jämföra ord som jag skrev nu med ord som ligger i listans sista platsen. Jag tänkte att skapa ett temporär värde och varje gång när man lägger ett ord till listan, det ord blir temporärt. Men jag har aldrig använt och aldrig sett i boken att man använder temporär värde när man använder lista i for-satsen . (När man gör det med array, jag såg det massa gånger. Till exempel när man gör sortering)

Det var bara min tanke. Jag vet inte om det är rätt väg..

Du måste tänka efter lite nu, gå igenom den felande raden och tänk på vad varje del får för värde.

Du sa att felet kommer i följande rad:
if (s.charAt(0)== wg.get(wg.size()-1).charAt(s.length()-1))

Säg att wg innehåller orden ['hej', 'test']. Du har just matat in ordet 'butik', som lagras i s.
Vilket värde får då s.charAt(0)? Vad får we.get(wg.size()-1)? Vad får s.length()-1? Vad får wg.get(wg.size()-1).charAt(s.length()-1)?

Att du lagrar ordet i en temporär variabel är helt korrekt. Du kan också lagra wg.get(wg.size()-1) i en temporär variabel om du vill, så kanske felet kommer fram.

Permalänk
Skrivet av Tazavoo:

Du måste tänka efter lite nu, gå igenom den felande raden och tänk på vad varje del får för värde.

Du sa att felet kommer i följande rad:
if (s.charAt(0)== wg.get(wg.size()-1).charAt(s.length()-1))

Säg att wg innehåller orden ['hej', 'test']. Du har just matat in ordet 'butik', som lagras i s.
Vilket värde får då s.charAt(0)? Vad får we.get(wg.size()-1)? Vad får s.length()-1? Vad får wg.get(wg.size()-1).charAt(s.length()-1)?

Att du lagrar ordet i en temporär variabel är helt korrekt. Du kan också lagra wg.get(wg.size()-1) i en temporär variabel om du vill, så kanske felet kommer fram.

Tack jag ska prova att göra med temporär variabel och prova igen på helgen