Autor Tema: java.lang.NoClassDefFoundError: Pair Error: no se ha podido inicializar la clase  (Leído 3920 veces)

Dani09

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 2
    • Ver Perfil
Hola, tengo una duda. Tengo el siguiente código pero no sé cómo arreglar el problema que hace que no compile.

El código es el siguiente:

Código: [Seleccionar]
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class CCC {
    //Propiedades de la clase CCC
    private double saldoDeCuenta;
    private String nombreDelTitular;
    private long numeroDeCuenta;

    //Constructor de la clase CCC
    public CCC (String nombreDelTitular, double saldoDeCuenta)
    {
        this.saldoDeCuenta = saldoDeCuenta;
        this.nombreDelTitular = nombreDelTitular;
        Random numAleatorioCuenta = new Random();
        this.numeroDeCuenta = Math.abs(numAleatorioCuenta.nextLong());
    }

    //Setters

    //Setter para aumentar el saldo de la cuenta bancaria (hacer un ingreso)
    public void setIngreso (double ingreso)
    {
        if (ingreso <= 0)
            System.out.println("El ingreso debe ser superior a cero euros");
        else
            saldoDeCuenta = saldoDeCuenta + ingreso;
    }

    //Setter para disminuir  el saldo de la cuenta bancaria (sacar dinero)
    public void setReintegro (double reintegro)
    {
        if (reintegro <= 0)
            System.out.println("El reintegro debe ser superior a cero euros");
        else
            saldoDeCuenta = saldoDeCuenta - reintegro;
    }

    //Getters
   
    //Getter que devuelve el saldo actual de la cuenta bancaria
    public Double getSaldoCuenta ()
    {
        return saldoDeCuenta;
    }

    //Getter que obtiene todos los datos de la cuenta bancaria en un List
    //Se puede usar cualquier otra opción para devolver los datos
    public List<String> getDatosCuenta ()
    {
        List<String> datosCuenta = new ArrayList<>();
        datosCuenta.add(nombreDelTitular);
        datosCuenta.add(Long.toString(numeroDeCuenta));
        //Redondeamos a dos decimales el saldo
        DecimalFormat saldoRedondeado = new DecimalFormat("###.##");
        datosCuenta.add(saldoRedondeado.format(saldoDeCuenta));

        return datosCuenta;
    }

    //Métodos

    //Método que incrementa el saldo de una CCC de destino y lo decrementa en la CCC origen
    //Para realizar una transferencia de una CCC a otra
    public static void RealizarTransferenciaEntreCuentas (CCC ccc1, CCC ccc2, double importeTransferencia)
    {
        ccc1.saldoDeCuenta = ccc1.saldoDeCuenta - importeTransferencia;
        ccc2.saldoDeCuenta = ccc2.saldoDeCuenta + importeTransferencia;
    }
}



///////////////////////////////////////////////////////////////////////////////////////////////////


Código: [Seleccionar]
import javafx.util.Pair;
import java.util.List;
import java.util.Scanner;

public class OperacionesBanco
{
    public static void main(String[] args)
    {
        //Para la primera cuenta bancaria
        System.out.println("Cuenta bancaria 1");
        //Pedimos el Titular y el Saldo de la primera cuenta bancaria
        //Lo almacenamos en un Pair (titular, saldo)
        Pair<String, Double> datos = pedirDatosUsuario();
        //Instanciar la clase CCC y crear la clase CCC_1
        CCC CCC_1 = new CCC (datos.getKey(), datos.getValue());

        //Repetimos el mismo proceso para crear la CCC_2
        //Para la segunda cuenta bancaria
        System.out.println("Cuenta bancaria 2");
        datos = pedirDatosUsuario();
        CCC CCC_2 = new CCC (datos.getKey(), datos.getValue());

        //Hacemos una transferencia desde la CCC_1 a la CCC_2
        Double importe = pedirImporteUsuario();
        CCC.RealizarTransferenciaEntreCuentas(CCC_1, CCC_2, importe);

        //Mostramos los datos de las cuentas bancarias por consola
        System.out.println("Datos de la CCC 1");
        List<String> datosCuenta;
        datosCuenta = CCC_1.getDatosCuenta();
        System.out.println("   ->      Titular: " + datosCuenta.get(0));
        System.out.println("   -> Nº de cuenta: " + datosCuenta.get(1));
        System.out.println("   ->        Saldo: " + datosCuenta.get(2));

        System.out.println("\nDatos de la CCC 2");
        datosCuenta = CCC_2.getDatosCuenta();
        System.out.println("   ->      Titular: " + datosCuenta.get(0));
        System.out.println("   -> Nº de cuenta: " + datosCuenta.get(1));
        System.out.println("   ->        Saldo: " + datosCuenta.get(2));
    }

