Você está na página 1de 105

Tema 0: Data Structures & Algorithms in Java (Temas: 1,2,3,4)

Tema 1: Introduccin Tema 2: rboles genricos Tema 3: Grafos Tema 4: Mapas y Diccionarios Tema 5: rboles de bsqueda Tema 6: ndices

Bloque 1

Bloque 2

Bloque 3

angel.sanchez@urjc.es jose.velez@urjc.es

abraham.duarte@urjc.es raul.cabido@urjc.es

Resumen
Repaso de las ED lineales ya conocidas
Invariantes de las ED, operaciones soportadas, complejidad de las mismas, posibles implementaciones

Implementacin en Java
Genericidad Collections

JUnit
Framework para la generacin de test

Objetivos
Dado un problema, identificar la estructura de datos ms adecuada Uso de las estructuras de datos disponibles en el framework Collections Definir casos de prueba JUnit para verificar de manera sistemtica el correcto funcionamiento de nuestro cdigo

Cualquier estructura que permite almacenar datos durante la ejecucin de un programa

Se puede hablar de:


ED dinmicas o estticas
Su uso de memoria puede cambiar (o no) durante la ejecucin de un programa

ED lineales o no lineales
Cada elemento tiene a lo sumo dos vecinos, uno que le precede y otro que le sigue. nicamente es posible un tipo de recorrido (en dos sentidos).

Operaciones sobre las estructuras de datos, dos tipos:


Consulta: search, minimum, maximum, sucessor, predecessor, Modificacin: insert, delete,

Es un modelo matemtico que permite definir un tipo de datos junto con las funciones que operan sobre l

La mayora de los actuales lenguajes de programacin permiten implementar TADs mediante el uso de clases
Las clases definen propiedades (representacin interna del TAD) y mtodos (operaciones soportadas por el TAD) Las instancias de un TAD son los objetos de una clase
LinkedList - head: Node - size: int + + + + + size():int isempty():bool add (index:int, value:E) remove(index:int):E get(index:int):E

Coleccin de elementos homogneos dispuestos en orden tal que se recuperan en orden inverso a como se introdujeron (poltica LIFO) Dos posibles implementaciones:
Mediante vectores: ArrayStack
0 2 push (9) 1 8 2 3 3 5 4 5 6 7 8 9

top = 4, MAX_SIZE = 10 0 2
0 2

1 8
1 8

2 3
2 3

3 5
3 5

4 9
4 9

top = 5, MAX_SIZE = 10 pop() 5 6 7 8 9

top = 4, MAX_SIZE = 10

Coleccin de elementos homogneos dispuestos en orden tal que se recuperan en orden inverso a como se introdujeron (poltica LIFO) Dos posibles implementaciones:
Mediante referencias: LinkedStack
top 5 top push (9) 9 top pop() 9 5 3 8 2 size = 5 3 8 2 size = 4

size = 4

Operaciones soportadas
size(), isEmpty() top() push(), pop()
Complejidad de cada operacin? Vara de una implementacin a otra?

Operacin
push(5) push(3) pop() push(7) pop() top() pop() pop()

Salida
3 7 5 5 Error

Stack
(5) (3,5) (5) (7,5) (5) (5) () ()

isEmpty()

true

()

Coleccin de elementos homogneos dispuestos en orden tal que se recuperan en igual orden a como se introdujeron (poltica FIFO) Dos posibles implementaciones:
Mediante vectores: ArrayQueue
0 3 dequeue () 1 7 2 11 3 2 4 7 5 3 6

head = 0, tail = 6, MAX_SIZE = 7 0 3


0 3

1 7
1 7

2 11
2 11

3 2
3 2

4 7
4 7

5 3
5 3

head = 1, tail = 6, MAX_SIZE = 7 enqueue (9) 6 9 head = 1, tail = 0, MAX_SIZE = 7

Coleccin de elementos homogneos dispuestos en orden tal que se recuperan en igual orden a como se introdujeron (poltica FIFO) Dos posibles implementaciones:
Mediante referencias: LinkedQueue
head tail

3
head dequeue () 3 head enqueue(9)

11

size = 6 tail

11

size = 5 tail

11

size = 6

Operaciones soportadas
size(), isEmpty() front(), back() enqueue(E e), dequeue()
Operacin
enqueue(5) enqueue(3) dequeue() enqueue(7)

Complejidad de cada operacin? Vara de una implementacin a otra? queue


(5) (3, 5) (3) (7,3)

Salida
5 -

dequeue()
front() dequeue()

3
7 7

(7)
(7) ()

Diferentes tipos:
Cola circular, con doble puntero a cabecera y final (dequeue), colas de prioridad (priorityqueue),

Coleccin de elementos homogneos dispuestos en orden


Cualquier elemento tiene un predecesor (excepto el primero) y un sucesor (excepto el ltimo)

Dos posibles implementaciones:


Mediante vectores: ArrayList
Ventajas: acceso directo O(1), insercin y borrado por cabecera O(1) Inconvenientes: insercin y borrado en otro caso O(n), capacidad fija

0 2 add( 9, 7) 0 2 0 2

1 8 1 8 1 9

2 3 2 3 2 8

3 5 3 5 3 3

4 6 4 6 4 5

5 7 5 7 5 6

6 9 6 9 6 7

7 2 7 2 7 9

head = 7 MAX_SIZE = 10

8 8 2

9 9
head = 8 MAX_SIZE = 10

