Autor Tema: ¿Por qué los atributos Java deben ser private#? Añadir Eliminar items ArrayList  (Leído 4837 veces)

sapph24

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 4
    • Ver Perfil
Buenas, me han dejado un programa para añadir, citar, etc elementos en un arraylist, he creado mis constructores y todo lo demas, pero no consigo agregar a la lista... Y para este punto ya he perdido la rienda de todo lo que estoy haciendo y estoy muy confundida, espero puedan ayudarme gracias.

/////CODIGO/////

*Clase Sistema.

Código: [Seleccionar]
public lass Sistema {
private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
private static PrintWriter stdOut = new PrintWriter(System.out, true);

CatalogoClientes catalogoClientes;

public Sistema() { }

public static void main(String [] args){
Sistema sistem= new Sistema();
sistem.option();   }

private void menu() {
System.out.println("Seleccione la acción: "+"\n"
+"[1]Añadir Cliente" +"\n"
+"[2] Añadir Provedor"+"\n"
+"[3] Mostrar Clientes"+"\n"
+"[4] Mostrar Provedores"+"\n"
+"[5] Añadir Producto");
System.out.println("choice>");             }

private int option() {
while (true) {
try {
menu();
int op = Integer.parseInt(stdIn.readLine() );
if(op>1 && op<=5) {
return op;
} else {throw new NumberFormatException();}
}
catch(IOException ioe) {
System.out.println("Error al leer los datos");
}
catch(NumberFormatException nfe) {
System.out.println("Se esperaban valores entre 1 y 5");
}
}
}

public void Mainprincipal(){
int op = 0;
do {op = option();
switch (op) {
case 1 :
AddCliente();
break;
case 2:
                            *Agregar luego
}
}while(op != 0);
}

ArrayList<Cliente>clientes= new ArrayList<Cliente>();

public void AddCliente() {
stdOut.println("Ingrese los datos: [Nombre, RFC, Direccion,Telefono, Razon Social,ID Cliente]");
stdOut.flush();

Cliente tmpCliente = new Cliente(
tmpCliente.setNombre(Nombre),
tmpCliente.setRFC(stdIn.readLine()),
tmpCliente.setDireccion(stdIn.readLine()),
tmpCliente.setTelefono(stdIn.readLine()),
tmpCliente.setRazonSocial(stdIn.readLine()),
tmpCliente.setIdCliente(stdIn.readLine())
);
clientes.add(tmpCliente);
*Todo esto es lo que no tengo idea de como hacer....
}

**********************************************************************


*Clase CatalogoClientes

Código: [Seleccionar]
public class CatalogoClientes implements Iterator<Persona>{

ArrayList<Persona> personas= new ArrayList<Persona>();

public CatalogoClientes() {
personas = new ArrayList<Persona>();
}

public void AddPersona(Persona persona) {
personas.add(persona);
}

public Persona getPersona (int indice) {
return personas.get(indice);
}

public Persona getPersonaByID (String RFC) {
for (Persona per: personas) {
if (per.getRFC()==RFC) {
return per; }
}
return null;}

public void ErasePersona (Persona per) {
personas.remove(per); }

public String ImprimirAll () {
for(int i=0;i<personas.size();i++){
         System.out.println(personas.get(i));   }
return null;
}

public Iterator<Persona> IteradorPersona () {
return personas.iterator(); }

@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}

@Override
public Persona next() {
// TODO Auto-generated method stub
return null;
}
}

**********************************************************************


*Clase Persona

Código: [Seleccionar]
public class Persona {
public String Nombre, RFC, Direccion,Telefono,RazonSocial;

ArrayList<Persona> personas= new ArrayList<Persona>();

public Persona(String Nombre, String RFC,String Direccion,String Telefono,String RazonSocial){    
    this.Nombre=Nombre;
    this.RFC=RFC;
    this.Direccion=Direccion;
    this.Telefono= Telefono;
    this.RazonSocial= RazonSocial;}

public String getNombre(){
    return Nombre;}

public void setNombre(String Nombre) {
this.Nombre=Nombre;}
//
public String getRFC(){
    return RFC;}

public void setRFC(String RFC) {
this.RFC=RFC;}
//
public String getDireccion(){
    return Direccion;}

public void setDireccion(String Direccion) {
this.Direccion=Direccion;}
//
public String getTelefono(){
    return Telefono;}

public void setTelefono(String Telefono) {
this.Telefono=Telefono;}
//

public String getRazonSocial(){
    return RazonSocial;}

public void setRazonSocial(String RazonSocial) {
this.RazonSocial= RazonSocial;}

public String toString(){
    return "Nombre: "+getNombre()+"RFC: "+getRFC()+ "Direccion:"+getDireccion()+"Telefono: "+getTelefono()+"Razon Social: "+getRazonSocial();}

}

**********************************************************************

*Clase Cliente


Código: [Seleccionar]
public class Cliente extends Persona{
    String idCliente;
 
    public Cliente (String Nombre, String RFC,String Direccion,String Telefono,String RazonSocial, String idCliente) {
        super(Nombre, RFC, Direccion, Telefono, RazonSocial);
        this.idCliente = idCliente;        }

    public String getIdCliente(){
        return idCliente;    }
   
    public void setIdCliente(String idCliente) {
this.idCliente=idCliente; }
   
    public String toString() {
        return super.toString() + "id cliente " + idCliente;   }
   
    public boolean equals (Object obj) {   
    if (obj instanceof Cliente) {
Cliente tmpCliente= (Cliente)obj;
if (super.equals(tmpCliente) && Nombre.equals(tmpCliente.getNombre())&&RFC.equals(tmpCliente.getRFC())&&Direccion.equals(tmpCliente.getDireccion())&&Telefono.equals(tmpCliente.getTelefono())&&RazonSocial.equals(tmpCliente.getRazonSocial())&&idCliente.equals(tmpCliente.getIdCliente())); {
return true;
} }
return true;
}}

**********************************************************************


*Clase Provedor

Código: [Seleccionar]
public class Provedor extends Persona{
String idProvedor;
String fax;
String email;

public Provedor(String idProvedor, String fax, String email, String Nombre,
String Direccion, String RFC, String Telefono, String RazonSocial){
    super(Nombre,Direccion,RFC,Telefono,RazonSocial);
    this.idProvedor = idProvedor;
    this.fax = fax;
    this.email = email; }

public String getIdProvedor(){
    return idProvedor;}

public void setIdProvedor(String idProvedor) {
this.idProvedor=idProvedor; }
//

public String getfax(){
    return fax; }

public void setFax(String fax) {
this.fax=fax;
}
//

public String getEmail(){
    return email;  }

public void setEmail(String email) {
this.email=email;}
}

**********************************************************************


Cabe resaltar que también tendré que tener una clase con productos (añadir,quitar,etc) , pero esa pensaba implementarla cuando pudiera lograr esto... de igual manera, se añadiría de la misma manera desde mi clase Sistema?... O tendria que implementar algo?