    //Solicita el titular de la cuenta y el saldo por consola al usuario
    //Almacena los datos en un Pair, donde la Key será el Titular y el Value el saldo
    public static Pair<String, Double> pedirDatosUsuario()
    {
        //Pedimos los datos al usuario por consola para la primera cuenta corriente
        System.out.print ("Introduzca el nombre del titular: ");
        Scanner entradaEscaner = new Scanner (System.in); //Creamos de un objeto Scanner
        String titular = entradaEscaner.nextLine (); //Invocamos un método sobre el objeto Scanner
        Double saldo = 0.0;
        System.out.print ("Introduzca el saldo inicial: ");
        //Comprueba que sólo se introduzcan números válidos (Double)
        while(!entradaEscaner.hasNextDouble())
        {
            System.out.print("No ha introducido un saldo correcto.\n" +
                    "Vuelva a intentarlo (sólo números y decimales): ");
            entradaEscaner.nextLine();
        }
        saldo = entradaEscaner.nextDouble();
        return new Pair<>(titular, saldo);
    }

    //Solicita el importe a transferir entre cuentas al usuario
    public static Double pedirImporteUsuario()
    {
        //Pedimos el importe al usuario por consola
        Scanner entradaEscaner = new Scanner (System.in); //Creamos de un objeto Scanner
        Double importe = 0.0;
        System.out.print ("\nIntroduzca el importe a transferir entre cuentas: ");
        //Comprueba que sólo se introduzcan números válidos (Double)
        while(!entradaEscaner.hasNextDouble())
        {
            System.out.print("No ha introducido un importe correcto.\n" +
                    "Vuelva a intentarlo (sólo números y decimales): ");
            entradaEscaner.nextLine();
        }
        importe = entradaEscaner.nextDouble();
        entradaEscaner.close();
        return importe;
    }
}
« Última modificación: 26 de Agosto 2022, 18:51 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re: Código
« Respuesta #1 en: 11 de Mayo 2022, 17:33 »
No dices cuál es el error que te da.  :o

Pero veo que usas la clase Pair de JavaFx. ¿El problema te viene por ahí?
JavaFx ya no está incluido en los JDK oficiales, son librerías que se tratan por separado, así que puede que no las hayas incluido correctamente en tu proyecto. De hecho conseguir incluir JavaFx puede dar tantos quebraderos de cabeza, que yo hace tiempo que lo dejé de lado. Y la verdad es que ahora mismo ni recuerdo como hacerlo.

Puedes intentar evitar el uso de Pair  escribiendo tú mismo una clase que cumpla las mismas funciones.

Otra posibilidad es usar la clase AbstractMap que tiene un clase estática para crear una "entrada simple" de un Map, y viene a ser prácticamente lo mismo que Pair:
Citar
AbstractMap.SimpleEntry<K,V>
Donde K sería la clave y V el valor asociado.
Por Google hay numerosos ejemplos sobre esto.

Si el error que tienes no viene por aquí, dinos que error de compilación te da, a ver si podemos ayudarte mejor.

Un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Dani09

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 2
    • Ver Perfil
Re: Código
« Respuesta #2 en: 11 de Mayo 2022, 19:20 »
Hola, es que tenía que hacer el siguiente programa:

Crear un proyecto que implemente una clase “CuentaBancaria” que tenga como
atributos:
➔ saldoCuenta, de tipo double.
➔ nombreTitular, de tipo String.
➔ numeroCuenta, de tipo long.