Coleccin de elementos homogneos dispuestos en orden


Cualquier elemento tiene un predecesor (excepto el primero) y un sucesor (excepto el ltimo)

Dos posibles implementaciones:


Mediante referencias: DoubleLinkedList
Ventajas: insercin y borrado (principio y final) O(1) Inconvenientes: acceso secuencial O(n)

head

tail

Operaciones soportadas:
addFirst(E e), addLast(E e), add(E e, int index) removeFirst(), removeLast(), remove (int index) clear() Complejidad de cada operacin? isEmpty(), size() getFirst(), getLast(), get(int) contains (E e) Vara de una implementacin a otra?
Operacin
add(5) add(3) add(9) addLast(7) remove(3) contains(10) get(1) getLast() clear()

Salida
9 false 5 7 -

List
(5) (5,3) (5,3,9) (5,3,9,7) (5,3,7) (5,3,7) (5,3,7) (5,3,7) ()

Operaciones soportadas:
addFirst(E e), addLast(E e), add(E e, int index) removeFirst(), removeLast(), remove (int index) clear() Complejidad de cada operacin? isEmpty(), size() getFirst(), getLast(), get(int) contains (E e) Vara de una implementacin a otra?

Diferentes tipos de listas


Simplemente enlazadas, doblemente enlazadas, ordenadas, circulares, etc

Implementar en Java el TAD ListaFlotantes (FloatList)


Definir un conjunto de clases que permitan trabajar con los dos tipos de implementaciones vistas:
FloatArrayList FloatLinkedList

Tipo de lista: simple


Insercin y borrado por cabecera

Operaciones:
size(), isempty() add(), remove() get() search(), contains() head 3 7 1 2 7 0 3 1 7 2 11 3 2 4 7 5 3 6

head = 0, tail = 6, MAX_SIZE = 7

<<interface>> FloatList + + + + + + + + + + size():int isempty():boolean add(value:Float) add (index:int, value:Float) remove():Float remove(index:int):Float get():Float get(index:int):Float search(value:Float):int contains (value:Float):boolean

FloatNode 1 - next: FloatNode - element: Float + + + + setElement(e:Float) setNext (node:FloatNode) getElement():Float getNext():FloatNode 1

FloatLinkedList

FloatArrayList ???????

- head: FloatNode - size: int

Inconveniente: capacidad fija


+ + + + + + + + +

<<interface>> FloatList size():int isempty():bool add(value:Float) add (index:int, value:Float) remove():Float remove(index:int):Float get():Float get(index:int):Float search(value:Float):int

Solucin?

FloatNode 1 - next: Node - element: Float + + + + setElement(value:Float) 1 setNext (node:Node) getElement():Float getNext():Node

FloatLinkedList

FloatArrayList ???????

- head: Node - n: int

<<interface>> FloatList

Hemos realizado algn tipo de prueba que nos permita garantizar que el comportamiento de nuestra ED es el esperado?

+ + + + + + + + + +

size():int isempty():boolean add(value:Float) add (index:int, value:Float) remove():Float remove(index:int):Float get():Float get(index:int):Float search(value:Float):int contains (value:Float):boolean

FloatNode 1 - next: FloatNode - element: Float + + + + setElement(e:Float) setNext (node:FloatNode) getElement():Float getNext():FloatNode 1

FloatLinkedList

FloatArrayList ???????

- head: FloatNode - size: int

Cmo compruebo el correcto funcionamiento de una clase en Java?


Mediante un programa principal main?
Mayor interfaz de la clase, mayor ser mi programa principal Fallo en la ejecucin de mi programa:
La ejecucin para en el primer fallo Qu mtodo fallo realmente? El resto funcionan como esperaba?, tambin estn fallando?

Qu % de mi cdigo cubre mi programa principal de prueba?

Pruebas unitarias
Permiten validar los componentes (mdulos) de un sistema por separado En OO se realizan pruebas a nivel de clase
Habitualmente, una prueba unitaria comprueba el correcto funcionamiento de un mtodo en un contexto determinado

Diferentes herramientas que automatizan su ejecucin

Actionscript (FlexUnit) Ada (AUnit) C (CUnit) C# (NUnit) C++ (CPPUnit) Fortran (fUnit) Delphi (DUnit) Free Pascal (FPCUnit)

JavaScript (JSUnit) Objective-C (OCUnit) Perl (Test::Class y Test::Unit) PHP (PHPUnit) Python (PyUnit) R (RUnit) Haskell (HUnit) Qt (QTestLib)

Framework que permite definir y ejecutar pruebas unitarias en Java


Desarrollado por Erich Gamma y Kent Beck

Se basa en el uso de aserciones (assert) para caracterizar los resultados de la prueba

El framework reside bajo los paquetes:


junit.framework para JUnit 3.8 y anteriores org.junit para JUnit 4 en adelante

Integrado en diferentes IDEs

Definir un conjunto de pruebas unitarias que permitan comprobar el correcto comportamiento de la ED FloatArrayList

public class FloatArrayListTest { @Test public void testSize() {} @Test public void testIsEmpty() {} @Test public void testAddFloat() {} @Test public void testAddIntFloat() {} }

public class FloatArrayListTest { @Test public void testSize() {} @Test public void testIsEmpty() {} @Test public void testAddFloat() {} @Test public void testAddIntFloat() {} }

Test mediante uso de aserciones