Muchas gracias.
« Última modificación: 07 de Junio 2020, 14:15 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 985
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #1 en: 11 de Junio 2019, 14:35 »
Hola. Te voy a comentar varias cosas y hacer varias correciones.

Lo haré en varios mensajes para no hacer un único post gigantesco.

En el último incluiré todo el código tal y como lo he cambiado yo, para que lo uses, lo mires, preguntes dudas y lo que sea.

Intentaré hacerlo lo más parecido a como lo estás desarrollando tú.

Vamos por partes.

Los atributos de las clases deberían ser private, no public.

Por convención, los atributos se declaran privados de manera que solo se pueda interactuar con ellos mediante los getters y setters.

Si se declaran públicos, los getters y los setters son totalmente innecesarios, ya que los atributos son visibles a cualquier otra clase que vaya a interactuar con nuestro objeto. Pero esto la mayoría de las veces no nos interesa que ocurra.

Los getters y setters nos permiten, si queremos, controlar de que manera se acceden a los atributos y podemos poner condiciones para por ejemplo controlar la calidad de los datos.

Te pongo un ejemplo.
Supon que la clase Persona tiene un atributo llamado edad.
Si este atributo lo pongo como public, entonces se podrá acceder directamente al atributo para leer/escribir su contenido. Y esto implica que podrían ocurrir cosas como esta:

Código: [Seleccionar]
Persona persona1 = new Persona();
persona1.edad = -984;

Ahora tengo una persona con -984 años, lo cual es absurdo. La "calidad" de ese atributo es pésima, nula... cualquier cálculo que quiera hacer ahora con este atributo me dará resultados igualmente absurdos.

Sin embargo, si lo declaro como private, ya no se puede acceder directamente al atributo como hemos visto en el ejemplo anterior. Ahora el compilador va a obligar a que se usen los getters y setters, los cuáles sí me van a permitir poner controles a la calidad de los datos.

Si alguien intenta hacer esto:
Código: [Seleccionar]
Persona persona1 = new Persona();
persona1.setEdad(-984);

No le va a funcionar, porque yo en mi setter habré puesto aunque sea un control mínimo de la calidad del dato:
Código: [Seleccionar]
public boolean setEdad(int edad) {
    if (edad < 0) {
        System.out.println("ERROR: La edad no puede ser un valor negativo");
        return false; //Informo de que no ha sido aceptado este valor
    }
    else {
        this.edad = edad;
        return true; //Informo de que SI hemos aceptado este valor
    }
}

Como puedes ver, con los setter puedo controlar la forma de aceptar datos y con los getter podría controlar cómo los devuelvo.
Para obligar a que se usen los getters/setters, me conviene declarar los atributos como private para que sea imposible acceder a ellos directamente.


Otra cosa que quería comentar.
Tu clase Persona, ha de definir como vamos a modelar la representación de una persona.
Es decir, vamos a definir que atributos tiene una persona del "mundo real", pero solo los que nos interesen para la funcionalidad de nuestro programa.

Por eso ponemos los atributos: Nombre, RFC, Direccion,Telefono,RazonSocial;
Porque una persona tiene un nombre, tiene una dirección, un teléfono...