Y las siguientes funciones:
➔ Constructor que admite el nombre del titular y el saldo de la cuenta, para el número de la cuenta, se generará de manera automática con el siguiente código:
➔ Se crearán dos getters, uno permitirá obtener el saldo (getSaldoCuenta) de la cuenta
corriente y el otro obtendrá los datos generales (getDatosCuenta) de una CCC.
➔ Se creará un método (RealizarTransferencia) para permitir realizar transferencias de
dinero de una cuenta a otra (de una CuentaBancaria a otra).
Para la implementación deberá crear dos cuentas bancarias y realizar una transferencia de una a otra, luego mostrar los datos de ambas cuentas.


Y si, el error que me aparece es este:

Error: no se ha podido inicializar la clase principal OperacionesBanco
Causado por: java.lang.NoClassDefFoundError: Pair


Gracias por responder Kabuto.
« Última modificación: 26 de Agosto 2022, 18:52 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re: Código
« Respuesta #3 en: 12 de Mayo 2022, 12:25 »
Vale, pues olvídate de la clase Pair, no la necesitas.

De hecho, creo que estás haciendo una implementación más complicada de lo que estaría pidiendo el enunciado.

Yo la clase CuentaBancaria la escribiría un poco distinta.
Tu método getDatosCuenta() me parece demasiado complicado al retornar un List de Strings. Si su propósito va a ser simplemente mostrar en pantalla los datos de la cuenta, podemos solucionarlo construyendo un único String con todos esos datos.
Con String.format() se puede hacer de forma sencilla y además hará el redondeo del valor double sin tener que recurrir a otras clases.

El método realizarTransferencia(). Como este método pertenece a la clase CuentaBancaria,es decir, lo vamos a invocar desde un objeto de dicha clase, no es necesario que reciba además dos objetos CuentaBancaria como argumentos entre paréntesis.
Bastaría con recibir uno, que será la cuenta "destino" donde se transferirá el importe. La cuenta "origen", será el propio objeto desde el que vamos a invocar este método.

Por cierto, conviene comprobar si la cuenta origen tiene suficiente saldo para cubrir el importe de la transferencia, a no ser que estemos de acuerdo en que la cuenta pueda tener saldo negativo y estar en deuda con el banco  ::)

Esta sería mi clase CuentaBancaria
Código: [Seleccionar]
import java.util.Random;

public class CuentaBancaria {

private double saldoDeCuenta;
    private String nombreDelTitular;
    private long numeroDeCuenta;
   
    public CuentaBancaria(String nombreDelTitular, double saldoDeCuenta) {
        this.saldoDeCuenta = saldoDeCuenta;
        this.nombreDelTitular = nombreDelTitular;
        Random numAleatorioCuenta = new Random();
        this.numeroDeCuenta = Math.abs(numAleatorioCuenta.nextLong());
    }
   
    public double getSaldo() {
    return saldoDeCuenta;
    }
   
    public String getDatosCuenta() {
    return String.format("CCC: %d\nNombre: %s\nSaldo: %.2f", numeroDeCuenta, nombreDelTitular, saldoDeCuenta);
    }
   
    public void realizarTransferencia(CuentaBancaria otraCuenta, double importe) {
   
    if (importe > saldoDeCuenta)
    System.out.println("Esta cuenta no tiene saldo suficiente para cubrir el importe a transferir");
    else {
    saldoDeCuenta -= importe;
    otraCuenta.saldoDeCuenta += importe;
    }
    }
}

Y ahora, una clase para comprobar que funciona la transferencia de dinero, nos puede servir una tan simple y sencilla como esta:
Código: [Seleccionar]
public class Test {

public static void main(String[] args) {

//Creamos cuentas
CuentaBancaria CCC1 = new CuentaBancaria("Sandra Ramirez", 45000.64);
CuentaBancaria CCC2 = new CuentaBancaria("Antonio Losada", 20000.93);

//Mostramos
System.out.println("Cuentas bancarias:");
System.out.println("\n" + CCC1.getDatosCuenta());
System.out.println("\n" + CCC2.getDatosCuenta());

//Transferencia
System.out.println("\nTransfiriendo un importe de: " + 5000.32);
CCC1.realizarTransferencia(CCC2, 5000.32);

//Mostramos de nuevo
System.out.println("\nCuentas despues de haber hecho transferencia:");
System.out.println("\n" + CCC1.getDatosCuenta());
System.out.println("\n" + CCC2.getDatosCuenta());

}

}

