Colecciones de Orden Superior en Java

28
Colecciones de Orden Superior en Java Por: Óscar López, M.Sc. Grupo GNU/Linux de la Universidad del Cauca

description

Librería que permite tener colecciones de orden superior en Java, tal como las que se encuentran en Smalltalk

Transcript of Colecciones de Orden Superior en Java

Page 1: Colecciones de Orden Superior en Java

Colecciones de Orden Superior en Java

Por: Óscar López, M.Sc.Grupo GNU/Linux de laUniversidad del Cauca

Page 2: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Agenda• Un ejercicio en ingeniería de lenguajes• Dos técnicas de programación

• Iteradores• Secuencias como interfaces convencionales

• Implementación en Smalltalk• ¿Y en Java, qué?

• Librería Higher Order Collections• Bloques en Java• Instanciación de colecciones• Métodos enumeradores

• Trabajo futuro• Bibliografía

Page 3: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Iteradores [4]

• Un patrón de diseño que permite acceder secuencialmente los elementos de un objeto agregado sin exponer su implementación interna

• Se clasifican como internos y externos, dependiendo de quién controla la iteración

• C++, Java, C# proporcionan iteradores polimórficos externos, Smalltalk dispone de iteradores internos

Page 4: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Ejemplo

List<Employee*>* employees;

Iterator<Employee*>* i;

i = employees->CreateIterator();

for (i.First();

!i.IsDone();

i.Next()) {

i.CurrentItem()->Print();

}

Page 5: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Secuencias ComoInterfaces Convencionales [3]• Definen un estilo particular para manipular

estructuras de datos• Un programa se concibe como datos

fluyendo a través de etapas de procesamiento

• Cada secuencia de datos expone una interfaz de operaciones convencionales para procesar sus elementos

• Similar en intención al patrón Visitor

Page 6: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Ejemplo

• Enumere las hojas de un árbol• Filtre, eligiendo las hojas impares• Calcule el cuadrado de las hojas elegidas• Acumule el valor de su sumatoria

Page 7: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Ejemplo

• Enumere los enteros de 0 hasta n• Calcule el número Fibonacci de cada uno• Filtre, seleccionando los pares• Acumule el resultado en una nueva lista

Page 8: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Ejemplo

(define (sum-odd-squares tree)(accumulate +

0(map sqr

(filter odd?(enumerate-tree tree)))))

(define (even-fibs n)(accumulate cons

‘()(filter even?

(map fibonacci(enumerate-interval 0 n)))))

Page 9: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Implementación en Smalltalk [5]

• Usa bloques: objetos de primera clase que encierran una función anónima y el contexto en el que ésta fue definida

• Todas las colecciones de objetos ofrecen una interfaz convencional que permite• Iterar sobre sus elementos• Realizar operaciones estándar sobre sus elementos

• Las operaciones están implementadas como funciones de orden superior que reciben un bloque como parámetro

• En Smalltalk, este conjunto de operaciones reciben el nombre de “métodos enumeradores”

Page 10: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Ejemplo

coll := #(1 2 3 4 5 6).

coll do: [ :e | Transcript show: e ].

coll collect: [ :e | e * e ].

coll detect: [ :e | e = 4 ].

coll select: [ :e | e < 4 ].

coll reject: [ :e | e < 4 ].

coll inject: 0 into: [ :subTotal :e | subTotal + e ].

Page 11: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Librería HigherOrderCollections

• Permite definir bloques en Java• Extiende las colecciones de Java,

adicionándoles métodos enumeradores como los de Smalltalk

• Disponible bajo licencia Apache 2.0 [7]• El artículo [1] profundiza en los detalles de

la implementación• El código fuente y la documentación se

pueden descargar en [2]

Page 12: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Librería HigherOrderCollections

Requerimientos e Instalación:

• Se debe tener instalado J2SE 1.5.0 ó superior• Incluir en el CLASSPATH el archivo higher-order-collections.jar

• Importar los siguientes paquetes:

import util.blocks.*;

import util.higherOrderCollections.*;

import static util.higherOrderCollections.HOCFactory.CollectionEnum.*;

Page 13: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Bloques en Java

• ¿Cómo implemento un bloque en Java?• ¿Cómo hago que sea seguro respecto a

tipos?Usando clases internas anónimas y tipos genéricos

• Existen numerosas implementaciones de bloques, se usó una versión modificada de “Blocks in Java” [6]

Page 14: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Bloques en Java• Procedimientos: Retornan void al evaluarlos

• Sin parámetros : ProcedureBlock• Con un parámetro (unario) : UnaryProcedureBlock• Con dos parámetros (binario) : BinaryProcedureBlock

• Predicados: Retornan un valor booleano al evaluarlos• Sin parámetros : PredicateBlock• Con un parámetro (unario) : UnaryPredicateBlock• Con dos parámetros (binario) : BinaryPredicateBlock

• Funciones: Retornan un tipo arbitrario al evaluarlos• Sin parámetros : FunctionBlock• Con un parámetro (unario) : UnaryFunctionBlock• Con dos parámetros (binario) : BinaryFunctionBlock

Page 15: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Ejemplo

final Integer uno = 1;

FunctionBlock<Integer> bloqueSuma;

bloqueSuma = new FunctionBlock<Integer>() {

public Integer value() {

return uno + uno; }};

bloqueSuma.value();

Page 16: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Instanciación de Colecciones• La forma más sencilla: usando la clase HOCFactory

HigherOrderCollection<Double> lista;

lista = HOCFactory.newInstance(LinkedList);

