Hola a todos. Aquí dejo mi implementación del ejercicio CU00921C del tutorial pdf de programación avanzada en Java. He implementado ambas opciones, ArrayList y LinkedList, en el mismo programa, para facilitarme la comparación de los resultados y practicar la aplicación del polimorfismo.
Los procedimientos de creación de las listas y de eliminación-inserción, los he implementado como métodos de la clase principal. Además, aunque no se pedía en el ejercicio, he incluido un método para mostrar el contenido de las listas y lo he usado para mostrar los resúmenes.
Clase Vehiculo
package cu00921c.ejercicio;
public class Vehiculo {
private int idVehiculo;
private String tipo;
public Vehiculo(int id, String tipo){
idVehiculo=id;
this.tipo=tipo;
}
public void setIdVehiculo(int id){idVehiculo=id;}
public void setTipo(String tipo){this.tipo=tipo;}
public int getIdVehiculo(){return idVehiculo;}
public String getTipo(){return tipo;}
@Override
public String toString(){
return "Vehiculo-> ID: "+idVehiculo+" Tipo: "+tipo;
}
}
Clase Principal
package cu00921c.ejercicio;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class CU00921CEjercicio {
public static void main(String[] args) {
List<Vehiculo> listaarray = new ArrayList();
List<Vehiculo> listalinked = new LinkedList();
String[] tipos ={"Coche", "Camion", "Furgoneta", "Moto"};
cargarLista(listaarray,tipos);
System.out.println("Ejecución con ArrayList\n");
imprimirLista(listaarray,"inicial",false);
eliminarInsertar(listaarray);
System.out.println("\nEjecución con LinkedList\n");
cargarLista(listalinked,tipos);
imprimirLista(listalinked,"inicial",false);
eliminarInsertar(listalinked);
}
//Método que permite imprimir la lista o sólo el resumen
private static void imprimirLista(List<Vehiculo> lista, String momento, boolean resumen){
int coches=0, camiones=0, furgonetas=0, motos=0;
for (int i=0;i<lista.size();i++){
if(resumen){System.out.println(lista.get(i));}
switch (lista.get(i).getTipo()) {
case "Coche":
coches++;
break;
case "Camion":
camiones++;
break;
case "Furgoneta":
furgonetas++;
break;
default:
motos++;
break;
}
}
System.out.println("Resumen lista "+momento+": hay "+coches+" Coches, "+camiones+" Camiones, "+furgonetas+ " Furgonetas y "+motos+" Motos");
}
//Método para general la lista
private static void cargarLista(List<Vehiculo> lista, String[] tipos){
Random rnd = new Random();
for (int i=1;i<=5000;i++){
lista.add(new Vehiculo(i,tipos[rnd.nextInt(4)]));
}
}
//Método para eliminar-insertar
private static void eliminarInsertar(List<Vehiculo> lista){
long inicio, fin;
Vehiculo tmp;
int eliminados=0;
int ultimoId;
//Eliminar elementos no Coche
inicio = System.nanoTime();
Iterator<Vehiculo> it = lista.iterator();
while(it.hasNext()){
tmp=it.next();
if(!tmp.getTipo().equals("Coche")){it.remove();eliminados++;}
}
//Insertar tantos vehiculos Coche como se han eliminado
ultimoId=lista.get(lista.size()-1).getIdVehiculo();
for (int i=ultimoId; i<ultimoId+eliminados;i++){
lista.add(new Vehiculo(i,"Coche"));
}
fin=System.nanoTime();
System.out.println("Una vez realizada la eliminación-inserción:");
System.out.println("Tiempo empleado en eliminación-inserción (en nanosegundos): "+(fin-inicio));
imprimirLista(lista,"final",false);
}
}
En cuanto a las preguntas del ejercicio, estas serían mis respuestas:
a y b) Resultados:
Ejecución con ArrayList
Resumen lista inicial: hay 1264 Coches, 1193 Camiones, 1267 Furgonetas y 1276 Motos
Una vez realizada la eliminación-inserción:
Tiempo empleado en eliminación-inserción (en nanosegundos): 4065861
Resumen lista final: hay 5000 Coches, 0 Camiones, 0 Furgonetas y 0 Motos
Ejecución con LinkedList
Resumen lista inicial: hay 1298 Coches, 1250 Camiones, 1237 Furgonetas y 1215 Motos
Una vez realizada la eliminación-inserción:
Tiempo empleado en eliminación-inserción (en nanosegundos): 1971780
Resumen lista final: hay 5000 Coches, 0 Camiones, 0 Furgonetas y 0 Motos
c) Después de varias ejecuciones, se observa que el tiempo empleado usando ArrayList es siempre más del doble del que se obtiene usando LinkedList, lo que creo que se debe a que, después del borrado, las nuevas inserciones se producen al final (en este caso concreto se han debido producir 3.702 inserciones.
Es cierto que se han producido el mismo número de eliminaciones, que la mayoría de ellas se han debido producir en posiciones intermedias, y que éstas son más rápidas (según se nos indica en el texto) con ArrayList, por lo que deduzco que la eficiencia de LinkedList en las inserciones en posiciones finales supera con creces la ventaja en eficiencia de eliminaciones en posiciones intermedias obtenidas con ArrayList.