Pero ojo, una persona del "mundo real", no tiene a "muchas otras personas" en su interior...
Lo digo porque has puesto un ArrayList de Personas, como atributo de Persona. Y esto no parece que tenga sentido, así que este atributo no es necesario.
Citar
public class Persona {
   private String Nombre, RFC, Direccion,Telefono,RazonSocial;

ArrayList<Persona> personas= new ArrayList<Persona>();

Y ojo, en programación todo es posible. Si podría ocurrir alguna situación en que necesitemos que una clase Persona, contenga un arrayList de Personas, si por ejemplo quisieramos modelar los hijos que tiene una persona, así que ese ArrayList contendría a sus descendientes.
Pero no es este el caso que nos trae.


Hablemos ahora de tu clase Cliente.
Tiene un único atributo, llamado idCLiente, que como dije antes, ha de ser declarado como private.

Tu método equals() es erróneo en dos sentidos:
Uno, en sintaxis, pues intentas acceder a atributos como Nombre, RFC, Dirección directamente.

Código: [Seleccionar]
public boolean equals (Object obj) {       
if (obj instanceof Cliente) {
Cliente tmpCliente= (Cliente)obj;         
if (super.equals(tmpCliente)   && Nombre.equals(tmpCliente.getNombre())&&RFC.equals(tmpCliente.getRFC())&&Direccion.equals(tmpCliente.getDireccion())&&Telefono.equals(tmpCliente.getTelefono())&&RazonSocial.equals(tmpCliente.getRazonSocial())&&idCliente.equals(tmpCliente.getIdCliente())); {
return true;
}   }
return true;
}
Eso no puedes hacerlo así, de hecho el compilador muestra un warning avisando de que no tiene ni idea de que variables son esas.

Si quieres acceder a esos atributos, has de pedirselos al super mediante getters. Por ejemplo:
Código: [Seleccionar]
super.getNombre().equals(tmpCliente.getNombre()

Dos, a parte de los errores de sintaxis, hay errores de lógica.
Varios, como que por ejemplo no se retorna false en ningún momento, pero el importante que hay que destacar es la elección de atributos para decidir si dos objetos Cliente son equivalentes/iguales.

El nombre, o la dirección, etc.... no deberían ser determinantes para decidir si dos clientes son equivalentes/iguales o no.
El atributo decisivo debería ser solo el id de Cliente. (salvo que el enunciado de este ejercicio indique lo contrario)
EL id, es el identificador que debemos asegurarnos que sea único e irrepetible, y por lo tanto ese debería ser el único atributo decisivo para decidir si dos objetos Cliente son equivalentes.
Del siguiente modo, quedaría más correcto:

Código: [Seleccionar]
public boolean equals (Object obj) {       
if (obj instanceof Cliente) {
//Es un objeto Cliente, hacemos casting para poder comparar atributo idCLiente
Cliente otroCLiente = (Cliente)obj;

if (this.idCliente.equals(otroCLiente.getIdCliente()))
return true; //Los ID son iguales, así que ambos objetos son el MISMO Cliente
else
return false; //Los ID son distintos, así que los objetos son CLientes distintos
}
else
return false; //No es un objeto Cliente, así que son cosas distintas
}

Sobre la clase Provedor, solo recordar que los atributos deberían ser private.
A esta clase no le has puesto método equals(), si fuera necesario ponérselo, de nuevo lo más lógico sería que el atributo decisivo fuera solo y únicamente el id de proveedor.

Sobre la clase CatalogoCliente, continuo en otro mensaje para que este no sea demasiado extenso.
« Última modificación: 07 de Junio 2020, 14:14 por Ogramar »
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

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 985
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #2 en: 11 de Junio 2019, 14:40 »
Sobre la clase CatalogoCliente aquí me surge una pregunta.
¿Es necesario que implemente la interfaz Iterator?
Yo es que nunca he necesitado usar iteradores, aunque bueno, solo soy un aprendiz más, apenas un aficionado a la programación. Pero bueno, como tampoco sé todavía cuáles son las funcionalidades completas que ha de tener tu programa, lo dejamos implementado.

Lo que si creo que está mal, es que dentro de esta clase está trabajando con la clase Persona.
Si esto va a ser un Catálogo de Clientes, lo normal, es que trabajemos con la clase Cliente, no con la clase Persona.
Así que hay que modificar todos los métodos, parámetros y argumentos para que hagan referencia a la clase Cliente en lugar de a Persona.

Además hay que aumentar la funcionalidad de algunos métodos.

Por ejemplo, el metodo para añadir un Cliente al ArrayList.
- Los Clientes tienen un idCliente que los identifica y los hace únicos.
- Si los hace únicos, significa que en nuestro ArrayList no podemos permitir tener dos Clientes con el mismo id, ya que en realidad serían el mismo.
- Para impedir que se nos repitan los Clientes en el ArrayList, nos ayudará el método equals() que le habíamos escrito a la clase Cliente, que es precisamente para que nos ayude en estos casos.

El método lo podemos reescribir así:

Código: [Seleccionar]
public boolean addCliente(Cliente cliente) {
if (clientes.contains(cliente)) //Ya existe un cliente con el mismo ID
return false; //Lo rechazamos
else {
clientes.add(cliente); //Aceptamos el Cliente
return true;
}
}

Aquí el ArrayList se llama clientes.
Y antes de añadir el nuevo cliente, le preguntamos al ArrayList si ya contiene ( contains() ) un cliente "igual" al que pretendemos añadir.
Nosotros no lo vemos, pero contains() lo que hace es recorrer todos los objetos Cliente dentro del ArrayList y va preguntando si alguno es igual ( equals() ) al CLiente que le hemos pasado por argumentos.

Si encuentra alguno igual, es decir, uno que tenga el mismo ID (ya que a la clase CLiente le hemos dicho que el atributo IdCliente es quien decide si son iguales o no) devolverá TRUE y en este caso, no debemos aceptar este Cliente, porque ya lo tenemos en el listado y si lo aceptamos lo tendremos repetido.

Así que nuestro método para añadir Clientes, ya no los acepta directamente sin más. Comprueba si está repetido o no y además informa con TRUE/FALSE si el Cliente ha sido aceptado/rechazado.

Además hay un método para buscar una Persona por su ID. Como ya hemos dicho, lo correcto sería que buscase Clientes por ID, no personas.
Lo modificamos y además te recuerdo que para comparar datos de tipo String, hay que usar el método equals()
Si usas el comparador básico de igualdad, el doble igual,  == no te dará resultados válidos.
Este comparador solo sirve para tipos primitivos como int, char, double, float, byte...
Para comparar objetos (los String son objetos, no son primitivos) hay que usar equals()

Código: [Seleccionar]
public Cliente getClienteByID(String idCliente) {
for (Cliente cli: clientes) {
if (cli.getIdCliente().equals(idCliente))
return cli;
}
return null;
}

Ahora viene un método para eliminar Clientes del ArrayList pasando como argumento un objeto Cliente.
EL método que has puesto está bien, pero quizás sería interesante que el método informase de si ha eliminado o no el Cliente.
¿Y si nos han pasado un Cliente para eliminar, que en realidad no existe en el ArrayList?
Quizás sería conveniente informar al usuario de este hecho, ya que quizás así se de cuenta de que nos ha pasado un Cliente posiblemente equivocado.
Si no le informamos, el usuario pensará que nos ha pasado un Cliente correcto y que ha sido eliminado, cuando en realidad no ha sido así.

Mejor informarle de qué resultado ha dado su intento de borrado, y además es muy fácil de hacer, ya que el metodo remove() del ArrayList ya devuelve true/false según si ha borrado o no.
Así que nos basta con retornar, lo que esté retornando este método:

Código: [Seleccionar]
public boolean eraseCliente (Cliente cliente) {
return clientes.remove(cliente); //Si el cliente no existiese, retornara false
}

Luego tienes un método llamado imprimirAll() para mostrar todos los Clientes del listado en pantalla. Has puesto que devuelve un String, pero no es necesario que retorne nada, basta con que escriba en pantalla y punto. Nada más.
Así que lo declaramos como void y quitamos la sentencia return

Código: [Seleccionar]
public void ImprimirAll () {   
for(int i=0;i<clientes.size();i++){
System.out.println(clientes.get(i));   }
}

Los siguientes métodos están relacionados con el Iterator, que no se si los necesitaremos o no realmente. De momento los dejamos tal cual.

Ahora viene el programa principal, de este también hablaremos en otro post separado.
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

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 985
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #3 en: 11 de Junio 2019, 14:46 »
OK, nos ponemos con la clase Sistema.

Para leer datos por teclado y mostrar datos en pantalla has declarado las clases BufferedReader y PrintWriter.

No se si es necesario que uses estos objetos porque te lo pide el enunciado o porque es como habitualmente te han enseñado tus profesores o no se...

Yo usaría un simple Scanner para leer datos por teclado y el comodísimo System.out.println() para mostrar en pantalla (de hecho, es lo que usas en el metodo menu() ).
Voy a seguir usando el BufferedReader para no alejarme mucho de lo que tu has hecho, pero el PrintWriter no, porque aunque desactive el "autoflush" me muestra todos los textos en pantalla sin haber llegado aún a esas partes del código, y bueno, yo no me aclaro con esta clase xD

Aunque el BufferedReader tampoco me hace gracia porque siempre va a exigir usar un try catch para leer datos, aunque sean por teclado, cosa que no pasa con el Scanner.


Luego ya sí que veo algo de confusión en la estructura del código...
- Hay un constructor vacío

- hay declarado el objeto CatalogoCliente... pero luego más adelante, mezclado entre los
métodos, hay igualmente declarado un ArrayList de Clientes..

- Hay un bucle while(true).
Esto de usar condicion true para que un bucle se repita, aunque es válido, es una mala práctica de programación.
Y sorprendemente lo enseñan muchísimos docentes. Pero no es buena práctica ya que no se aplica un flujo realmente lógico a la estructura del programa.
Y además, no es necesario hacerlo así. Nunca lo es.

- Para pedir que se elija opción, se usa un poco arbitrariamente las excepciones.
Si el usuario introduce un número de opción no válido, se lanza un NumberFormatException. Este excepción debería representar errores en el formato de un valor numérico, no que se haya escogido una opcion inexistente.
Vale que luego en la práctica nos puede servir, pero tampoco es buena práctica usar las excepciones que no representan lo que realmente ha ocurrido.
En todo caso, deberíamos crear nuestra propia excepción.
Pero vamos, en realidad para controlar esto de las opciones del menú, no se necesitan excepciones.

- Los métodos y algunos objetos NO están declarados como static, con lo cual se hace necesario instanciar un objeto de la clase Sistema para poder acceder a ellos.
Y, aunque esto es opcional, creo que lo más cómodo sería declararlo todo como static para poder acceder a todo desde el main sin tener que instanciar ningún objeto Sistema.

Voy a cambiarlo todo más o menos a como yo lo haría, y tu ya decides si te sirve o no.

- En el método para añadir un nuevo Cliente.
El usuario ha de introducir cada uno de los datos para los atributos.
Lo podemos hacer de dos formas:
1 Almacenar cada uno de esos datos en sus variables separadas y luego pasarselas al contructor del nuevo cliente que vamos a crear.
2 Instanciar el nuevo cliente y hacer la lectura de datos directamente en el contructor.

Para ahorrar tiempo lo he hecho de la segunda forma, aunque he decir que no me gusta mucho. Normalmente prefiero leer datos uno a uno, cada uno en su variable, y luego se las paso todas al constructor del objeto.


Bueno, este mensaje incorpora al final el código de todas las clases.

Pruébalo. El programa ya funciona y permite añadir nuevos clientes y también listarlos en pantalla.

Mira bién el código, pregunta lo que no entiendas y si ya lo tienes claro, intenta completar lo que te falta.

Si hubiera que cambiar algo por alguna exigencia del enunciado o de tus profesores, comentalo e intentamos adaptarlo.

Un saludo.


Clase CatalogoClientes


Código: [Seleccionar]
package catalogoClientes;

import java.util.ArrayList;
import java.util.Iterator;

public class CatalogoClientes implements Iterator<Cliente>{

private ArrayList<Cliente> clientes;

public CatalogoClientes() {
clientes = new ArrayList<Cliente>();
}

/*
* Metodo para añadir Cliente. al ArrayList
* Devuelve TRUE si el cliente es aceptado.
* Devuelve FALSE si es rechazado, porque ya existe
* un Cliente con el mismo ID.
*/
public boolean addCliente(Cliente cliente) {
if (clientes.contains(cliente)) //Ya existe un cliente con el mismo ID
return false; //Lo rechazamos
else {
clientes.add(cliente); //Aceptamos el Cliente
return true;
}
}

public Cliente getCliente (int indice) {
return clientes.get(indice);   
}

public Cliente getClienteByID(String idCliente) {
for (Cliente cli: clientes) {
if (cli.getIdCliente().equals(idCliente))
return cli;
}
return null;
}

public boolean eraseCliente (Cliente cliente) {
return clientes.remove(cliente); //Si el cliente no existiese, retornara false
}

public void ImprimirAll () {
System.out.println("\n\t\tListado Clientes");
if (clientes.isEmpty())
System.out.println("No hay Clientes registrados para mostrar.");
else
for(int i=0;i<clientes.size();i++){
System.out.println(clientes.get(i));   }
}

public Iterator<Cliente> IteradorCliente () {
return clientes.iterator();   }

@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}

@Override
public Cliente next() {
// TODO Auto-generated method stub
return null;
}
}


Clase Cliente


Código: [Seleccionar]
package catalogoClientes;

public class Cliente extends Persona{
private String idCliente;

public Cliente (String Nombre, String RFC,String Direccion,String Telefono,String RazonSocial, String idCliente) {
super(Nombre, RFC, Direccion, Telefono, RazonSocial);
this.idCliente = idCliente;        }

public String getIdCliente(){
return idCliente;    }

public void setIdCliente(String idCliente) {
this.idCliente=idCliente;   }

public String toString() {
return super.toString() + " ID cliente " + idCliente;   }

public boolean equals (Object obj) {       
if (obj instanceof Cliente) {
//Es un objeto Cliente, hacemos casting para poder comparar atributo idCLiente
Cliente otroCLiente = (Cliente)obj;

if (this.idCliente.equals(otroCLiente.getIdCliente()))
return true; //Los ID son iguales, así que ambos objetos son el MISMO Cliente
else
return false; //Los ID son distintos, así que los objetos son CLientes distintos
}
else
return false; //No es un objeto Cliente, así que son cosas distintas
}
}


Clase Persona

Código: [Seleccionar]
package catalogoClientes;

public class Persona {

private String Nombre, RFC, Direccion,Telefono,RazonSocial;

//ArrayList<Persona> personas= new ArrayList<Persona>();

public Persona(String Nombre, String RFC,String Direccion,String Telefono,String RazonSocial){       
this.Nombre=Nombre;
this.RFC=RFC;
this.Direccion=Direccion;
this.Telefono= Telefono;
this.RazonSocial= RazonSocial;}

public String getNombre(){
return Nombre;}

public void setNombre(String Nombre) {
this.Nombre=Nombre;}
//
public String getRFC(){
return RFC;}

public void setRFC(String RFC) {
this.RFC=RFC;}
//
public String getDireccion(){
return Direccion;}

public void setDireccion(String Direccion) {
this.Direccion=Direccion;}
//
public String getTelefono(){
return Telefono;}

public void setTelefono(String Telefono) {
this.Telefono=Telefono;}
//

public String getRazonSocial(){
return RazonSocial;}

public void setRazonSocial(String RazonSocial) {
this.RazonSocial= RazonSocial;}

public String toString(){
return "Nombre: "+getNombre()+" RFC: "+getRFC()+ " Direccion:"+getDireccion()+
" Telefono: "+getTelefono()+" Razon Social: "+getRazonSocial();
}
}


Clase Proveedor

Código: [Seleccionar]
package catalogoClientes;

public class Provedor extends Persona{
private String idProvedor;
private String fax;
private String email;

public Provedor(String idProvedor, String fax, String email, String Nombre,
String Direccion, String RFC, String Telefono, String RazonSocial){
super(Nombre,Direccion,RFC,Telefono,RazonSocial);
this.idProvedor = idProvedor;
this.fax = fax;
this.email = email; }

public String getIdProvedor(){
return idProvedor;}

public void setIdProvedor(String idProvedor) {
this.idProvedor=idProvedor; }
//

public String getfax(){
return fax; }

public void setFax(String fax) {
this.fax=fax;
}
//

public String getEmail(){
return email;  }

public void setEmail(String email) {
this.email=email;}
}


Clase Sistema

Código: [Seleccionar]
package catalogoClientes;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sistema {
private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
//private static PrintWriter stdOut = new PrintWriter(System.out, true);   
private static CatalogoClientes catalogoClientes = new CatalogoClientes();


public static void main(String[] args){
int opcion = 0;
do {
opcion = pedirOpcion();
switch (opcion) {
case 1:
addCliente();
break;
case 2:
//añadir proveedor
break;
case 3:
catalogoClientes.ImprimirAll();
break;
case 4:
//mostrar proveedores
break;
case 5:
//añadir producto
break;
case 6:
System.out.println("\n\t\tFIN DE PROGRAMA");
}
}while (opcion != 6);
}

private static void menu() {
System.out.println("\nSeleccione la acción: "+"\n"
+"[1] Añadir Cliente\n"
+"[2] Añadir Provedor\n"
+"[3] Mostrar Clientes\n"
+"[4] Mostrar Provedores\n"
+"[5] Añadir Producto\n"
+"[6] CERRAR PROGRAMA");
System.out.print("choice> ");
}


private static int pedirOpcion() {
menu();
try {
int op = Integer.parseInt(stdIn.readLine());
if (op >= 1 || op <= 6)
return op; //La opcion es válida, podemos retornarla como valida.
else {
System.out.println("Elija solo entre [1-6]");
return -1; //Opcion no válida, devolvemos cualquier int distinto de 1-6...
           //...para que el SWITCH lo ignore
}
} catch (NumberFormatException e) {
System.out.println("El dato introducido no es un número");
return -1;
} catch (IOException e) {
System.out.println("Error al leer los datos");
return -1;
}
}

private static void addCliente() {
System.out.println("Ingrese los datos: [Nombre, RFC, Direccion,Telefono, Razon Social,ID Cliente]");
try {
Cliente nuevoCliente = new Cliente(stdIn.readLine(), stdIn.readLine(), stdIn.readLine(),
stdIn.readLine(), stdIn.readLine(), stdIn.readLine());

//Intentamos añadir el nuevo cliente creado. Si estuviera repetido (mismo ID), será rechazado
if (catalogoClientes.addCliente(nuevoCliente))
System.out.println("\nNuevo Cliente registrado...");
else
System.out.println("\nNuevo Cliente rechazado.\nYa existe un Cliente con el ID " + nuevoCliente.getIdCliente());
} catch (IOException e) {
System.out.println("Error en lectura de datos\nNo se pudo crear el Nuevo Cliente");
}

}
}
« Última modificación: 07 de Junio 2020, 14:14 por Ogramar »
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

sapph24

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 4
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #4 en: 11 de Junio 2019, 16:33 »
Muchas gracias por tomarte el tiempo para explicarme, porque sinceramente estaba super perdida,  tomare y corregire todos los puntos que me diste (asi como el .zip) para corregir y seguir/guiarme con el programa, enserio muchas gracias!!! Me salvas completamente la vida!

sapph24

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 4
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #5 en: 12 de Junio 2019, 04:09 »
Bueno...Aqui otra duda, veras tengo una clase "productos"(Atributos Cantidad, ID Producto, etc...) e "Inventario" (agrega productos, quita, etc,muy parecido con lo que ya me has ayudado) ya la he realizado y puedo agregar productos correctamente, pero ahora tengo el problema de tener que implementar una clase de "Facturas", y "Facturas Registro"esta de igual manera agrega y elimina facturas(Listo); el problema es que al agregar una Factura (Atributos Factura: Nota, IdFactura + Atributos claseProducto:Cantidad+IdProducto...etc), la cantidad del producto marcado en la factura debe de agregarse a la cantidad de la clase productos... Como puedo hacer esto?

Espero haberme explicado bien...

Enserio muchas gracias...
« Última modificación: 07 de Junio 2020, 14:07 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 985
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #6 en: 12 de Junio 2019, 14:47 »
Vale, creo que te entiendo.
A ver, he añadido las nuevas clases a mi código, lo básico para ver como hacer lo que pides.

A mi modo de ver, sería interesante que cada Factura incluyese su propio ArrayList con los objetos Producto que se están facturando. Así es más cómodo gestionarlo todo.

Mira, esta podría ser la clase Producto con los atributos básicos que supongo ha de tener.
Fíjate que aquí se me ha ocurrido ponerle dos constructores.

En uno, se pide el id de producto, la descripcion y la cantidad.
Este constructor podría ser más útil para añadir Productos al Inventario, ya que aquí los añadiremos una única vez y querremos que tengan su descripción más completa.

En el otro constructor, solo se pide el id y la cantidad. No se pide la descripción.
Este sería más cómodo para cuando tengamos que añadir Productos a una Factura, nos ahorramos tener que poner la descripción.

Que no es necesario hacerlo así, esto es algo que se me ha ocurrido sobre la marcha y aunque luego no se aplique, está bien saber que existe esta posibilidad de tener distintos constructores para elegir según cada ocasión.

Atenta a un método llamado variarCantidad(). Este método, a diferencia de setCantidad(), lo que hará será sumar la cantidad recibida por argumentos a la cantidad actual, y será uno de los método que nos ayudará a cumplir con lo que pides.
Si le pasasemos una cantidad con valor negativo, entonces dicha cantidad se restaría.
Por eso he preferido llamarlo variarCantidad() en lugar de por ejemplo sumarCantidad(), aunque el nombre es irrelevante.

Por supuesto, la clase también incorpora el método equals(), pues dentro de nuestro Inventario no deberían haber objetos Producto repetidos.

Aquí la clase Producto

Código: [Seleccionar]
public class Producto {

private String idProducto;
private String descripcion;
private int cantidad;

/*
* Podemos hacer dos constructores.
* Uno donde no sea necesario dar la descripcion, ideal para añadir Productos en Facturas.
* Otro donde sí se pida la descripción, más adecuado para añadir Productos al Inventario.
*/

public Producto(String id, int cant) {
idProducto = id;
cantidad = cant;
setDescripcion("");
}

public Producto(String id, String descripcion, int cant) {
idProducto = id;
cantidad = cant;
this.setDescripcion(descripcion);
}

public String getIdProducto() {
return idProducto;
}

public String getDescripcion() {
return descripcion;
}

public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}

public int getCantidad() {
return cantidad;
}

public void setCantidad(int cantidad) {
this.cantidad = cantidad;
}

public void variarCantidad(int cantidad) {
this.cantidad += cantidad;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Producto) {
Producto otroProducto = (Producto)obj;

return idProducto.equals(otroProducto.getIdProducto());
}
else
return false;
}
}