@Test public void testAddFloat() { final int SIZE = 100; FloatArrayList list = new FloatArrayList(SIZE); list.add(new Float(3.0)); list.add(new Float(4.0)); list.add(new Float(5.0)); assertEquals(5.0, list.get().floatValue(), 0.0); list.remove(); assertEquals(4.0, list.get().floatValue(), 0.0); list.remove(); assertEquals(3.0, list.get().floatValue(), 0.0); }

Test mediante uso de aserciones


assertXXX (mensaje,
Assert

valor_esperado,

valor_obtenido)

Comprueba que

assertTrue(msg, b) assertFalse(msg, b) assertEquals(msg,v1,v2)


assertEquals(msg,v1,v2,e) assertNull(msg,obj) assertNotNull(msg, obj) assertSame(msg, o1, o2) assertNotSame(msg, o1, o2) fail(msg)

b es cierto b es falso v1=v2


|v1-v2|<=e obj es null Obj no es null O1 y o2 son el mismo objeto O1 y o2 no son el mismo objeto falla siempre

http://junit.sourceforge.net/javadoc/org/junit/Assert.html

Test para excepciones


Cmo verificar que se lanzan las excepciones esperadas? @Test (expected = ExceptionName.class)

@Test(expected=FullArrayException.class) public void testFullArrayException() { final int SIZE = 10; FloatArrayList list = new FloatArrayList(SIZE);

for (int i = 0; i <= SIZE; i++) { list.add(new Float(i)); }


} http://junit.sourceforge.net/javadoc/org/junit/Assert.html

Test fixtures
Estado fijo empleado como base para correr los test Ventajas
Permiten separar la contruccin (y destruccin) de un estado inicial del cdigo propio del test Reutilizar un estado inicial para ms de un test (evitamos replicar cdigo)

