Home > Back-end >  Arraylist index out of bounds in lotto ticket class
Arraylist index out of bounds in lotto ticket class

Time:07-08

I made a simple lottery game with 3 classes, one to create a lottery "ticket", one to create the objects to put in said class and another to test things. In my lottery ticket class, the user inputs 5 numbers and these numbers are added to a holder list where there's then a verification of several conditions to see where to place the number in the arraylist but for some reason, I'm getting an out of bound exception when I check index 1.

Leaving all classes below along with stacktrace

package jogoloto;
import java.util.ArrayList;

/**
 *
 * @author Nuno
 */
public class LinhaCartao {
    ArrayList<NumeroLoto> Nums;
    ArrayList<Integer> holder;

    public LinhaCartao(int n1, int n2, int n3, int n4, int n5) {
        Nums = new ArrayList<>(9);
        holder = new ArrayList<>();
        holder.add(n1);
        holder.add(n2);
        holder.add(n3);
        holder.add(n4);
        holder.add(n5);
            for(int n : holder){ 
                if(Nums.isEmpty() && n >=1 && n<=9 || 
Nums.get(0) == null && n >=1 && n<=9){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(0,num);
                    
                }
                else if(Nums.isEmpty() && n >=10 && n<=19 || 
Nums.get(1) == null && n >=10 && n<=19){ //EXCEPTION HERE
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(1,num);
                    
                }
                else if(Nums.isEmpty() && n >=20 && n<=29 ||
Nums.get(2) == null && n >=20 && n<=29){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(2,num);
                    
                }
                else if(Nums.isEmpty() && n >=30 && n<=39 || 
Nums.get(3) == null && n >=30 && n<=39){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(3,num);
                    
                }
                else if(Nums.isEmpty() && n >=40 && n<=49 || 
Nums.get(4) == null && n >=40 && n<=49){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(4,num);
                    
                }
                else if(Nums.isEmpty() && n >=50 && n<=59 || 
Nums.get(5) == null && n >=50 && n<=59){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(5,num);
                    
                }
                else if(Nums.isEmpty() && n >=60 && n<=69 || 
Nums.get(6) == null && n >=60 && n<=69){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(6,num);
                    
                }
                else if(Nums.isEmpty() && n >=70 && n<=79 || 
Nums.get(7) == null && n >=70 && n<=79){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(7,num);
                    
                }
                else if(Nums.isEmpty() && n >=80 && n<=89 || 
Nums.get(8) == null && n >=80 && n<=89){
                    NumeroLoto num = new NumeroLoto(n);
                    Nums.add(8,num);
                    
                }
                else System.out.println("N invalido");    
            }
    }
    
    public void imprimeLinha(){
        for(int i = 0; i<9; i  ){
            if(Nums.get(i).getNumero()>0){
                System.out.println(":" Nums.get(i).getNumero() ":");
            }
            else if(Nums.get(i)== null){
                System.out.println(":_:");
            }
        }
    }
    
    public void marcaNumeroAnunciado(int numero){
        for(NumeroLoto n : Nums){
            if(n.getNumero()==numero){
                n.setSaiu(true);
            }
        }
    }
    
    public int quantosNumerosPorMarcar(){
        int count = 0;
        for(NumeroLoto n : Nums){
            if(n.getEstado()==false){
                count  ;
            }
        }
        return count;
    }
    
    public boolean verificaLinhaCompleta(){
        int count = 0;
        for(NumeroLoto n : Nums){
            if(n.getEstado()==true){
                count  ;
            }
            if(count==5){
                return true;
            }
        }
        return false;
    }
    
    public int limpaLinha(){
        int count = 0;
        for(NumeroLoto n : Nums){
            if(n.getEstado()==true){
                count  ;
                Nums.remove(n);
            }
        }
        return count;
    }
}

package jogoloto;

/**
 *
 * @author Nuno
 */
public class NumeroLoto {
    int numero;
    public boolean saiu;

    public NumeroLoto(int numero) {
        this.numero = numero;
        saiu = false;
    }

    public int getNumero() {
        return numero;
    }
    
    public boolean getEstado(){
        return saiu;
    }

    public void setSaiu(boolean saiu) {
        this.saiu = saiu;
    }  
}

public class JogoLoto {

    public static void main(String[] args) {
        LinhaCartao l = new LinhaCartao(1, 20, 45, 58, 71); //EXCEPTION WHEN I CALL CONSTRUCTOR
        l.imprimeLinha();
        l.quantosNumerosPorMarcar();
    }
    
}

stacktrace:


Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
    at java.base/java.util.Objects.checkIndex(Objects.java:359)
    at java.base/java.util.ArrayList.get(ArrayList.java:427)
    at jogoloto.LinhaCartao.<init>(LinhaCartao.java:30)
    at jogoloto.JogoLoto.main(JogoLoto.java:14)
C:\Users\Nuno\AppData\Local\NetBeans\Cache\14\executor-snippets\run.xml:111: The following error occurred while executing this line:
C:\Users\Nuno\AppData\Local\NetBeans\Cache\14\executor-snippets\run.xml:68: Java returned: 1
BUILD FAILED (total time: 0 seconds)

CodePudding user response:

You are overcomplicating things way too much. There are obviously simpler approaches to achieve what you are trying to do. I will share a solition below where your code should work, with little modification in your current code as possible, but at the same time encourage you to refactor and try better aproaches.

First issue, the line Nums = new ArrayList<>(9); will not create a list with prefilled list having 9 values. It will just create an empty list (size == 0). 9 is just the initial capacity. change it to

Nums = new ArrayList<>(Arrays.asList(null,null,null,null,null,null,null,null,null));

Second issue remove all holder.remove(n) calls. (which you have already done in between)

third issue use Nums.add(index, n) to put an element at a specific index, but you need to remove the null first so that your list size still remains 9

if(Nums.get(0) == null && n >=1 && n<=9){ 
    NumeroLoto num = new NumeroLoto(n);
    Nums.remove(0);
    Nums.add(0, num);

}
else if(Nums.get(1) == null && n >=10 && n<=19){
    NumeroLoto num = new NumeroLoto(n);
    Nums.remove(1);
    Nums.add(1, num);

}
// ... and so on

fourth issue in your imprimeLinha method check for null first (change condition of if and else if) to avoid NullPointerException. If Nums.get(i) is null you cann't call Nums.get(i).getNumero()>0 without an NPE

public void imprimeLinha(){
    for(int i = 0; i<9; i  ){
        if(Nums.get(i)== null){
            System.out.println(":_:");
        }
        else if(Nums.get(i).getNumero()>0){
            System.out.println(":" Nums.get(i).getNumero() ":");
        }
    }
}

Fifth issue in all other metods add a null check in your if condition for the same reason as above

public void marcaNumeroAnunciado(int numero){
    for(NumeroLoto n : Nums){
        if(n != null && n.getNumero()==numero){    // <- n != null
            n.setSaiu(true);
        }
    }
}

For easier access your whole code modified:

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author Nuno
 */
public class LinhaCartao {

    ArrayList<NumeroLoto> Nums;
    ArrayList<Integer> holder;

    //1, 20, 45, 58, 71
    public LinhaCartao(int n1, int n2, int n3, int n4, int n5) {
        Nums = new ArrayList<>(Arrays.asList(null, null, null, null, null, null, null, null, null));
        holder = new ArrayList<>();
        holder.add(n1);
        holder.add(n2);
        holder.add(n3);
        holder.add(n4);
        holder.add(n5);
        for (int n : holder) {
            if (Nums.get(0) == null && n >= 1 && n <= 9) { 
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(0);
                Nums.add(0, num);

            } else if (Nums.get(1) == null && n >= 10 && n <= 19) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(1);
                Nums.add(1, num);

            } else if (Nums.get(2) == null && n >= 20 && n <= 29) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(2);
                Nums.add(2, num);

            } else if (Nums.get(3) == null && n >= 30 && n <= 39) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(3);
                Nums.add(3, num);

            } else if (Nums.get(4) == null && n >= 40 && n <= 49) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(4);
                Nums.add(4, num);

            } else if (Nums.get(5) == null && n >= 50 && n <= 59) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(5);
                Nums.add(5, num);

            } else if (Nums.get(6) == null && n >= 60 && n <= 69) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(6);
                Nums.add(6, num);

            } else if (Nums.get(7) == null && n >= 70 && n <= 79) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(7);
                Nums.add(7, num);

            } else if (Nums.get(8) == null && n >= 80 && n <= 89) {
                NumeroLoto num = new NumeroLoto(n);
                Nums.remove(8);
                Nums.add(8, num);

            } else {
                System.out.println("N invalido");
            }
        }
    }

    public void imprimeLinha() {
        for (int i = 0; i < 9; i  ) {
            if (Nums.get(i) == null) {
                System.out.println(":_:");
            } else if (Nums.get(i).getNumero() > 0) {
                System.out.println(":"   Nums.get(i).getNumero()   ":");
            }
        }
    }

    public void marcaNumeroAnunciado(int numero) {
        for (NumeroLoto n : Nums) {
            if (n != null && n.getNumero() == numero) {
                n.setSaiu(true);
            }
        }
    }

    public int quantosNumerosPorMarcar() {
        int count = 0;
        for (NumeroLoto n : Nums) {
            if (n != null && n.getEstado() == false) {
                count  ;
            }
        }
        return count;
    }

    public boolean verificaLinhaCompleta() {
        int count = 0;
        for (NumeroLoto n : Nums) {
            if (n != null && n.getEstado() == true) {
                count  ;
            }
            if (count == 5) {
                return true;
            }
        }
        return false;
    }

    public int limpaLinha() {
        int count = 0;
        for (NumeroLoto n : Nums) {
            if (n != null && n.getEstado() == true) {
                count  ;
                Nums.remove(n);
            }
        }
        return count;
    }
}

CodePudding user response:

As discussed in the discussion chat the constructor can be rewritten as this:

public LinhaCartao(int...holder) { ///... means there can be as many parameters as wanted (stored as array)
    nums = new ArrayList<>(Arrays.asList(new Integer[9])); //list with the length of 9; default values are 'null' 
    for (int n : holder) {
        int firstDigit = n / 10; //the int division by 10. So e.g. 24 / 5 = 2 and 67 / 10 = 6
        nums.set(firstDigit, n); //overrides the position in the list with the number n
    }
}
  •  Tags:  
  • java
  • Related