• HOCFactory proporciona adaptadores por defecto para las siguientes colecciones:

ArrayList, ConcurrentLinkedQueue, CopyOnWriteArrayList, CopyOnWriteArraySet, HashSet, LinkedBlockingQueue, LinkedHashSet, LinkedList, PriorityBlockingQueue, PriorityQueue, Stack, TreeSet y Vector

Page 17: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Instanciación de Colecciones• La forma más flexible: extendiendo la clase AbstractHigherOrderCollection

• Notar que el método getCollection()permite recuperar la colección usada internamente por la colección de orden superior:

HigherOrderCollection<Integer> col;

col = HOCFactory.newInstance(ArrayList);ArrayList<Integer> lista;lista = (ArrayList<Integer>)col.getCollection();

Page 18: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

void doBlock(UnaryProcedureBlock<E> aBlock)

Evalúa el bloque sobre cada uno de los elementos de la colección

coleccion.doBlock(new UnaryProcedureBlock<Integer>() {

public void value(Integer elemento) {

System.out.print(elemento + “ ”); }});

1 2 3 4 5 6

Page 19: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

int count(UnaryPredicateBlock<E> aBlock)

Retorna el número de elementos que al ser evaluados sobre el bloque hacen que éste retorne true

coleccion.count(new UnaryPredicateBlock<Integer>() {

public boolean value(Integer elemento) {

return elemento.intValue() % 2 == 0; }});

3

Page 20: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

E detect(UnaryPredicateBlock<E> aBlock)

Retorna el primer elemento que al ser evaluado sobre el bloque hace que éste retorne true

coleccion.detect(new UnaryPredicateBlock<Integer>() {

public boolean value(Integer elemento) {

return elemento == 4; }});

4

Page 21: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

E remove(UnaryPredicateBlock<E> aBlock)

Remueve de la colección y retorna el primer elemento que al ser evaluado sobre el bloque hace que éste retorne true

coleccion.remove(new UnaryPredicateBlock<Integer>() {

public boolean value(Integer elemento) {

return elemento == 5; }});

5

Page 22: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

HigherOrderCollection<E>

removeAll(UnaryPredicateBlock<E> aBlock)

Remueve de la colección todos los elementos que al ser evaluados sobre el bloque hacen que éste retorne true. Retorna una nueva colección con los elementos que fueron removidos

coleccion.removeAll(new UnaryPredicateBlock<Integer>() {

public boolean value(Integer elemento) {

return elemento.intValue() % 2 != 0; }});

1 3 5

Page 23: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

R inject(R thisValue,

BinaryFunctionBlock<R,E,R> binaryBlock)

Acumula y retorna el resultado de evaluar el bloque sobre cada uno de los elementos. El primer parámetro sirve como valor inicial del acumulador

coleccion.inject(0,

new BinaryFunctionBlock<Integer,Integer,Integer>() {

public Integer value(Integer acc, Integer elemento) {

return acc + elemento; }});

21

Page 24: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

HigherOrderCollection<R>

collect(UnaryFunctionBlock<E,R> aBlock)Evalúa el bloque sobre todos los elementos de la colección y va añadiendo cada valor retornado por el bloque a una nueva colección, que finalmente es retornada

coleccion.collect(

new UnaryFunctionBlock<Integer,Integer>() {

public Integer value(Integer elemento) {

return elemento * elemento; }});

1 4 9 16 25 36

Page 25: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

HigherOrderCollection<E>

select(UnaryPredicateBlock<E> aBlock)

Añade a una nueva colección los elementos que al ser evaluados sobre el bloque hacen que éste retorne true

coleccion.select(new UnaryPredicateBlock<Integer>() {

public boolean value(Integer elemento) {

return elemento < 4; }});

1 2 3

Page 26: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Métodos Enumeradores

HigherOrderCollection<E>

reject(UnaryPredicateBlock<E> aBlock)

Añade a una nueva colección los elementos que al ser evaluados sobre el bloque hacen que éste retorne false

coleccion.reject(new UnaryPredicateBlock<Integer>() {

public boolean value(Integer elemento) {

return elemento < 4; }});

4 5 6

Page 27: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Trabajo Futuro

• Definir métodos enumeradores sobre las clases que implementan la interfaz Map

• Agregar nuevos métodos enumeradores• Agregar nuevos bloques que soporten un

número variable de argumentos• Proporcionar un algoritmo de iteración

más eficiente para las colecciones que implementan la interfaz RandomAccess

• Incluir un script de Ant para compilar, probar y generar la documentación

Page 28: Colecciones de Orden Superior en Java

GLUC 2005 - GNU FDL

Bibliografía1. Artículo -

http://gluc.unicauca.edu.co/wiki/index.php/Colecciones_de_Orden_Superior_en_Java

2. Código Fuente -http://gluc.unicauca.edu.co/wiki/images/e/e5/Higher-order-collections.tar.bz2

3. Harold Abelson, Gerald Sussman y Julie Sussman. “Structure and Interpretation of Computer Programs”, 2da Edición. MIT Press, 1996.

4. E. Gamma, R. Helm, R. Johnson and J. Vlissides. “Design Patterns: Elements of Reusable Object Oriented Software”. Addison-Wesley, 1995.

5. Adele Goldberg, David Robson. “Smalltalk-80: The Language and Its Implementation” (El Libro Azul). Addison-Wesley, 1985.

6. Bloques en Java - http://c2.com/cgi/wiki?BlocksInJava7. Licencia Apache 2.0 - http://www.apache.org/licenses/LICENSE-

2.0