ArrayListExtra
Publicado por Ana (1 intervención) el 04/06/2006 18:10:51
Hola!! estoy implementando una clase ArrayListExtra que hereda de ArrayList. Esta clase tiene dos clases internas: ParesIterator y CloneIterator. Lo he implementado de esta forma:
public class ArrayListExtra extends ArrayList {
// Iteradores
/**
* Iterador ParesIterator: Permite devolver sólo los elementos pares de una
* lista
*/
private class ParesIterator implements Iterator {
/**
* Índice del elemento que va a ser devuelto
*/
int cursor = 0;
/**
* Índice del último elemento devuelto
*/
int lastRet = -1;
/**
* Contador de operaciones de cambio sobre la lista. Almacenamos el
* número de cambios de la lista la última vez que accedimos a ella. El
* campo modCount es heredado de AbstractList
*/
int expectedModCount = ArrayListExtra.this.modCount;
public boolean hasNext() {
return cursor < ArrayListExtra.this.size();
}
public Object next() {
checkForComodification();
try {
Object next = get(cursor);
lastRet = cursor;
cursor = cursor + 2;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException("No existen mas elementos");
}
}
public void remove() {
if (lastRet == -1)
throw new IllegalStateException(
"El metodo next aun no ha sido llamado");
checkForComodification();
try {
ArrayListExtra.this.remove(lastRet);
cursor=lastRet;
lastRet=-1;
expectedModCount = ArrayListExtra.this.modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException(
"No existe el elemento a eliminar");
}
}
final void checkForComodification() {
if (ArrayListExtra.this.modCount != expectedModCount)
throw new ConcurrentModificationException(
"Se ha modificado la lista mientras se usaba este iterador");
}
}
/**
* Iterador CloneIterator: Permite devolver los elementos sin efectos, es
* decir se devuelven clones de los objetos almacenados, no los propios
* objetos
*/
private class CloneIterator implements Iterator {
/**
* Índice del elemento que va a ser devuelto
*/
int cursor = 0;
/**
* Índice del último elemento devuelto
*/
int lastRet = -1;
/**
* Contador de operaciones de cambio sobre la lista. Almacenamos el
* número de cambios de la lista la última vez que accedimos a ella. El
* campo modCount es heredado de AbstractList
*/
int expectedModCount = ArrayListExtra.this.modCount;
public boolean hasNext() {
return cursor < ArrayListExtra.this.size();
}
public Object next() {
checkForComodification();
try {
Object next = getClone(get(cursor));
lastRet = cursor;
cursor = cursor + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException("No existen mas elementos");
}
}
public void remove() {
if (lastRet == -1)
throw new IllegalStateException(
"El metodo next aun no ha sido llamado");
checkForComodification();
try {
ArrayListExtra.this.remove(lastRet);
cursor=lastRet;
lastRet=-1;
expectedModCount = ArrayListExtra.this.modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException(
"No existe el elemento a eliminar");
}
}
private Object getClone(Object o) {
Object clon = null;
try {
Method method = o.getClass().getMethod("clone", null);
clon = method.invoke(o, null);
} catch (IllegalAccessException ex1) {
throw new ClassCastException("El metodo clone no es publico ("
+ ex1.toString() + ")");
} catch (NoSuchMethodException ex2) {
throw new ClassCastException(
"El objeto no implementa la interfaz Cloneable ("
+ ex2.toString() + ")");
} catch (InvocationTargetException ex3) {
throw new ClassCastException(
"Error inesperado al llamar al metodo clone ("
+ ex3.toString() + ")");
}
return clon;
}
final void checkForComodification() {
if (ArrayListExtra.this.modCount != expectedModCount)
throw new ConcurrentModificationException(
"Se ha modificado la lista mientras se usaba este iterador");
}
}
// Iteradores
/**
* Devuelve un iterador sobre los elementos de la lista, del tipo
* especificado como parámetro de entrada
*/
public Iterator iterator(String type) throws NoSuchIteratorTypeException {
if (type.equals("CloneIterator"))
return new CloneIterator();
else if (type.equals("ParesIterator"))
return new ParesIterator();
else
throw new NoSuchIteratorTypeException(
"Tipo de iterador no soportado:" + type);
}
}
Me da un error y me dice que el objeto no implementa la interfaz cloneable. ¿Alguien puede decirme cómo solucionarlo?
public class ArrayListExtra extends ArrayList {
// Iteradores
/**
* Iterador ParesIterator: Permite devolver sólo los elementos pares de una
* lista
*/
private class ParesIterator implements Iterator {
/**
* Índice del elemento que va a ser devuelto
*/
int cursor = 0;
/**
* Índice del último elemento devuelto
*/
int lastRet = -1;
/**
* Contador de operaciones de cambio sobre la lista. Almacenamos el
* número de cambios de la lista la última vez que accedimos a ella. El
* campo modCount es heredado de AbstractList
*/
int expectedModCount = ArrayListExtra.this.modCount;
public boolean hasNext() {
return cursor < ArrayListExtra.this.size();
}
public Object next() {
checkForComodification();
try {
Object next = get(cursor);
lastRet = cursor;
cursor = cursor + 2;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException("No existen mas elementos");
}
}
public void remove() {
if (lastRet == -1)
throw new IllegalStateException(
"El metodo next aun no ha sido llamado");
checkForComodification();
try {
ArrayListExtra.this.remove(lastRet);
cursor=lastRet;
lastRet=-1;
expectedModCount = ArrayListExtra.this.modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException(
"No existe el elemento a eliminar");
}
}
final void checkForComodification() {
if (ArrayListExtra.this.modCount != expectedModCount)
throw new ConcurrentModificationException(
"Se ha modificado la lista mientras se usaba este iterador");
}
}
/**
* Iterador CloneIterator: Permite devolver los elementos sin efectos, es
* decir se devuelven clones de los objetos almacenados, no los propios
* objetos
*/
private class CloneIterator implements Iterator {
/**
* Índice del elemento que va a ser devuelto
*/
int cursor = 0;
/**
* Índice del último elemento devuelto
*/
int lastRet = -1;
/**
* Contador de operaciones de cambio sobre la lista. Almacenamos el
* número de cambios de la lista la última vez que accedimos a ella. El
* campo modCount es heredado de AbstractList
*/
int expectedModCount = ArrayListExtra.this.modCount;
public boolean hasNext() {
return cursor < ArrayListExtra.this.size();
}
public Object next() {
checkForComodification();
try {
Object next = getClone(get(cursor));
lastRet = cursor;
cursor = cursor + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException("No existen mas elementos");
}
}
public void remove() {
if (lastRet == -1)
throw new IllegalStateException(
"El metodo next aun no ha sido llamado");
checkForComodification();
try {
ArrayListExtra.this.remove(lastRet);
cursor=lastRet;
lastRet=-1;
expectedModCount = ArrayListExtra.this.modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException(
"No existe el elemento a eliminar");
}
}
private Object getClone(Object o) {
Object clon = null;
try {
Method method = o.getClass().getMethod("clone", null);
clon = method.invoke(o, null);
} catch (IllegalAccessException ex1) {
throw new ClassCastException("El metodo clone no es publico ("
+ ex1.toString() + ")");
} catch (NoSuchMethodException ex2) {
throw new ClassCastException(
"El objeto no implementa la interfaz Cloneable ("
+ ex2.toString() + ")");
} catch (InvocationTargetException ex3) {
throw new ClassCastException(
"Error inesperado al llamar al metodo clone ("
+ ex3.toString() + ")");
}
return clon;
}
final void checkForComodification() {
if (ArrayListExtra.this.modCount != expectedModCount)
throw new ConcurrentModificationException(
"Se ha modificado la lista mientras se usaba este iterador");
}
}
// Iteradores
/**
* Devuelve un iterador sobre los elementos de la lista, del tipo
* especificado como parámetro de entrada
*/
public Iterator iterator(String type) throws NoSuchIteratorTypeException {
if (type.equals("CloneIterator"))
return new CloneIterator();
else if (type.equals("ParesIterator"))
return new ParesIterator();
else
throw new NoSuchIteratorTypeException(
"Tipo de iterador no soportado:" + type);
}
}
Me da un error y me dice que el objeto no implementa la interfaz cloneable. ¿Alguien puede decirme cómo solucionarlo?
Valora esta pregunta


0