@Test public void testSize() { final int SIZE = 100; FloatArrayList list = new FloatArrayList(SIZE); } @Test public void testIsEmpty() { final int SIZE = 100; FloatArrayList list = new FloatArrayList(SIZE);

Test fixtures
Para crear un estado inicial
Declarar como atributos aquellos objetos que conformarn el estado inicial Inicializarlos en un mtodo anotado con @Before

public class FloatArrayListTest{ private FloatArrayList list; private static final int SIZE = 100; @Before public void setUp() { list = new FloatArrayList(SIZE); }

Test fixtures
Para crear un estado inicial
Orden de ejecucin

setup(); testSize(); setup(); testIsEmpty (); setup(); testAddFloat();

public class FloatArrayListTest{ private FloatArrayList list; private static final int SIZE = 100; @Before public void setUp() { list = new FloatArrayList(SIZE); }

Test fixtures
Si el mtodo anotado como @Before reserva recursos externos, stos deben liberarse en su equivalente @After
public class OutputTest { private File output; @Before public void setup() { output = new File(...); } @After public void tearDown() { output.delete(); }

Test fixtures

setup(); Si el mtodo anotado como @Before reserva recursos testSize(); tearDown(); externos, stos deben liberarse en su equivalente @After setup(); testIsEmpty (); tearDown(); public class OutputTest { private File output; @Before public void setup() { output = new File(...); } @After public void tearDown() { output.delete(); }

Ms documentacin en
http://junit.sourceforge.net/

Algunos enlaces de inters


JUnit Cookbook
http://junit.sourceforge.net/doc/cookbook/cookbook.htm

Javadoc
http://kentbeck.github.com/junit/javadoc/latest/

FAQs
http://junit.sourceforge.net/doc/faq/faq.htm

JUnit in Eclipse
http://www.eclipse.org/resources/resource.php?id=408

Si queremos crear una Lista de Imgenes?


Solucin: crear otra jerarqua cambiando Float por Image?

<<interface>> FloatList + + + + + + + + + + size():int isempty():bool add(value:Float) add (index:int, value:Float) remove():Float remove(index:int):Float get():Float get(index:int):Float search(value:Float):int contains (value:Float):bool

Replicar cdigo nunca fue una buena idea

FloatNode 1 - next: Node - element: Float + + + + setElement(value:Float) 1 setNext (node:Node) getElement():Float getNext():Node

FloatLinkedList

FloatArrayList ???????

- head: Node - n: int

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Los genricos son un mecanismo utilizado en los lenguajes de programacin con tipado esttico para especificar el tipo de los elementos de una estructura de datos En C++ se les denomina plantillas (templates) Aparte de las estructuras de datos, tambin puede utilizarse en otros contextos

Los genricos se incorporaron en Java 5

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Clase pila de fracciones implementada con un array

class PilaFracciones { private Fraccion[] elementos; private int numElementos; public PilaFracciones(int tope) { this.elementos = new Fraccion[tope]; this.setNumElementos(0); } public Fraccion getElemento(int indice) { return this.elementos[indice]; } public void addElemento(Fraccion fraccion) { if(numElementos < elementos.length){ this.elementos[numElementos] = fraccion; numElementos++; } } ... }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

public static void main(String[] args) {

Uso de la clase pila de fracciones

PilaFracciones pila = new PilaFracciones(5); Fraccion fraccion1 = new Fraccion(1,2); Fraccion fraccion2 = new Fraccion(1,3); Fraccion fraccion3 = new Fraccion(1,4); pila.addElemento(fraccion1); pila.addElemento(fraccion2); pila.addElemento(fraccion3); ... }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

class PilaIntervalos {

Si queremos implementar pila de Intervalos? Creamos otra clase cambiando Fraccin por Intervalo? Duplicar cdigo es malo

private Intervalo[] elementos; private int numElementos; public PilaIntervalos(int tope) { this.elementos = new Intervalo[tope]; this.setNumElementos(0); } public Intervalo getElemento(int indice) { return this.elementos[indice]; } public void addElemento(Intervalo intervalo) { if(numElementos < elementos.length){ this.elementos[numElementos] = intervalo; numElementos++; } } ... }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

public static void main(String[] args) {

Uso de la clase pila de intervalos

PilaIntervalos pila = new PilaIntervalos(5); Intervalo intervalo1 = new Intervalo(1,2); Intervalo intervalo2 = new Intervalo(1,3); Intervalo intervalo3 = new Intervalo(1,4); pila.addElemento(intervalo1); pila.addElemento(intervalo2); pila.addElemento(intervalo3); ... }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

class PilaObjects {

Si queremos implementar pila de Intervalos? Podemos usar polimorfismo Hacemos que los elementos sean de tipo Object?
}

private Object[] elementos; private int numElementos;


public PilaObjects(int tope) { this.elementos = new Object[tope]; this.setNumElementos(0); } public Object getElemento(int indice) { return this.elementos[indice]; } public void addElemento(Object object) { if(numElementos < elementos.length){ this.elementos[numElementos] = object; numElementos++; } } ...

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Usar Object funciona Pero el compilador no nos ayuda Se puede escribir cdigo incorrecto
//Queremos que la pila contenga Intervalos PilaObjects pila = new PilaObjects(5); pila.addElemento(new Intervalo(2,4)); pila.addElemento(new Intervalo(2,6)); //Nos equivocamos y el compilador no da error //No se genera una excepcin en ejecucin pila.addElemento(new Fraccion(1,2)); //Siempre que sacamos intervalos tenemos //que hacer cast. Puede generar una excepcin Intervalo intervalo = (Intervalo) pila.getElemento()

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Lo ideal sera definir el tipo de los elementos cuando se usa la pila, no cuando se implementa la pila
public static void main(String[] args) { PilaIntervalo pilaIntervalo; PilaFraccion pilaFraccion; ...

A partir de Java 5 se puede implementar la pila con elementos genricos, sin definir su tipo El tipo se define cuando se usa la pila
Al declarar una variable Al instanciar un objeto pila

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

class PilaIntervalos {
public PilaIntervalos(int tope) { ... } public Intervalo getElemento(int indice) { ... } public void addElemento(Intervalo intervalo) { ... } }

class Pila<E> {
public Pila(int tope) { ... } public E getElemento(int indice) { ... } public void addElemento(E elem) { ... } ... }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

//Queremos que la pila contenga Intervalos PilaIntervalos pilaIntervalos = new PilaIntervalos(5);

Sin usar genricos

Intervalo i1 = new Intervalo(2,4); Intervalo i2 = new Intervalo(2,6); pilaIntervalos.addElemento(i1); pilaIntervalos.addElemento(i2); Intervalo i3 = pilaIntervalos.getElemento(1); //Queremos que la pila contenga Intervalos Pila<Intervalo> pilaIntervalos = new Pila<Intervalo>(5);

Usando genricos

Intervalo i1 = new Intervalo(2,4); Intervalo i2 = new Intervalo(2,6); pilaIntervalos.addElemento(i1); pilaIntervalos.addElemento(i2); Intervalo i3 = pilaIntervalos.getElemento(1)

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Sin usar genricos

PilaIntervalos pilaIntervalos = new PilaIntervalos(5); PilaFracciones pilaFracciones = new PilaFracciones(5); Intervalo i3 = pilaIntervalos.getElemento(1); Fraccion fraccion = pilaFracciones.getElemento(1);

Pila<Intervalo> pilaIntervalos = new Pila<Intervalo>(5); Pila<Fraccion> pilaFracciones = new Pila<Fraccion>(5);

Usando genricos

Intervalo intervalo = pilaIntervalos.getElemento(1); Fraccion fraccion = pilaFracciones.getElemento(1);

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

En Java 7 se ha simplificado la creacin de objetos genricos Antes de Java 7 En Java 7


Pila<Intervalo> pilaIntervalos = new Pila<Intervalo>(5); Pila<Fraccion> pilaFracciones = new Pila<Fraccion>(5);

Pila<Intervalo> pilaIntervalos = new Pila<>(5); Pila<Fraccion> pilaFracciones = new Pila<>(5);

El tipo de los elementos se infiere de la declaracin de la variable y se puede omitir de la construccin del objeto

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Micael Gallego Carrillo

Francisco Gortzar Bellas

Gracias al grupo sidelab por sta introduccin a genricos!

Si queremos crear una Lista de Imgenes?


Solucin: crear otra jerarqua cambiando Float por Image?

<<interface>> FloatList + + + + + + + + + + size():int isempty():boolean add(value:Float) add (index:int, value:Float) remove():Float remove(index:int):Float get():Float get(index:int):Float search(value:Float):int contains (value:Float):boolean

Solucin: utilizar genricos

FloatNode 1 - next: FloatNode - element: Float + + + + setElement(e:Float) setNext (node:FloatNode) getElement():Float getNext():FloatNode 1

FloatLinkedList

FloatArrayList ???????

- head: FloatNode - size: int

Si queremos crear una Lista de Imgenes?


Solucin: crear otra jerarqua cambiando Float por Image?

<<interface>> List + + + + + + + + + + size():int isempty():boolean add(value:E) add (index:int, value:E) remove():E remove(index:int):E get():E get(index:int):E search(value:E):int contains (value:E):boolean

Solucin: utilizar genricos

Node 1 - next: Node<E> - element: E + + + +

E E E

LinkedList 1

ArrayList ???????

setElement(e:E) setNext (node:Node<E>) getElement():E getNext():Node<E>

- head: Node<E> - size: int

Formas de recorrer una coleccin de elementos


Usando un bucle for con acceso por posicin

Usando iteradores
Usando el for mejorado

Usando un bucle for con acceso por posicin


List<String> ciudades = new ArrayList<String>(); ciudades.add("Ciudad Real"); ciudades.add("Madrid"); ciudades.add("Valencia");

for (int i=0; i < ciudades.size(); i++) { String ciudad = ciudades.get(i); System.out.println(ciudad + "\n"); }

No se recomienda, especialmente en ED donde el acceso a los elementos no es directo


Ejemplo: LinkedList<String>
Recorrido: O(n^2)

Usandoiteradores? Iterador
Patrn de diseo software que abstrae el recorrido de una coleccin elemento a elemento Encapsula el concepto de posicin actual y elemento siguiente dentro de una coleccin
Proporciona una forma general de acceder a los elementos de una coleccin (independientemente de su organizacin interna)
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }

Usando iteradores

public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }

List<String> ciudades = new ArrayList<String>(); ciudades.add("Ciudad Real"); ciudades.add("Madrid"); ciudades.add("Valencia"); Iterator<String> it = ciudades.iterator(); while (it.hasNext()){ String s = it.next(); System.out.println(s + "\n"); }

Proporciona una forma general de acceder a los elementos de una coleccin (independientemente de su organizacin interna)

Usando iteradores

public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }

List<String> ciudades = new LinkedList<String>(); ciudades.add("Ciudad Real"); ciudades.add("Madrid"); ciudades.add("Valencia"); Iterator<String> it = ciudades.iterator(); while (it.hasNext()){ String s = it.next(); System.out.println(s + "\n"); }

Proporciona una forma general de acceder a los elementos de una coleccin (independientemente de su organizacin interna)

Usando iteradores

public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }

HashSet<String> ciudades = new HashSet<String>(); ciudades.add("Ciudad Real"); ciudades.add("Madrid"); ciudades.add("Valencia"); Iterator<String> it = ciudades.iterator(); while (it.hasNext()){ String s = it.next(); System.out.println(s + "\n"); }

Proporciona una forma general de acceder a los elementos de una coleccin (independientemente de su organizacin interna)

for mejorado de Java

public interface Iterator<E> { boolean hasNext(); E next(); void remove(); }

Internamente usa un iterador (forma preferida)


HashSet<String> ciudades = new HashSet<String>(); ciudades.add("Ciudad Real"); ciudades.add("Madrid"); ciudades.add("Valencia"); Iterator<String> it = ciudades.iterator(); while (it.hasNext()){ String s = it.next(); System.out.println(s + "\n"); for (String ciudad: ciudades) { } System.out.println(ciudad + "\n"); }

Requisito: la coleccin debe implementar la interfaz Iterable

<<interface>> Iterable

<<interface>> Iterator

E
<<interface>> List + iterator(): Iterator<E>

+ hasNext ():boolean + next(): E + remove()

E
ArrayListIterator

E
LinkedListIterator LinkedList

E
ArrayList

Consejo: Iteradores como nested classes

Operaciones de actualizacin en una lista enlazada


Manera de indicar dnde se realiza ndice
add(int index, E value) acceso secuencial remove (int index) acceso secuencial O(n) List<String> ciudades = new LinkedList<String>(); ciudades.add(i, "Madrid"); O(n) List<String> ciudades = new LinkedList<String>(); ciudades.remove(i);

Operaciones de actualizacin en una lista enlazada


Manera de indicar dnde se realiza ndice
add(int index, E value) acceso secuencial remove (int index) acceso secuencial O(n) List<String> ciudades = new LinkedList<String>(); ciudades.add(i, "Madrid"); O(n) List<String> ciudades = new LinkedList<String>(); ciudades.remove(i);

Alguna solucin?

Operaciones de actualizacin en una lista enlazada


En una lista enlazada, parece ms natural (y eficiente) utilizar referencias a nodo en lugar de ndices para indicar donde realizar la operacin de actualizacin
head 3 p ndice O(n) list.add(2, 123) list.add(2, 123) list.remove (2) 5 q 8 r Referencia O(1) list.addBefore(r, 123) list.addAfter(q, 123) list.remove (r) 6 s

Operaciones de actualizacin en una lista enlazada


En una lista enlazada, parece ms natural (y eficiente) utilizar referencias a nodo en lugar de ndices para indicar donde realizar la operacin de actualizacin
//void add(int index, E value) Node<E> addBefore (Node<E> node, E value); Node<E> addAfter (Node<E> node, E value); //E remove (int index) E remove (Node<E> node)

Problema
Exponemos la representacin interna de la lista al usuario (desencapsulacin) El usuario podra romper las invariantes de la ED
A travs de las referencias a nodo podra modificar la estructura interna de la lista, sin nuestro conocimiento

Operaciones de actualizacin en una lista enlazada


Solucin:
Devolver nodos en modo lectura: Position
//void add(int index, E value) Node<E> addBefore (Node<E> node, E value); Node<E> addAfter (Node<E> node, E value);
E

<<interface>> Position
+ getValue():E

//E remove (int index) E remove (Node<E> node)

Node

//void add(int index, E value) Position<E> addBefore (Position<E> pos, E value); Position<E> addAfter (Position<E> pos, E value);

- next: Node<E> - value: E

//E remove (int index) E remove (Position<E> pos)

+ + + +

setElement(value:E) setNext(node:Node<E>) getElement():E getNext():Node<E>

<<interface>> Position
+ getElement():E

<<interface>> Iterable

E LinkedPositionList DLinkedNode 1
- next: DLinkedNodE<E> - prev: DLinkedNode<E> - element: E + + + + + + setElement(e:E) setNext (node:DLinkedNode) setPrev (node:DLinkedNode) getElement():E getNext(): DLinkedNode getPrev(): DLinkedNode

E
+ + + + + + + + + + + + size(): int isEmpty(): boolean add(element:E): Position<E> addAfter(pos:Position<E>, element:E):Position<E> addBefore(pos:Position<E>,element:E):Position<E> remove(pos: Position<E>):E get(): Position<E> set(pos: Position<E>, element: E):E search(element: E): Position<E> contains(element: E): boolean iterator(): Iterator<E> toString(): String

Operaciones como remove y addBefore requieren que la lista sea doblemente enlazada

Operacin de actualizacin addBefore


public Position<E> addBefore(Position<E> pos, E element) { DLinkedNode<E> nextNode = (DLinkedNode<E>) pos; DLinkedNode<E> newNode = new DLinkedNode<E>(element, nextNode, nextNode.getPrev()); if (this.head==nextNode){ this.head = newNode; } else{ nextNode.getPrev().setNext(newNode); } nextNode.setPrev(newNode); this.size++; return (Position<E>) newNode; }
E
<<interface>> Position
+ getElement():E

DLinkedNode
- next: DLinkedNodE<E> - prev: DLinkedNode<E> - element: E + + + + + + setElement(e:E) setNext (DLinkedNode :E) setPrev (DLinkedNode :E) getElement():E getNext(): DLinkedNode getPrev(): DLinkedNode

Y si pos no es una posicin vlida?

Operacin de actualizacin addBefore


public Position<E> addBefore(Position<E> pos,E element) throws InvalidPositionException{ DLinkedNode<E> nextNode = this.checkPosition(pos); DLinkedNode<E> newNode = new DLinkedNode<E>(element, nextNode, nextNode.getPrev()); if (this.head==nextNode){ this.head = newNode; } else{ nextNode.getPrev().setNext(newNode); } nextNode.setPrev(newNode); this.size++; return (Position<E>) newNode; }
E
<<interface>> Position
+ getElement():E

DLinkedNode
- next: DLinkedNodE<E> - prev: DLinkedNode<E> - element: E + + + + + + setElement(e:E) setNext (DLinkedNode :E) setPrev (DLinkedNode :E) getElement():E getNext(): DLinkedNode getPrev(): DLinkedNode

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

A las estructuras de datos en Java se las denomina colecciones

Colecciones: objetos que mantienen una coleccin de elementos, independientemente de su estructura interna
Framework Collections
Arquitectura unificada para representar y manejar colecciones Separa la parte pblica (interfaz) de los detalles de implementacin internos Se conforma de interfaces, implementaciones y algoritmos

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Interfaces:
Permiten que las colecciones puedan manipularse independientemente de los detalles de implementacin
T max(Collection<? extends T> coll){} void reverse(List<?> list){}

Definen la funcionalidad, no cmo debe implementarse esa funcionalidad

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Implementaciones:
Clases que implementan los interfaces que definen los tipos de colecciones (listas, mapas y conjuntos)

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Algoritmos
Mtodos que realizan algn cmputo concreto sobre colecciones de elementos Se dice que son polimrficos
Mismo mtodo puede utilizarse con diferentes implementaciones de una coleccin

java.util.Collections
Bsqueda, ordenacin, etc.
T max(Collection<? extends T> coll){} void reverse(List<?> list){}

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Core collection interfaces


Encapsula diferentes tipos de colecciones

Insistimos: stas interfaces permiten a las colecciones ser manipuladas independientemente de sus detalles de implementacin

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Iterable<T>
Representa la expresin mnima de una coleccin de elementos Slo permite recorrer los elementos
No permite consultar cuantos son No permite aadir elementos

public static void print (Iterable<?> iterableCollection){ Iterator<?> it = iterableCollection.iterator(); while (it.hasNext()){ System.out.println(it.next().toString()); } }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Collection<E>
Representa a una coleccin de objetos Aade nueva funcionalidad:
Consultar vaca Consultar nmero de elementos Aadir elemento/s

Clase padre de las colecciones con acceso por posicin y de forma secuencial Dependiendo de las interfaces hijas
Hay colecciones que permiten elementos duplicados y otras no Hay colecciones ordenadas o desordenadas Hay colecciones que permiten el valor null, otras no

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Algunos mtodos de Collection<E>


Para agregar y eliminar elementos
boolean add(E e) boolean remove(Object o)

Para realizar consultas


int size() boolean isEmpty() boolean contains(Object o)

Para realizar varias operaciones de forma simultnea


boolean containsAll(Collection<?> collection) void clear() boolean removeAll(Collection<?> collection)

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Set<E>
Coleccin que no mantiene el orden de insercin y que no puede tener dos o ms objetos iguales

List<E>
Coleccin que s mantiene el orden de insercin y que puede contener elementos duplicados

Queue<E>
Coleccin para almacenar mltiples elementos antes de ser procesados
Elementos ordenados bajo un criterio FIFO
Excepciones: colas de prioridad

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Map<K,V>
Estructura que guarda los elementos (valores) asociados a una clave

SortedSet<E>
Conjunto que mantiene todos los elementos ordenados
Orden ascendente

SortedMap<K,V>
Mapa que mantiene sus claves ordenadas
Orden ascendente

Los mapas se vern en profundidad en temas posteriores

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

El framework Collections proporciona implementaciones de propsito general para las interfaces presentadas

Ms comunmente utilizadas
Set<E> HashSet<E> List<E> ArrayList<E> Map<K,V> HashMap<K,V> SortedSet<E> TreeSet<E> SortedMap<K,V> TreeMap<K,V> Queue<E>
LinkedList<E>: Cola FIFO PriorityQueue<E>: Ordena sus elementos antes de ser procesados

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Coleccin que mantiene el orden de insercin y que puede contener elementos duplicados

Similar a un array pero que crece de forma dinmica


Se accede a los elementos indicando su posicin (tipo int) Algunos mtodos:
void add(int index, E element) boolean addAll(int index, Collection<? extends E> c) E get(int index) E remove(int index)

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Es la estructura de datos ms usada Es la estructura de datos ms eficiente para la insercin de elementos (al final) No obstante, no es muy eficiente para bsquedas (porque son secuenciales)

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Interfaces vs. Implementaciones


Las variables, parmetros y atributos se declaran con el tipo de las interfaces La clase de implementacin slo se usa para instanciar los objetos Se abstrae lo ms posible de la implementacin concreta (y se puede cambiar fcilmente en el futuro)
ArrayList<E> es la clase por defecto que implementa List<E> List<Intervalo> listaIntervalos = new ArrayList<Intervalo>(); List<Fraccion> listaFracciones = new ArrayList<Fraccion>(); listaIntervalos.add(new Intervalo(2,4)); listaFracciones.add(new Fraccion(2,6)); Intervalo intervalo = listaIntervalos.get(0); Fraccion fraccion = listaFracciones.get(0);

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

No mantiene el orden de insercin No es posible recuperar los elementos en el orden en que fueron insertados No admite elementos duplicados
Si se aade un objeto al conjunto y ya haba otro igual, no se produce ningn cambio en la estructura

Es la estructura de datos ms eficiente buscando elementos

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

HashSet<E> es la implementacin por defecto de Set<E> y se implementa utilizando una tabla hash
Tiempo constante para la mayor parte de sus operaciones
add(), remove(), contains() y size()

No mantiene orden de insercin


//Declaro la variable del tipo de la interfaz, //y le asigno un objeto del tipo de la clase de //implementacin. Set<Intervalo> intervalos = new HashSet<Intervalo>(); Intervalo intervalo = new Intervalo(2,4); intervalos.add(intervalo); //Esta insercin no tiene efecto intervalos.add(intervalo); int numIntervalos = intervalos.size(); // Devuelve 1

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Define una estructura de datos que asocia o mapea claves con valores
<idContacto, telfono> <palabra, significado> <ciudad, litros de agua>

No permite claves repetidas


Varias claves distintas pueden estar asociadas al mismo valor

La bsqueda de un valor asociado a una clave es muy eficiente


Tiempo constante
Mapas se vern con detalle en temas posteriores

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Algunos mtodos:
V put(K key, V value) : insertar un valor asociado a la clave V get(Object key) : obtener un valor asociado a la clave Collection<V> values() : devuelve la coleccin de valores Set<K> keySet(): devuelve el conjunto de claves Entry<K,V> entrySet(): devuelve el conjunto de pares clave-valor (entradas del mapa)

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

HashMap<K,V> es la implementacin por defecto de Map<K,V> que implementa el conjunto de datos utilizando una tabla hash
Map<String, Coche> propietarios = new HashMap<String, Coche>(5); Coche toledo = new Coche("Seat", "Toledo", 110) Coche punto = new Coche("Fiat", "Punto", 90); propietarios.put("M-1233-YYY", toledo); propietarios.put("M-1234-ZZZ", punto); Coche c = propietarios.get("M-1234-ZZZ");

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Cuando los elementos son comparables entre s, puede ser til insertar de forma ordenada los elementos
SortedSet<E>, SortedMap<E>

Un objeto es comparable si:


Implementa la interfaz Comparable<T> orden natural Y si quiero ordenar en base a otro criterio que no sea el marcado como orden natural?
Proporcionar un Comparator<T>

Lectura obligada: http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

SortedSet<E>
Ordena los elementos de manera ascendente Permite realizar consultas basadas en rango
Dado un texto, dame las palabras que empiecen por de. Mustralas ordenadas de manera ascendente.

Implementacin TreeSet<E>
add(), remove(), contains() O(log n)

SortedMap<K,V>
Ordena las claves de forma ascendente Permite realizar consultas basadas en rango
Comit olmpico: ciudades con nota mayor a 6 (<nota, ciudades>)

Implementacin TreeMap<E>
containsKey(), get(), put(), remove() O(log n)

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Aparte de las implementaciones por defecto, existen otras implementaciones para situaciones especiales
De propsito general De propsito especfico Para soporte de concurrencia Combinadas Wrappers etc

Ms info: http://docs.oracle.com/javase/tutorial/collections/implementations/index.html

Se pide implementar el mtodo parejas en Java:


public static void parejas(ArrayList<Integer> array, Integer m){ }

Dicho mtodo recibe un array de N enteros (array) y muestra por pantalla todos los pares cuya suma sea igual a un valor m. La complejidad del mtodo desarrollado deber ser O(n). Como ejemplo, dado un vector de entrada [1 3 12 23 1 2 2], y tomando m valor 4, la salida obtenida debera ser: {1, 3} {3,1}, {2,2}

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Hay tres posibles formas de recorrer una coleccin


Usando un bucle for con acceso por posicin Usando los iteradores (Iterator<E>) de forma secuencial Usando el for mejorado

List<String> ciudades = new ArrayList<String>(); ciudades.add("Ciudad Real"); ciudades.add("Madrid"); ciudades.add("Valencia"); for (String ciudad: ciudades) { System.out.println(ciudad + "\n"); }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Existen clases que se comportan como los tipos primitivos (clases de envoltura, wrapper)
Integer, Double, Float, Boolean, Character...

El autoboxing y autounboxing es la capacidad de conversin automtica entre un valor de un tipo primitivo y un objeto de la clase correspondiente
int numero = 3; Integer numObj = numero; int otroNum = numObj;

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Esto permite usar las colecciones con tipos primitivos

Hay que ser consciente de que se tienen que realizar conversiones y eso es costoso

List<Integer> enteros = new ArrayList<Integer>(); enteros.add(3); enteros.add(5); enteros.add(10);

int num = enteros.get(0);

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Existen implementaciones de terceros con estructuras de datos especialmente diseadas para tipos primitivos Deben usarse cuando se utilizan mucho en un programa y las conversiones sean muy numerosas
http://trove4j.sourceforge.net/ http://fastutil.dsi.unimi.it/ http://commons.apache.org/primitives/

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

java.util.Collections Coleccin de algoritmos polimrficos


Mtodos estticos
Primer argumento: coleccin sobre la que operar

La mayora trabajan sobre instancias de List y Collection

Clasificacin
Sorting Shuffling Data manipulation Searching Composition Finding extreme values

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Sorting
Reordena la lista en orden ascendente
En base a su orden natural Comparable<E>

List<String> nombres = new ArrayList<String>(); nombres.add("Pepe"); nombres.add("Juan"); nombres.add("Antonio"); Collections.sort(nombres); System.out.println(nombres);

nombres = [Antonio, Juan, Pepe]

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Sorting
Reordena la lista en orden ascendente
En base a su orden natural Comparable<E> En base a un criterio diferente Comparator<E> List<String> nombres = new ArrayList<String>(); nombres.add("Juanin"); nombres.add("Pepe"); nombres.add("Antonio"); Collections.sort(nombres, new Comparator<String>(){ public int compare(String o1, String o2) { return o1.length() - o2.length(); } });

nombres = [Pepe, Juanin, Antonio]

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Shuffling
suffle: reordena los elementos de una lista de forma aleatoria

Routine data manipulation


reverse: invierte orden de los elementos en una lista fill: cada elemento se sustituye por el elemento especificado copy: copia los elementos de una lista origen en una lista destino swap: intercambio de elementos en las posiciones especificadas de una lista addAll: aade los elementos especificados a una coleccin

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Searching
La forma ms eficiente de saber si un elemento est o no en una estructura de datos es usar un Set o un Map Si usamos listas
Si la lista est desordenada, usamos el mtodo indexOf(E e) Si la lista est ordenada, se puede usar una bsqueda binaria
Si el elemento est en la lista, devuelve su posicin Si el elemento no est en la lista, devuelve el lugar en el que debera estar

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Searching
List<String> nombres = new ArrayList<String>(); nombres.add("Pepe"); nombres.add("Juan"); nombres.add("Antonio");
Collections.sort(nombres); //int pos = nombres.indexOf("Mario"); int pos = Collections.binarySearch(nombres, "Mario"); if (pos < 0){ //El nombre no est en la lista int insertPos = -pos-1; System.out.println("No est. Debera estar en: "+insertPos); } else { System.out.println("Est en la posicin: "+pos); }

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Composition
frequency: nmero de veces que aparece un determinado elemento dentro
de una coleccin

disjoint: determina si dos colecciones son disjuntas (ningn elemento en


comn)

Finding Extreme Values


min max

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Reduccin del esfuerzo del programador Incremento de la velocidad y calidad Interoperabilidad entre APIs no relacionadas Menor esfuerzo de aprendizaje y uso de otras APIs Fomenta la reutilizacin del software

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Aunque las estructuras de datos de la API son muy completas, existen libreras de terceros que las complementan
Google Guava:
http://code.google.com/p/guava-libraries/

Otras:
http://java-source.net/open-source/collection-libraries

Autora: Micael Gallego Carrillo y Francisco Gortzar Bellas

Implementar el juego del Bingo en Java


Definir las clases necesarias para ello
Jugador, Partida, Bombo, Cartn
Un jugador puede comprar ms de un cartn Inicialmente se juega para lnea. Un vez cantada jugaremos para bingo Premio por partida: 50% del dinero recaudado
(precio_del_cartn x num_cartones_vendidos)*0.5

Elegir las ED adecuadas para:


Cartn Jugador Bombo

Criterio?
Eficiencia en tiempo