package colecciones.programas.applets.lista2;
import java.util.Collection;
import java.util.AbstractList;//<-OjO
import java.util.Iterator;
import java.util.NoSuchElementException;
import colecciones.programas.applets.entrada.Entrada;
public class Lista2
extends AbstractList//<-OjO
implements Cloneable
{
private Entrada último;
private int size; //longitud de la lista
//constructores
public Lista2() {
}
public Lista2(Collection c) {
addAll(c);
}
//operadores especificados
//anula. Convierte a la lista en un lista vacia.
public void clear() { //OPCIONAL
último = null;
size = 0;
}
//inserta. Inserta o en la posición index. Si index no existe, el
//resultadoes indefinido. size() es un lugar válido.
public void add(int index, Object o) { //OPCIONAL
if(index < 0 || index > size) {
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size);
}
Entrada entrada = new Entrada(o);
if(isEmpty()) {
entrada.setSiguiente(entrada); //1er. nodo de la lista circular
último = entrada;
} else {
Entrada anterior = (index == 0 || index == size) ?
último :
entrada(index - 1);
entrada.setSiguiente(anterior.getSiguiente());
anterior.setSiguiente(entrada);
if(index == size) { //nuevo último: insertó al final
último = entrada;
}
}
size++;
}
//suprime. Elimina el elemento situado en la posición index. El resultado
//es indefinido si no existe la posición especificada. Retorna el elemento
//eliminado.
public Object remove(int index) { //OPCIONAL
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size);
}
//existe posición
Entrada anterior = último;
for(int i=0; i < index; i++) {
anterior = anterior.getSiguiente();
}
Entrada eliminado = anterior.getSiguiente();
Object elemento = eliminado.getElemento();
remove(anterior); //elimina anterior.getSiguiente()
if(eliminado == último) { //si la lista está vacia:
último = anterior; //eliminado != null && último == null
}
return elemento;
}
//localiza. Retorna la posición de la primera ocurrencia de o en la lista.
//Retorna -1 si o no existe en la lista.
public int indexOf(Object o) {
int nActual = 0;
for(Iterator i = iterator(); i.hasNext(); nActual++) {
if(o.equals(i.next())) {
return nActual;
}
}
return -1;
}
//recupera. Retorna el elemento que se encuentra en la posición index. El
//resultado es indefinido si no existe la posición especificada.
public Object get(int index) {
return entrada(index).getElemento();
}
//contiene. Retorna true si la lista contiene a o.
public boolean contains(Object o) {
return indexOf(o) != -1;
}
//longitud. Retorna la cantidad de elementos que contiene la lista.
public int size() {
if(size > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return size;
}
//métodos de apoyo
//implementado sólo por ejercicio
public Object set(int index, Object o) {//<-OjO //OPCIONAL
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size);
}
//existe posición
Entrada entrada = entrada(index);
Object elemento = entrada.getElemento();
entrada.setElemento(o);
return elemento;
}
private Entrada entrada(int index) {
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size);
}
//existe posición
Entrada entrada = último.getSiguiente( );
for(int nActual = 0; nActual < index; nActual++) {
entrada = entrada.getSiguiente();
}
return entrada;
}
//elimina el nodo anterior.getSiguiente()
//asume que existe el nodo anterior
private void remove(Entrada anterior) {
if(anterior.getSiguiente() == anterior) { //hay 1 elemento
último = null;
} else { //elimina por cualquier otra parte
anterior.setSiguiente(anterior.getSiguiente().getSiguiente());
}
size--;
}
//clone
public Object clone() {
Lista2 clone = null;
try {
clone = (Lista2)super.clone();
} catch(CloneNotSupportedException e) {
throw new InternalError();
}
clone.clear( );
for(Iterator e = iterator(); e.hasNext(); ) {
clone.add(e.next());
}
return clone;
}
}