Foros del Web » Programación para mayores de 30 ;) » Java »

Cambiar un objeto de clase en un ArrayList

Estas en el tema de Cambiar un objeto de clase en un ArrayList en el foro de Java en Foros del Web. Hola a todos. Antes de nada, querría presentarme: mi nombre es Daniel y soy estudiante de ingeniería. En la asignatura de fundamentos de informática, estamos ...
  #1 (permalink)  
Antiguo 02/05/2010, 13:18
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 13 años, 11 meses
Puntos: 0
Cambiar un objeto de clase en un ArrayList

Hola a todos.

Antes de nada, querría presentarme: mi nombre es Daniel y soy estudiante de ingeniería. En la asignatura de fundamentos de informática, estamos trabajando el JAVA y en la práctica que debo entregar me surje el siguiente problema:

Tengo una clase GestorDeCliente en el que he creado un ArrayList para añadir un listado de objetos de dos tipos de clases: Clientes y ClientesVIP (éste último, una subclase de la clase Clientes). Me piden que cree un método para seleccionar un objeto del tipo Cliente y lo cambie a ClienteVIP y viceversa. Cuando utilizo el ciclo "for" para seleccionar el cliente (por medio del nif), utilizo los métodos get para obtener todos los campos de definición del objeto, para luego añadir un nuevo ClienteVIP. El compilador me complia, pero cuando ejecuto, me sale un error de "concurrencia". Llevo varios días intentándolo, con lo cual agradecería cualquier orientación sobre como afrontar el problema, teniendo en cuenta que soy muy novato (tan sólo llevo dos meses estudiando JAVA) y que nunca antes he programado en ningún lenguaje.

Perdón por el ladrillo y espero vuestra inestimable ayuda...

Slds,
Daniel M.
  #2 (permalink)  
Antiguo 02/05/2010, 13:48
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 6 meses
Puntos: 454
Respuesta: Cambiar un objeto de clase en un ArrayList

¿Cual es el error exacto que te da y el trozo de código en donde te da?
Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #3 (permalink)  
Antiguo 02/05/2010, 14:01
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 13 años, 11 meses
Puntos: 0
Respuesta: Cambiar un objeto de clase en un ArrayList

Gracias por la rápida respuesta chuidiang y perdona por los pocos datos que he reflejado. El método que he escrito es:

Código Javascript:
Ver original
  1. public void cambiarClienteAVIP(String nifCliente)
  2. {
  3. int indice = 0;
  4. for(Cliente clienteCambiado : clientes) {
  5. if (nifCliente.equals(clienteCambiado.getNif())) {
  6. ClienteVIP nuevoCliente = new ClienteVIP(clienteCambiado.getNombre(), clienteCambiado.getApellidos(),
  7. clienteCambiado.getNif(), clienteCambiado.getSexo(), clienteCambiado.getAñoDeNacimiento(),
  8. clienteCambiado.getNumeroDeCliente(), clienteCambiado.getAñoDeAlta());
  9. clientes.remove(clienteCambiado);
  10. clientes.add(nuevoCliente);
  11. indice++;
  12. }
  13. }
  14. if (indice == 0) {
  15. System.out.println("El NIF indicado no corresponde a ningún cliente");
  16. }
  17.  
  18. }

Me salta el error:

java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification( AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java: 343)
at GestorDeClientesAvanzado.cambiarClienteAVIP(Gestor DeClientesAvanzado.java:69)

Y me pone en amarillo (utilizo BlueJ) la línea de inicio del ciclo "for".

Aparecen ya los datos necesarios para analizar el problema?? (Es que estoy perdidísimo, jejeje...)

Gracias por adelantado!!

Daniel M.

Última edición por Damarsito; 03/05/2010 a las 01:44
  #4 (permalink)  
Antiguo 02/05/2010, 16:12
Avatar de DiabloGuardian  
Fecha de Ingreso: noviembre-2008
Ubicación: Hidalgo
Mensajes: 215
Antigüedad: 15 años, 5 meses
Puntos: 3
Respuesta: Cambiar un objeto de clase en un ArrayList

Hola!!
La documentacion de java dice:

Cita:
Esta excepción puede ser lanzada por los métodos que se han detectado modificaciones simultáneas de un objeto cuando tal modificación no está permitido.

...

Por ejemplo, si un hilo modifica una colección directamente mientras se está interactuando sobre la colección con un iterador no-rápido, el iterador lanzarán esta excepción.
Eso quiere decir que:

Código java:
Ver original
  1. public void cambiarClienteAVIP(String nifCliente)
  2. {
  3. int indice = 0;
  4. for(Cliente clienteCambiado : clientes) {
  5. if (nifCliente.equals(clienteCambiado.getNif())) {
  6. ClienteVIP nuevoCliente = new ClienteVIP(clienteCambiado.getNombre(), clienteCambiado.getApellidos(),
  7. clienteCambiado.getNif(), clienteCambiado.getSexo(), clienteCambiado.getAñoDeNacimiento(),
  8. clienteCambiado.getNumeroDeCliente(), clienteCambiado.getAñoDeAlta());
  9.  
  10.  
  11. clientes.remove(clienteCambiado);  <<-- Aqui intentas eliminar un objeto que esta siendo usado
  12.  
  13.  
  14. clientes.add(nuevoCliente);
  15. indice++;
  16. }
  17. }
  18. if (indice == 0) {
  19. System.out.println("El NIF indicado no corresponde a ningún cliente");
  20. }
  21.  
  22. }

Se me ocurren dos posibles soluciones:
1) puedes clonar tu objeto haciendo algo asi:

Código java:
Ver original
  1. Cliente clienteTemp = clienteCambiado.clone();
  2. clientes.remove(clienteTemp);

2) Podrias hacer unos castings, si dices que ClientesVIP es una subclase de Clientes, intenta hacer algo asi:


Código java:
Ver original
  1. public void cambiarClienteAVIP(String nifCliente)
  2. {
  3. int indice = 0;
  4. for(Cliente clienteCambiado : clientes) {
  5. if (nifCliente.equals(clienteCambiado.getNif())) {
  6. clienteCambiado=(ClienteVIP)clienteCambiado;
  7. //aqui solo agregarias los valores de los atributos que cambian
  8. indice++;
  9. }
  10. }
  11. if (indice == 0) {
  12. System.out.println("El NIF indicado no corresponde a ningún cliente");
  13. }
  14.  
  15. }


Ojala te sirva esto, saludos
__________________
-=:[ Lo importante no es saber todo, sino saber buscar ]:=-
  #5 (permalink)  
Antiguo 03/05/2010, 01:34
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 13 años, 11 meses
Puntos: 0
De acuerdo Respuesta: Cambiar un objeto de clase en un ArrayList

Gracias por la respuesta, DiabloGuardian.

Creo que el problema no es el intentar borrar el objeto seleccionado por el ciclo "for", ya que tengo otro método de "eliminarClientePorNif" que lo hace sin problemas. He probado ambas soluciones que me has aconsejado y no sirve ninguna, pues ni siquiera compilan.

Voy a cambiar de táctica, pues creo que el problema viene por agregar un nuevo objeto a un ArrayList por el que corre un ciclo "for". Voy a intentar cambiar el ciclo por un "while" a ver que tal...

Cualquier otra propuesta, será bienvenida!!

Gracias,
Daniel M.
  #6 (permalink)  
Antiguo 03/05/2010, 01:47
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.511
Antigüedad: 15 años, 8 meses
Puntos: 188
Respuesta: Cambiar un objeto de clase en un ArrayList

Construye un segundo arraylist actualizandolo a medida que recorres el for del primero, se añade el elemento sin modificar si no hay que hacer nada, y se añade como VIP cuando haya que hacerlo. Luego asignas el nuevo arraylist a la referencia del primero y ya puedes seguir procesándolo.
  #7 (permalink)  
Antiguo 03/05/2010, 03:08
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 13 años, 11 meses
Puntos: 0
Respuesta: Cambiar un objeto de clase en un ArrayList

Gracias Fuzzylog, pero llevo un rato intentándolo y no lo consigo. Me compila, pero sigue saltando el error de "ConcurrentModificationException" en la misma línea del primer ciclo "for"... No entiendo nada!!

Me puedes ampliar la info, para hacerlo correctamente, por favor??

Gracias!!
DM
  #8 (permalink)  
Antiguo 03/05/2010, 03:33
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Respuesta: Cambiar un objeto de clase en un ArrayList

Si recorres una coleccion con un bucle for-each, no puedes borrar elementos de ella mientras lo haces. Para poder borrar un elemento, lo que tienes que hacer es declarar y recorrer explicitamente la coleccion con un Iterator y usar el metodo remove() que tiene.

Lo explican en la documentación del bucle for-each, al final:
http://java.sun.com/j2se/1.5.0/docs/...e/foreach.html

Cita:
Unfortunately, you cannot use it everywhere. Consider, for example, the expurgate method. The program needs access to the iterator in order to remove the current element. The for-each loop hides the iterator, so you cannot call remove.
S!
__________________
Para obtener respuestas, pregunta de forma inteligente o si no, pregunta lo que quieras que yo contestaré lo que me dé la gana.
  #9 (permalink)  
Antiguo 03/05/2010, 03:37
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 13 años, 11 meses
Puntos: 0
De acuerdo Respuesta: Cambiar un objeto de clase en un ArrayList

Gracias GreenEyed, voy a buscar información del Iterator, que no se como funciona, y lo intento...

Slds,
DM

Etiquetas: arraylist, clase, objeto
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:53.