-2

Fines didácticos únicamente. Estoy practicando ArrayLists[] y tengo esta simple "app bancaria" que hace cosas como agregar una sucursal, agregar clientes, transacciones a un cliente, etc.

Una de sus funciones me está dando NullPointerException al intentar agregar un cliente y su correspondiente depósito inicial a una sucursal.

He modificado el metodo newClientAndTransaction varias veces, encarando el problema de varias maneras pero sigo sin encontrar cual es el error, u objeto inexistente.

Cual es el problema? Cómo puedo identificar este tipo de errores? Tengo entendido que es "común" en Java tener un NPE. Saludos.

[Main]

import java.util.Scanner;
public class Main {
    public static Scanner scanner = new Scanner(System.in);
    private static Bank banco = new Bank("Banco Central");


    public static void main(String[] args) {

        banco.addBranch("prueba");
        newClientAndTransaction();


    }

    public static void newClientAndTransaction() {
        System.out.println("Enter branch to open account in\n");

        String branchName = scanner.nextLine();
        banco.findBranch(branchName); //busca si en alguna posicion int de la lista de sucursales hay una con el nombre pasado

        //si lo encuentra pasa a usar el objeto Branch de la posicion donde encontró ese nombre para agregarle un cliente
        if (banco.findBranch(branchName) >= 0) {
            Branch sucursalDeRadicacion = banco.queryBranchObjectInArray(branchName);
            System.out.println("Branch " + branchName + " exists. It is branch #" + banco.findBranch(branchName));
            System.out.println("Please type new client name\n");
            String newClientName = scanner.nextLine();
            System.out.println("Enter initial deposit");
            double initialDeposit = scanner.nextInt();

            Branch.agregarCliente(sucursalDeRadicacion, newClientName, initialDeposit);

        } else {
            System.out.println("Can't add client because branch " + branchName +  " was not found");
        }

    }
}

[Branch]

import java.util.ArrayList;

public class Branch {

    private String branchName;
    private static ArrayList<Client> clients;

    public Branch(String name) {
        this.branchName = name;
        this.clients = new ArrayList<Client>();
        System.out.println("Sucursal " + name + " creada.");

    }


    public static void agregarCliente(Branch branchName, String name, double initialTransaction) {
        branchName.clients.add(new Client(name, initialTransaction));
        System.out.println("Cliente " + name + " agregado a esta sucursal. Transaccion inicial: " + initialTransaction);
    }

    public String getName() {
        return this.branchName;
    }
}

[Bank]

import java.util.ArrayList;

public class Bank {

    private String name;
    private ArrayList<Branch> branches;

    //CONSTRUCTOR
    public Bank(String name) {
        this.name = name;
        this.branches = new ArrayList<Branch>();


    }

    public void addBranch(String branchName) {
        Branch newBranch = new Branch(branchName);
        branches.add(newBranch);

    }

    public int findBranch(String branchNameToSearch) {
        int numOfBranches = this.branches.size();
        String queryToLowerCase = branchNameToSearch.toLowerCase(); //pasa a lower case para evitar problemas

        for (int i = 0; i < numOfBranches; i++) {
            String branchNameToLower = branches.get(i).getName().toLowerCase();
            boolean exists = queryToLowerCase.equals(branchNameToLower);
            if (exists) {
                return i;
            }

        }
        return -1;

    }

    public Branch queryBranchObjectInArray(String name) {
        int ArrayPositionOfNameSearched = findBranch(name);
        if (ArrayPositionOfNameSearched >= 0) {
            return this.branches.get(ArrayPositionOfNameSearched);
        }
        return null;


    }

}

[Client]

import java.util.ArrayList;

public class Client {

    private String clientName;
    private ArrayList<Double> transactions; // = new ArrayList<Double>()