Los Productos se guardarán en la clase Inventario, que básicamente es un ArrayList donde insertar Productos.
Como ya hemos dicho, no pueden haber Productos con el mismo ID, así que antes de insertar un Producto se comprueba si ya existe en el inventario o no.

Aquí hay que destacar el método actualizaCantidadProducto() (sí, es muy largo, puedes ponerle uno más corto si quieres)
Este método lo que hace es recibir un ID de producto y una cantidad, y entonces buscará en el Inventario el Producto que coincida con ese ID y le sumará la cantidad recibida.
De este modo, cuando tengamos una Factura, con este método podremos actualizar el Inventario con las nuevas cantidades indicadas por la Factura.

Clase Inventario
Código: [Seleccionar]
public class Inventario {

private ArrayList<Producto> productos;

public Inventario() {
productos = new ArrayList<Producto>();
}

public boolean addProducto(Producto producto) {
if (productos.contains(producto))
return false;
else
return productos.add(producto);
}

public boolean actualizaCantidadProducto(String idProducto, int cantidad) {
for (Producto prod: productos) {
if (prod.getIdProducto().equals(idProducto)) {
prod.variarCantidad(cantidad);
return true; //Producto encontrado y actualizado
}
}
//Si el bucle termina sin retornar true, es que no se ha encontrado producto con ese id
return false;
}

}