Fíjate en lo que decía antes, para hacer la transferencia, invocamos el método desde la cuenta "origen" y nos basta con pasarle como argumento la cuenta "destino" (y el importe claro)
Código: [Seleccionar]
CCC1.realizarTransferencia(CCC2, 5000.32);Con solo eso, si lo ejecutamos, vemos que todo funciona y básicamente se cumple lo que nos está pidiendo el enunciado:
Citar
Cuentas bancarias:

CCC: 7850162117938004654
Nombre: Sandra Ramirez
Saldo: 45000,64

CCC: 3902791561329441160
Nombre: Antonio Losada
Saldo: 20000,93

Transfiriendo un importe de: 5000.32

Cuentas despues de haber hecho transferencia:

CCC: 7850162117938004654
Nombre: Sandra Ramirez
Saldo: 40000,32

CCC: 3902791561329441160
Nombre: Antonio Losada
Saldo: 25001,25

Bien, pues ya lo tenemos.
Sin embargo, ya que parece que no te gustan las cosas tan simples  ;) podemos hacer una versión algo más avanzada.
Ya que intentabas crear "pares" con claves y valores...., podemos hacer un programa con menú para crear tantas cuenta bancarias como queramos.
Estas cuentas las podemos "mapear" utilizando el código de cuenta bancaria como clave para asociarlas.
Y con otra opción de menú, seleccionar una cuenta origen, otra destino y hacer transferencia.

Para ello, primero quiero modificar levemente la clase CuentaBancaria.
Le vamos a añadir un get para obtener el número de cuenta que se genera aleatoriamente, ya que lo vamos a necesitar para usarlo como clave al "mapear" las cuentas.

Y el método para realizar transferencias, lo vamos a hacer boolean, para que retorne false si no puedo hacerse la transferencia (por falta de fondos) o true si todo salió bien.

Marco en negrita los cambios:
Citar
public class CuentaBancaria {

   private double saldoDeCuenta;
    private String nombreDelTitular;
    private long numeroDeCuenta;
   
    public CuentaBancaria(String nombreDelTitular, double saldoDeCuenta) {
        this.saldoDeCuenta = saldoDeCuenta;
        this.nombreDelTitular = nombreDelTitular;
        Random numAleatorioCuenta = new Random();
        this.numeroDeCuenta = Math.abs(numAleatorioCuenta.nextLong());
    }
   
    public long getNumeroCuenta() {
       return numeroDeCuenta;
    }

   
    public double getSaldo() {
       return saldoDeCuenta;
    }
   
    public String getDatosCuenta() {
       return String.format("CCC: %d\nNombre: %s\nSaldo: %.2f", numeroDeCuenta, nombreDelTitular, saldoDeCuenta);
    }
   
    public boolean realizarTransferencia(CuentaBancaria otraCuenta, double importe) {
       
       if (importe > saldoDeCuenta) {
          System.out.println("Esta cuenta no tiene saldo suficiente para cubrir el importe a transferir");
          return false;
       }
       else {
          saldoDeCuenta -= importe;
          otraCuenta.saldoDeCuenta += importe;
          return true;
       }
    }
}

Y ahora creamos un nuevo programa principal, donde usaremos un HashMap para mapear las cuentas mediante su código de cuenta como clave.
Y con un menú, el usuario podrá escoger opciones.
Código: [Seleccionar]
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Scanner;

public class Test {

private static HashMap<Long, CuentaBancaria> cuentas = new HashMap<Long, CuentaBancaria>();
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

int opcion = 0;
while (opcion != 4) {
System.out.println("\n\t\tBANCO ORACLE");
System.out.println("\t\t----- ------\n");
System.out.println("[1] -- Crear una Cuenta Bancaria");
System.out.println("[2] -- Listar todas las Cuentas");
System.out.println("[3] -- Hacer una Transferencia");
System.out.println("[4] -- SALIR");
System.out.print("Elija opcion: ");
opcion = Integer.parseInt(teclado.nextLine());

switch(opcion) {
case 1:
crearCuenta();
break;
case 2:
listarCuentas();
break;
case 3:
hacerTransferencia();
break;
case 4:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opcion equivocada");
}
}

}