    //CONSTRUCTOR
    public Client(String clientName, double initialTransactions) {
        this.clientName = clientName;
        this.transactions.add(initialTransactions);
    }
}
pinkfloyd90
  • 248
  • 1
  • 11
  • [Aquí tienes la respuesta](https://es.stackoverflow.com/a/42978/95505) de como evitar e identificar los NullPointerException – YemisiSCG Dec 03 '19 at 23:55
  • Depura pon un punto de ruptra en los emtodo y mira que va a nulo – unknow Dec 03 '19 at 23:59
  • Para evitar NullPointerExceptions es simple, siempre inicializa tus variables y nunca involucres asignaciones u operaciones en las que tengas que usar null, por ejemplo evita expresiones como miVariable == null. Desde Java 8 se agregaron las clases Optional las cuales ayudan a precisamente eso te recomiendo les des una leida: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html .Por ultimo si quieres ayuda con tu codigo sube tu traza de errores para ver la raiz de tu error – Eduardo Marin Dec 04 '19 at 00:20

1 Answers1

2

Te cuento porque tienes un lio gordo. 1º Los constructores se sobrecargar se crean 2 uno con parametros y otro sin ellos,en le constructor vacio se inicializan los array 2º nunca nunca nunca jams se pone print en un metodo que no sea el main 3º yo al menos agradeceria que programes en español porque no me entero de muchas cosas y otras las he tenido que buscar. 4º siempre se crean getter y setter 5º Respecto a tu null pointer es muy probable que venga de la clase cliente que nunca inicalizas el array. 6º y ultimo te he reeditado el codigo, corregido todo lo que he podido y entendido. Si tienes alguna duda pregunta o aclara que es para que te lo ponga correctamente. Cliente

public class Cliente {

    private String nombre;
    private List<Double> transactions; 

    public Cliente(String nombre, List<Double> transactions) {
        this.nombre = nombre;
        this.transactions = transactions;
    }

    public Cliente() {
        this.transactions = new ArrayList<Double>();
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public List<Double> getTransactions() {
        return transactions;
    }

    public void setTransactions(List<Double> transactions) {
        this.transactions = transactions;
    }

    public void añadirTransaccion(){
        // aqui ya emetes lo que te de la gana
    }
}

Banco

public class Banco {

    private String nombre;
    private List<Oficina> oficinas;

    public Banco(String nombre, List<Oficina> branches) {
        this.nombre = nombre;
        this.oficinas = oficinas;
    }

    public Banco() {
        this.oficinas = new ArrayList<Oficina>();
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public List<Oficina> getOficinas() {
        return oficinas;
    }

    public void setOficinas(List<Oficina> oficinas) {
        this.oficinas = oficinas;
    }

    // faltan los clientes una oficina tiene una lista de clientes no puede añardir ofocina sin ellos
    public void addOficina(String nombreOficina, ) {
        Oficina oficina = new Oficina();
        branches.add(newBranch);

    }

    public boolean buscarOficina(String nombre) {
        boolean existe = false;
        for (int i = 0; i < oficinas.size(); i++) {
            if (nombre.compareToIgnoreCase(oficinas.get(i).getNombre()) == 0) {
                existe = true;
            } else {
                existe = false;
            }
            return existe;
        }


// este metodo no tiene sentido el meotdo sera public ArrayList pero no public Oficina
    //ademas al usar spanglish no entiendo que queires hacer
    public Oficina queryOficinaObjectInArray(String nombre) {
        int ArrayPositionOfNameSearched = findOficina(nombre);
        if (ArrayPositionOfNameSearched >= 0) {
            return this.oficinas.get(ArrayPositionOfNameSearched);
        }
        return null;
    }
}

Oficina

public class Oficina {

        private String nombre;
        private List<Cliente> cliente;

        public Oficina(String nombre, List<Cliente> cliente) {
            this.nombre = nombre;
            this.cliente = cliente;
        }

        public Oficina(List<Cliente> cliente) {
            this.cliente = new ArrayList<Cliente>();
        }

        public String getNombre() {
            return nombre;
        }

        public void setNombre(String nombre) {
            this.nombre = nombre;
        }

        public List<Cliente> getCliente() {
            return cliente;
        }

        public void setCliente(List<Cliente> cliente) {
            this.cliente = cliente;
        }


        // aqui falla algo pero es porque no se que quiere hacer con trnasaccion
        public static void agregarCliente(Oficina nombreO, String nombre, double initialTransaction) {
            nombreO.cliente.add(new Cliente(nombre, initialTransaction));
        }

La mayoria de los metodo que no se que hacen te lo he puesto si me das una descripcio de que quieres que haga te lo corrijo. Si ajustas tus metodos que nos e a mis clases no deberia haber ningun error. Por comodida no se si te lo dicho deja el spanglish si vas usar ingles pregunta el foro ingles sera mas facil. Al menos para mi no se el divel del personal

Depdendiente de la IDE (programa para programar) que uses yo uso neatbeans y en teoria todo deben de tenerlo en la clase das clic derecho inser code y te da la opcion del constructor, si lo metes con todos lo parametros es el principal y se queda tal cual, luego creas otro con el mismo nombre y vacio entonces en ese vacio se inicializa el array, nunca en los parametros ni en el constructor con parametros

Los print es que en un metodo void tiene un print, nunca se hace print en un metodo de una clase. Solo puedes hacer print en la clase Main osea la principal del programa donde creas tu banco y tus oficinas para prpobar que todo funciona.

lO DE lIST no tiene una explicacion me enseñaron asi, se usa List primero y se iguala a new arraList el porque ni idea soy muy novato aun jaja.

No pones getter y setter en todas las clases o de todos los parametrs, haz de hacerlo.

Creo que no me dejo nadasi se me olvida algo dimelo y te lo pongo. Lo del ingles no te lo tomes a mal pero mi nivel de ingles es muy bajo y no me da para entender todo lo que quieres hacer, si no te hubiera dejado todas las clases perfectas pero vamos te puedes hacer uan idea.

unknow
  • 1,896
  • 9
  • 35
  • Gracias. Efectivamente el error era intentar agregar una transaccion a un array que no estaba inicializado por lo que cambié el campo de Cliente a "private ArrayList transactions = new ArrayList();" Si tenés tiempo me podrías explicar por qué debería sobrecargar el constructor e inicializar el ArrayList en el constructor sobrecargado? Y por qué usas List como campo pero ArrayList en el constructor sobrecargado? Y si sos tan amable por qué aconsejas en tu punto #2 nunca hacer printout en métodos que no sean de Main? – pinkfloyd90 Dec 04 '19 at 01:14
  • Te reescribo la respuesta y te lo pongo todo debajo que aqui no cabe – unknow Dec 04 '19 at 09:04
  • Otra cosa importante olvidate de pasar minusculas mayusculas, usa compareToIgnorecase asi da igual como este escrito compara las letras esten como esten – unknow Dec 04 '19 at 11:02
  • Muchísimas gracias. – pinkfloyd90 Dec 04 '19 at 14:52