Ahora pasamos a las Facturas.
Como dije antes, además del ID y su atributo notas, me parece interesante que tenga un ArrayList donde se irán añadiendo los Productos que se van a facturar.

A la hora de agregar Productos, al tratarse de una Factura y no el Inventario, en este caso podríamos admitir tener Productos repetidos (mismo ID) en el ArrayList de la Factura.
Pero, creo que es más interesante hacer que cuando se quiera registrar un Producto que ya está listado en la Factura, lo que podemos hacer es sumar la cantidad del Producto recibido a la cantidad del Producto que ya está en la Factura.
Así cada Producto solo estará listado una sola vez, pero con todas las cantidades que se hayan querido facturar.

De todo esto se encargará el método addProducto()
Fíjate que hay otro método llamado getProductosFacturados() que retorna el ArrayList completo.
Este método nos será útil para, cuando en el programa principal hayamos registrado una Factura, obtener los Productos de los cuáles hemos de actualizar las cantidades en el Inventario. Eso lo veremos luego.

Aquí clase Factura, con su obligado método equals(), pues no podemos admitir Facturas repetidas con el mismo ID.
Código: [Seleccionar]
public class Factura {

private String idFactura;
private String nota;
private ArrayList<Producto> productosFacturados;

public Factura(String id, String nota) {
idFactura = id;
this.nota = nota;
productosFacturados = new ArrayList<Producto>();
}

public String getIdFactura() {
return idFactura;
}

public String getNota() {
return nota;
}

public void setNota(String nota) {
this.nota = nota;
}

public void addProducto(Producto producto) {
if (productosFacturados.contains(producto)) {
/*
* Si ya existe este Producto en la factura, en lugar de
* añadirlo, lo que haremos será sumar las cantidades.
* Así en la Factura cada producto aparece una sola vez
* pero con la suma de todas las cantidades facturadas
*/
int indice = productosFacturados.indexOf(producto); //Averiguamos indice del producto coincidente
productosFacturados.get(indice).variarCantidad(producto.getCantidad()); //Sumamos las cantidades
}
else
productosFacturados.add(producto);
}

public ArrayList<Producto> getProductosFacturados() {
return productosFacturados;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Factura) {
Factura otraFactura = (Factura)obj;
return idFactura.equals(otraFactura.getIdFactura());
}
else
return false;
}

}

