style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Las magias de groovy y las colecciones de Java

Bueno, hoy experimentando con el tan aclamado lenguaje para la
JVM (porqué estoy terminando el desarrollo de una aplicación web
con Play 1.2.3, y recordemos que el sistema de templates es groovy),
me vi abocado a manejar una lista desde las vistas. El punto es que
yo necesitaba una lista de mapas, en donde la llave fuera un objeto
y el valor una cadena, traducido en Java:

Persona p = new Persona("Chachito", "Perez");
HashMap<Persona, String> personas = new HashMap<Persona, String>();
List<Map<Persona, String>> listamapas = new ArrayList<HashMap<Persona,String>>();
persona.put(p, "silver_user.png");
listamapas.add(persona);

De ahí, yo necesitaba validar con el objeto (de ahí que la llave sea un
objeto y no la cadena o un entero...aunque se podría dar el caso, en
fin) y si se validaba mostrar en la vista cada persona asociada a una imagen.

Y pues dado que en Play! tienes la capacidad de usar código Groovy
puro y duro, empecé con un código muy java pero usando ciertas magias
de Groovy:

listamapas.eachWithIndex(){v,i ->
--println(v.get(persona))
}

Sin embargo, como andaba haciendo algo de gestión en Python, por "error"
mi teclado respondió a mis impulsos con un: v[persona]
de ahí recargué la página y dije: "¡Chihuahua hombre!, no era así, tenía que poner get"
y antes de que alcanzara a llegar al IDE para hacer "la corrección" me di cuenta que
no hubo error, funcionó.

Otra cosa es que me puse a pensar y en teoría (o al menos dentro de lo que sé)
la clase java.util.ArrayList no tiene un método llamado "eachWithIndex". Sin embargo,
pues, funciona. Luego hice una prueba aislada en la consola de groovy y vi que los podía hacer
algo como: listamapas[0][persona].

Supongo que groovy agrega más de estas magias (o dicho de otra manera, sintáctica
azucarada), ¿me pueden decir en dónde se pueden encontrar la documentación de como
se extienden las clases java a través de Groovy, que transformaciones toman, etc.? Para
saber como sacarle el provecho a Groovy (aunque creo que será de las últimas aplicaciones
que desarrolle con Play 1.x.x, pero igual se me puede ofrecer).

Desde ya, gracias.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

docs

Adiciones de groovy al JDK:

http://groovy.codehaus.org/groovy-jdk/

API de Groovy:

http://groovy.codehaus.org/api/

Imagen de benek

Así es estimado, Groovy

Así es estimado, Groovy agrega métodos de este tipo no solamente a colecciones, sino a todos los objetos, o sea que puedes hacer each o eachWithIndex _sobre cualquier objeto_, o puedes acceder a una variable String como si fuese un array, estilo: cadena[1..3]. Hay más métodos estilo collect(), any(), grep(), etc... que provienen desde la clase Object de Groovy.

Muchas gracias

Ohh!... Muchas gracias por la información, no sabía que incluso a clases como String se le agregaran métodos como each. Creo entonces que la API de reflexión incluida en Java (por lo que entendí del comentario de @benek) es básicamente inútil usando groovy, el ver las propiedades y demás de un objeto (¿o es qué como en Ruby las clases mismas son un objeto?), de ahí que muchas personas ven el potencial de Groovy supongo para la creación de un DSL o frameworks tipo Hibernate que necesitan ver que contiene cada ve tu a saber que clase.

Bueno, después de medio divagar en el tema y de ver las aportaciones, me gustaría saber si entendí bien.

Saludos.

Imagen de rodrigo salado anaya

Groovy esta bien fumado...

Groovy esta bien fumado, incluso puedes hacer cosas como por ejemplo convertir una lista de caracteres a números enteros pero con más ponch:

lista = []

['1', '2', '3', '4'].collect(lista) {
            n = it as int
            if(n%2 == 0){
                return n
            }else{
                return '??'
            }
}

assert lista == ['??', 2, '??', 4]

closureToInt = {it as int}

['1', '2', '3', '4'].collect(lista, closureToInt)

assert lista == ['??', 2, '??', 4, 1, 2, 3, 4]

Referencias útiles:
http://groovy.codehaus.org/Closures
http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html#collect%...

Re: Groovy esta bien fumado...

Ésa es justamente una de las razones por las que Groovy no me convence del todo. Es decir, tienes como mil maneras de hacer una cosa, pero al fin "es la misma gata pero revolcada". En el ejemplo que das bien podría sustituir n = it as int por n = it.toInteger() incluso creo que pudiera suplantar ese if(n%2==0) por un if(n.mod(2)==0) e incluso if(n.mod(20).equals(0))... No sé, quizá para usarlo uno para scripts o desarrollo de pocas personas vaya bien, pero creo que la consistencia del código es muy frágil dada la flexibilidad del lenguaje, aunque igual si ya usé Ruby y me gustó (cosa rara, Groovy es básicamente lo mismo).

En fin, fumado no está, lo que tiene es que es demasiado flexible y tiene una capacidad de expresión tremenda, vamos que para mí Groovy es lo contrario de Java que es muy estricto y Groovy es más liberal en como quieras expresar las cosas.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">