private static void crearCuenta() {
System.out.println("\n\tNUEVA CUENTA");
System.out.print("Nombre Titular: ");
String nombre = teclado.nextLine();
System.out.print("Saldo inicial: ");
double saldo = Double.parseDouble(teclado.nextLine());
CuentaBancaria nuevaCCC = new CuentaBancaria(nombre, saldo);
cuentas.put(nuevaCCC.getNumeroCuenta(), nuevaCCC);
}

private static void listarCuentas() {
System.out.println("\nLISTADO DE CUENTAS");
if (cuentas.isEmpty())
System.out.println("No hay cuentas bancarias registradas");
else {
for(Entry<Long, CuentaBancaria> ccc: cuentas.entrySet())
System.out.println("\n" + ccc.getValue().getDatosCuenta() + "\n");
}
}

private static void hacerTransferencia() {
System.out.println("\n\tHACER TRANSFERENCIA");
System.out.print("Num. Cuenta ORIGEN: ");
long cccOrigen = Long.parseLong(teclado.nextLine());
System.out.print("Num. Cuenta DESTINO: ");
long cccDestino = Long.parseLong(teclado.nextLine());
System.out.print("Importe: ");
double importe = Double.parseDouble(teclado.nextLine());

//Buscamos las cuentas
CuentaBancaria origen = cuentas.get(cccOrigen);
CuentaBancaria destino = cuentas.get(cccDestino);

//Comprobamos que existen, y si existen, intentamos transferencia
if (origen == null)
System.out.println("No existe cuenta ORIGEN con nº: " + cccOrigen);
else if (destino == null)
System.out.println("No existe cuenta DESTINO con nº: " + cccDestino);
else if (origen.realizarTransferencia(destino, importe))
System.out.println("Transferencia realizada con exito");

}
}

Si lo ejecutamos, vemos que se pueden crear cuentas, seleccionarlas mediante su código y hacer transferencias entre ellas:
Citar
      BANCO ORACLE
      ----- ------

[1] -- Crear una Cuenta Bancaria
[2] -- Listar todas las Cuentas
[3] -- Hacer una Transferencia
[4] -- SALIR
Elija opcion: 1

   NUEVA CUENTA
Nombre Titular: Sara Pelaez
Saldo inicial: 4500.45

      BANCO ORACLE
      ----- ------

[1] -- Crear una Cuenta Bancaria
[2] -- Listar todas las Cuentas
[3] -- Hacer una Transferencia
[4] -- SALIR
Elija opcion: 1

   NUEVA CUENTA
Nombre Titular: Pedro Ramiro
Saldo inicial: 1500.75

      BANCO ORACLE
      ----- ------

[1] -- Crear una Cuenta Bancaria
[2] -- Listar todas las Cuentas
[3] -- Hacer una Transferencia
[4] -- SALIR
Elija opcion: 2

LISTADO DE CUENTAS

CCC: 1790563580212299009
Nombre: Pedro Ramiro
Saldo: 1500,75


CCC: 7698480902857524209
Nombre: Sara Pelaez
Saldo: 4500,45


      BANCO ORACLE
      ----- ------

[1] -- Crear una Cuenta Bancaria
[2] -- Listar todas las Cuentas
[3] -- Hacer una Transferencia
[4] -- SALIR
Elija opcion: 3

   HACER TRANSFERENCIA
Num. Cuenta ORIGEN: 7698480902857524209
Num. Cuenta DESTINO: 1790563580212299009
Importe: 500.45
Transferencia realizada con exito

      BANCO ORACLE
      ----- ------

[1] -- Crear una Cuenta Bancaria
[2] -- Listar todas las Cuentas
[3] -- Hacer una Transferencia
[4] -- SALIR
Elija opcion: 2

LISTADO DE CUENTAS

CCC: 1790563580212299009
Nombre: Pedro Ramiro
Saldo: 2001,20


CCC: 7698480902857524209
Nombre: Sara Pelaez
Saldo: 4000,00


      BANCO ORACLE
      ----- ------

[1] -- Crear una Cuenta Bancaria
[2] -- Listar todas las Cuentas
[3] -- Hacer una Transferencia
[4] -- SALIR
Elija opcion: 4

      FIN DE PROGRAMA



Y ahora sí, ya tenemos un programa un poco más avanzado.
Pregunta lo que no entiendas o pienses que pueda ser incorrecto.

Un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".