Y ahora necesitamos una clase para Registrar las Facturas.
Siguiendo la mecánica habitual, se va a tratar básicamente de un ArrayList para insertar Facturas y que impedirá que estas se repitan.
No tiene nada destacable.

Código: [Seleccionar]
public class FacturasRegistro {

private ArrayList<Factura> facturas;

public FacturasRegistro() {
facturas = new ArrayList<Factura>();
}

public boolean addFactura(Factura factura) {
if (facturas.contains(factura))
return false;
else
return facturas.add(factura);
}

}

OK. Ya tenemos todos los elementos necesarios para trabajar. Ahora hay que ver como los ponemos en funcionamiento.

No se exactamente como quieres que funcione esto en el programa principal.
Pero vamos a suponer que en el menu habrá una opción para registrar una Factura y que al registrarla, se actualicen las cantidades de los Productos facturados en el Inventario.
La secuencia de pasos podría ser:
- Pedir datos para crear una nueva Factura.
- Pedir datos para crear Productos hasta que el usuario indique finalizar.
   Los Productos que se van creando se añaden a la nueva Factura
- Cuando la Factura está lista, se inserta en el Registro de Facturas.
- Si la Factura se ha registrado correctamente (su ID no estaba repetido), entonces actualizamos los Productos del Inventario con las nuevas cantidades.
- Informamos por pantalla de si algún Producto no se ha podido actualizar, quizás porque en el Inventario no se ha encontrado un Producto coincidente con alguno de los que hay en la Factura.



Bien, pues todos estos pasos, son los que va a realizar este método que estaría declarado en la clase Sistema (la principal) y podría ser invocado desde una de las opciones del menú.

Código: [Seleccionar]
private static void facturarArticulos() {
//Creamos factura
System.out.println("Ingresar datos factura: ID, Notas");
try {
Factura nuevaFactura = new Factura(stdIn.readLine(), stdIn.readLine());
//Tenemos factura creada. Hay que añadir artículos.
String idProducto = "";
int cantidad = 0;
do {
System.out.println("Facturando productos.");
System.out.println("Teclee ID del Producto a facturar o escriba 'fin' para terminar");
System.out.println("ID Producto: ");
idProducto = stdIn.readLine();
if (!idProducto.equals("fin")) {
System.out.print("Cantidad a facturar: ");
cantidad = Integer.parseInt(stdIn.readLine());
//Añadimos producto a Factura
nuevaFactura.addProducto(new Producto(idProducto, cantidad));
}
}while(!idProducto.equals("fin"));
//Articulos añadidos a Factura. Hay que registrarla.
if (facturasRegistro.addFactura(nuevaFactura)) {
//La Factura ha sido aceptada, hay que actualizar el inventario.
System.out.println("Factura aceptada.\nSe va a actualizar el Inventario");
for (Producto prod: nuevaFactura.getProductosFacturados()) {
if (inventario.actualizaCantidadProducto(prod.getIdProducto(), prod.getCantidad()))
System.out.println("Producto con ID " + prod.getIdProducto() + "actualizado" );
else {
System.out.println("\nProducto con ID " + prod.getIdProducto() + "no actualizado");
System.out.println("Este producto no existe en el Inventario.\n");
}
}
}
else //La factura NO ha sido aceptada en el Registro.
System.out.println("Factura no registrada. Ya existe una factura con ese ID");
} catch (IOException e) {
System.out.println("Error en lectura de datos.");
} catch (NumberFormatException e) {
System.out.println("El dato introducido no es un número");
}
}

Parece que hay mucho código, pero no es tanto y básicamente lo que hace es seguir los pasos que he descrito antes.

Fíjate que cuando actualizamos las cantidades de los Productos del Inventario, si ocurre el caso de que un Producto que está en la Factura, no está en el Inventario (y por tanto no se puede actualizar ninguna cantidad), aquí se nos abre la posibilidad de añadir directamente ese Producto al Inventario.
Aunque es un Producto que en ese momento no tiene nada en su atributo Descripcion, y quizás antes de añadirlo habría que pedirle al usuario este dato.

Pero bueno, esto lo comento como una posibilidad que puedes decidir añadirla o no. Tampoco es necesario crear el "programa perfecto", si no aprender a a trabajar con distintas clases, aprender como relacionarlas y como almacenarlas en distintas colecciones de datos.

Creo que esto es más o menos lo que querías conseguir. Leete con detenimiento cada clase que he posteado, asegurate de que te queda claro para qué vamos a necesitar cada uno de los métodos que he destacado y sobre todo entender bien este último método, que simplemente cumple con los pasos enumerados anteriormente.

He de decir que no he tenido ocasión de probar su funcionamiento.
Lo he escrito pero no he podido probarlo...estoy bastante seguro de que funciona, pero nunca se sabe je je :P
 
Cualquier duda o cosa que no entiendas, ya sabes, pregúntala por aquí.
Un saludo.
« Última modificación: 12 de Junio 2019, 14:52 por Kabuto »
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

sapph24

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 4
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #7 en: 13 de Junio 2019, 02:35 »
Muchas gracias por todo nwn mi programa ya funciona como deberia y todo gracias a ti nwn Enserio muchas gracias!!

TricuspidAp7

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 2
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #8 en: 13 de Junio 2019, 07:54 »
Buenas noches, viendo esto me a ayudado mucho con un caso similar que tengo, incluso me he basado en gran parte del codigo para realizar el mio (que va muy similar al que trabajan ahora mismo), veras ya he creado mis clases y etc, estas son mis clases:

Todas las ArrayList incluyen metodo de imprimir toda la lista, asi como añadir una nueva factura, o producto respectivamente

Clase Producto:
Atributos:
Cantidad int
idProducto, Descripcion string
double impuesto, precio
*getters y setters puestos.

Clase Inventario
ArrayList<Productos>

Clase Factura
Atributos
String Nota, IdFactura, Fecha
*getters y setters colocados y funcionando

Clase FacturaRegistro
ArrayList<Facturas>

Clase Vendedor
Atributos: IdProvedor

Clase Sistema
Los metodos estan manejados por un switch para cada caso
metodos:
   addProducto()
   addFactura()
   addVendedor()
   mostrarFacturasEnOrden()

En mi caso necesito poder agregar una  factura, esta debe de contener el IDVendedor, Producto vendido(id), Cantidad (Ademas esta cantidad debe de sustraerse de un producto en caso de existir), Y poder ordenar las facturas de acuerdo a la fecha.
Seria de gran ayuda si pudieses ayudarme, estoy algo perdido en esto tambien jaja..

Gracias por adelantado.

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 985
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #9 en: 13 de Junio 2019, 11:51 »
Muchas gracias por todo nwn mi programa ya funciona como deberia y todo gracias a ti nwn Enserio muchas gracias!!
De nada, un placer.

En mi caso necesito poder agregar una  factura, esta debe de contener el IDVendedor, Producto vendido(id), Cantidad (Ademas esta cantidad debe de sustraerse de un producto en caso de existir), Y poder ordenar las facturas de acuerdo a la fecha.
Seria de gran ayuda si pudieses ayudarme, estoy algo perdido en esto tambien jaja..
Preguntas:
¿En una Factura solo habrá un Producto vendido?
En el código que hice para la compañera sapph24, di por hecho que en una Factura puede haber facturado más de un artículo.
Por eso decidí que cada Factura debería tener algún tipo de colección para guardar la info de estos Productos facturados y escogí un ArrayList que contenga objetos Productos.

Pero si solo va a contener un único producto, no será necesario ningún tipo de array. Bastará con un String para el ID producto y un int para la cantidad.

Sobre la fecha. ¿Se ha decidido qué formato va a tener?
Para la fecha se va a usar la clase String y si queremos poder ordenar por fecha, hay que tener muy claro que formato va a tener:
- Dias, mes y año: ddmmaaaa
- Mes, dia y años: mmddaaaa
- Año, mes y dia: aaaammdd (la más comoda para ordenar)

¿Se introduce sin separadores o con separadores?, ejemplos:
- dd-mm-aaaa
- dd/mm/aaaa

El algortimo que ordene fechas dependerá de cuál sea el formato de esta.
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

TricuspidAp7

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 2
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #10 en: 13 de Junio 2019, 17:48 »
Hola, bueno  pensaba usar el "año mes día" aaaammdd,  como recomiendas, ...¿como se podria hacer esto? Gracias.

P.d. Estamos intentando eliminar productos o vendedores, alguna idea para realizarlo?

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 985
    • Ver Perfil
Re:Añadir, Citar, Eliminar Elementos (ArrayList)
« Respuesta #11 en: 13 de Junio 2019, 20:59 »
Hola, bueno  pensaba usar el "año mes día" aaaammdd,  como recomiendas, ...¿como se podria hacer esto? Gracias.

P.d. Estamos intentando eliminar productos o vendedores, alguna idea para realizarlo?

Vale usando ese formato es muy fácil ordenar.
Explico:
Colecciones como ArrayList tienen un método que permite ordenar los objetos que contiene. Es el método .sort().

Para usar este método hay dos maneras:
- Le pasamos por argumentos en el paréntesis una expresión para indicarle al ArrayList como debe ordenar los objetos que contiene..
- Le pasamos valor null, y confiamos en que el ArrayList sepa como ordenarse.

La primera manera puede ser algo complicado saber construir correctamente dicha expresión.

La segunda manera es la más fácil, pero claro, dependemos de que el ArrayList sepa ordenarse.
Aunque lo cierto, es que esto no depende del ArrayList, sino de los objetos que contiene. Son ellos los que tienen que saber como "compararse" unos con otros para decidir quien es menor y quien es mayor.
Los objetos que saben "compararse", son los que su clase implementa la interfaz Comparable

Por ejemplo los objetos de clases que representan números: Integer, Double, Float.... sí la implementan y por eso saben perfectamente que un 4 es menor que un 5.

La clase String, también la implementa, así que saben perfectamente que la cadena "b" es menor que la cadena "c".

Así que nunca tendremos problemas para ordenar un ArrayList de Integer o de String, basta con llamar a sort(null) y se ordenará al momento el solito.

Pero nuestro ArrayList de Registro de Facturas, va a contener objetos de la clase Factura.
Una clase que hemos creado nosotros y que sus objetos no saben como compararse para decidir quien es menor o mayor.
Así que ahora mismo nuestro ArrayList de Facturas, no sabe como ordenar sus objetos.

Pero para eso estamos nosotros, para enseñarle a la clase Factura como compararse.

Lo primero es implementarle la interfaz Comparable, indicándole el tipo de clase con el que se tiene que comparar, que lo normal es que sea ella misma.

Código: [Seleccionar]
public class Factura implements Comparable<Factura>{
......
......

Al implementar esta interfaz, el compilador inmediatamente nos obliga a implementar también el método compareTo().
Este método es el que explica como ha de compararse un objeto y ha de retorna un int.
Si los objetos se consideran del "mismo valor" ha de retorna 0
Si el objeto recibido por argumentos, es mayor respecto al objeto que invoca el método, ha de retornar -1.
Si el objeto recibido es menor, entonces ha de retornar 1.

Bien, en nuestro caso, tendríamos que escribir un código que compare las fechas.
Podemos ordenarlas de modo que las fechas más antiguas se consideren menores que las fechas más recientes.
Es decir, la fecha 20191105 es menor que la fecha 20191205, porque esta última es más reciente.
Bueno, para hacer esto podríamos empezar a trocear el String que contiene la fecha, para separar el valor del año, del mes y del dia...y parsearlos a valores int, y entonces....

Pero, ¡¡espera!!. Hemos dicho antes que los objetos String ya saben compararse. Y precisamente se comparan de forma que coincide a como queremos ordenar las fechas.

El String "20191105" se considera menor que el String "20191205".
Es más, podemos usar separadores como guiones y la comparación de String fucnionará igual.
"2019-11-05" es menor que "2019-12-05".

Así que no tenemos que hacer nada, tan solo decirle a nuestro método compareTo(), que retorne el resultado de comparar directamente los String de fechas.

Código: [Seleccionar]
@Override
public int compareTo(Factura otraFactura) {
return fecha.compareTo(otraFactura.getFecha());
}

Genial, ahora nuestra clase Factura ya sabe como compararse unas con otras para decidir cual es menor o mayor, en función de su fecha.

Ahora lo que podemos hacer es decirle a nuestra clase de Registro de Facturas, que cada vez que entre una nueva Factura en el ArrayList, lo ordene. Así siempre estará ordenado tras cada inserción.

Código: [Seleccionar]
public boolean addFactura(Factura factura) {
if (facturas.contains(factura))
return false;
else {
facturas.add(factura);
facturas.sort(null); //Null es porque las Facturas ya saben como compararse para ordenarse
return true;
}
}


Con esto, si desde el programa principal, tras haber hecho algunas facturas pedimos un listado, veremos que salen ordenadas por fecha, de más antigua a más moderna.
Las facturas de este listado yo las he ido creando por orden de ID: FAC01, FAC02, FAC03 y FAC04.
Pero al entrar en el ArrayList, se han ido ordenando por la fecha.

Citar
      FACTURAS REGISTRADAS

ID: FAC03 Fecha: 2018-12-12
Notas: jiol

ID: FAC02 Fecha: 2019-06-14
Notas: popop

ID: FAC01 Fecha: 2019-06-15
Notas: fasdfsa

ID: FAC04 Fecha: 2019-08-15
Notas: sdafsa

Bueno, ¿y si queremos que el orden sea al revés? ¿De más reciente a más antiguas?
Entonces bastaría con modificar el método comparteTo() de la clase Factura, diciéndole que modifique el signo del resultado de comparar los Strings de fechas.
Cuando el resultado sea -1, ha de devolver +1 y viceversa.
Para hacer esto, puesto que somos grandes matemáticos xD, ya sabemos que nos basta con multiplicar lo que retorna, por -1

Citar
   @Override
   public int compareTo(Factura otraFactura) {
      return fecha.compareTo(otraFactura.getFecha()) * -1;
   }

Esto revierte a como se ordenan las facturas, ahora las fechas recientes se consideran menores que las antiguas:
Citar
      FACTURAS REGISTRADAS

ID: FAC04 Fecha: 2019-08-15
Notas: sdafad

ID: FAC01 Fecha: 2019-06-15
Notas: fsadfa

ID: FAC02 Fecha: 2019-06-14
Notas: popop

ID: FAC03 Fecha: 2018-12-12
Notas: jiol


Y ya está.
Cierto es que hemos optado por la via fácil, usar un String con formato aaaa-mm-dd.
Y ojo, es que ese formato de fecha cumple en realidad con la norma ISO 8601 y es la que se suele usar en informática precisamente por esto, porque facilita mucho la ordenación alfanumérica.

Sin embargo en la mayoría de paises de habla hispana, lo habitual es usar dd-mm-aaaa.
Pero bueno, no creo que sea necesario ahora pelearse con formatos de fecha.

Lo importante aquí es aprender que para ordenar objetos, podemos hacerlo implementado la interfaz Comparable y decidir nosotros que atributos son decisivos para hacer la comparación.
En el Curso de Java Avanzado tienes un ejemplo algo más elaborado.

Sabiendo ya esto, puedes decidir ya si quieres usar otro formato de fecha, o usar clases como LocalDate

En ambos casos ya se requiere meter más programación.

Respecto a esto:
Citar
P.d. Estamos intentando eliminar productos o vendedores, alguna idea para realizarlo?

Los ArrayList tienen el metodo remove() que debería permitirte hacer esto fácilmente.

Por ejemplo, en la clase Inventario, si quiero eliminar un Producto de su ArrayLsit, me basta con escribirle este método:
Código: [Seleccionar]
public boolean eliminarProducto(Producto producto) {
return productos.remove(producto);
}

Este método recibe un objeto Producto que es el que se ha de eliminar.
Así que se lo pase al método remove() del ArrayList.
remove() lo que hace es que si dicho Producto existe en el ArrayList, lo elimina y retorna true.
Si no existiera, entonces retorna false.

Entonces, en el programa principal, cuando el usuario active la opción "eliminar Producto", tu tendrás que pedirle al usuario el ID de producto que quiere eliminar.
Con ese ID construyes un objeto Producto y se lo pasas a este método para que lo elimine del ArrayList de Inventario.

No hace falta que construyas un Producto con los datos idénticos a como esté en el ArrayList. No necesitas saber la cantidad ni la descripción del producto ni ningún otro valor, solo el ID.
Recuerda que Producto tiene un método llamado equals() en donde se indica que dos objetos Producto son IGUALES si coincide su ID.

Así que te basta con construir un Producto con el ID indicado, y el resto de parámetros del constructor pueden tener cualquier valor, no importa. Solo necesitas que coincida el ID.

Por ejemplo, mi clase Producto que escribí para este ejercicio, si recuerdas, tiene dos constructores y uno solo pide un String con el ID y un valor int para la cantidad.
Yo a ese int le puedo poner cualquier valor, no tiene que coincidir con la cantidad que marca el Inventario para poder borrarlo.
El código podría ser algo así:
Código: [Seleccionar]
System.out.print("Indique el ID del producto a eliminar: ")
String idPRoducto = stdIn.readLine();
if (inventario.eliminarProducto(new Producto(idProducto, 0)) //Pongo una cantidad cualquiera
    System.out.println("Producto ha sido eliminado");
else
    System.out.println("No hay ningún Producto con ese ID en el Inventario");

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".