Accueil » Java

Gym avec Groovy, exercice 1

26 janvier 2010 1 595 affichages 6 commentaires

Merci de participer ce matin à notre petite série d’exercice sur Groovy. Après un échauffement, nous allons travailler les abdos-fixtures, faire quelques moulinets de Closures, s’étirer avec des astuces sur les fichiers, bref que du bon code pour débuter. Je vous prends en main cette semaine, avec chaque jour un petit exercice simple afin de vous réhabituer à un bon langage, léger
Après avoir pris votre tapis… de souris, venez vous assoir devant moi, et écouter attentivement. Les exercices sont adaptés du livre « Groovy Recipes » par Scott Davis pour ceux qui veulent pratiquer de leur côté.

La surchage pondérale d’opérateur

Grâce à Java, je sais que ce petit problème de surcharge pondérale n’était plus trop d’actualité. Pourtant nous allons voir ensemble qu’avec Groovy, la surcharge d’opérateur est une chose très pratique. Pour cela, nous allons travailler avec la date.

Notre série d’exercices se déroulera dans une salle toute neuve hébergée sur Google App Engine (prononcez eng-i-neu) développée avec Gaelyk par Guillaume Laforge. Ouvrez donc la Groovy Web Console et débutons par quelques exercices simples pour travailler la surcharge d’opérateur. Tapez simplement le texte ci-dessous puis appuyez sur « Execute script« . Je note avec le symbole « => » le résultat de l’opération.

def today=new Date()

=> Mon Jan 25 07:57:43 UTC 2010

La surcharge d’opérateur est une fonction très pratique en Groovy. Imaginons que vous souhaitez connaître la data dans 7 jours. L’opérateur ‘+’ étant surchargé dans le cas d’une Date, il est alors possible d’écrire ce code:

def today=new Date()
println today
=> Tue Jan 26 08:28:33 UTC 2010

def tomorrow=today.next()
println tomorrow
=> Wed Jan 27 08:28:33 UTC 2010

def nextWeek=tomorrow+7
println nextWeek
=> Wed Feb 03 08:28:33 UTC 2010

def yesterday=today.previous()
println yesterday
=> Mon Jan 25 08:28:33 UTC 2010

Derrière l’opérateur plus, Groovy appelle la fonction next(). Voici une liste des opérateurs et des méthodes correspondants à ces opérateurs en Groovy :

Opérateur		Méthode
a==b or a!=b	a.equals(b)
a + b	 		a.plus(b)
a - b			a.minus(b)
a * b			a.multiply(b)
a / b			a.div(b)
a % b			a.mod(b)
a++ ou ++a		a.next()
a-- ou --a		a.previous()
a & b			a.and(b)
a | b			a.or(b)

Les opérateurs suivants sont plus communs, surtout lors de la manipulation des Listes :

Opérateur		Méthode
a[b]			a.getAt(b)
a[b]=c			a.putAt(b,c)
a << b			a.leftShift(b)
a >> b			a.righShift(b)
a < b ou a > b 	a.compareTo(b)
a <= b / a >= b	a.compareTo(b)

La manipulation des listes est encore plus simple en Groovy qu’en Java. Il est donc possible d’écrire par exemple ce bout de code (tiré du livre Groovy Recipes par Scott Davis).


def today=new Date()

(1..7).each{
println today++
}

=>
Mon Jan 25 09:31:41 CET 2010
Tue Jan 26 09:31:41 CET 2010
Wed Jan 27 09:31:41 CET 2010
Thu Jan 28 09:31:41 CET 2010
Fri Jan 29 09:31:41 CET 2010
Sat Jan 30 09:31:41 CET 2010
Sun Jan 31 09:31:41 CET 2010

Note: Ce code ne marchera que sur votre machine en local en utilisant groovyConsole.

Passage sur le dos, parlons des listes

Avez-vous noté la notation (1..7) dans l’exercice précèdent ? C’est ce que l’on appelle une Range en Groovy. Pratique non ?

Passons à un exercice plus intéressant, et plus proche de ce que vous allez pratiquer avec Groovy d’ici quelques semaines : la manipulation des listes, des Maps et des Sets en Groovy.

Création d’une liste

La syntaxe est simple. Une liste est créé en utilisant les crochets. C’est une ArrayList simple, ni plus, ni moins.

def touilleurThemes=["Java","Apple","Scrum","Groovy"]

println touilleurThemes
=> [Java, Groovy, Scrum, Apple]

println touilleurThemes.size()
=> 4

touilleurThemes << "Web 2.0"
println touilleurThemes
=> [Java, Groovy, Scrum, Apple,Web 2.0]

// Récuperer le premier élement
println touilleurThemes.first()
=> Java
println touilleurThemes[0]
=> Java

Itérer une liste en Groovy

Les closures sont utilisées lors de l’itération d’une liste. Voici quelques exemples d’itérations de la liste :

// Itération simple
def touilleurThemes=["Java","Groovy","Scrum","Apple"]
touilleurThemes.each{nom->
 println nom
}
=>Java
Groovy
Scrum
Apple

// Verson simplifié, it est une variable implicite
// Itération encore plus simple
def touilleurThemes=["Java","Groovy","Scrum","Apple"]
touilleurThemes.each{
 println it
}

Il reste possible d’itérer la liste en utilisant la syntaxe de Java 5 si vous préférez celle-ci :

def touilleurThemes=["Java","Groovy","Scrum","Apple"]
for(String item : touilleurThemes) {
println item
}

=>Java
Groovy
Scrum
Apple

Trier, ranger, manipuler une liste

Les listes sont des objets facilement manipulables. Il est possible de les trier, de les découper, de dépiler un élément comme sur une Queue, de rechercher un pattern, bref de faire un grand nombre d’opérations très pratique. Plutôt qu’un long discours, regardez attentivement ces exemples de code. Vous me ferrez 2 séries de 10, avec une grande respiration entre chaque exercice.


// Trier une liste avec sort
// Le tri est permanent, la liste originale est triée
def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"]
languages.sort()
languages.each{ println it }

=>Clojure
Groovy
Java
Lisp
Perl
Python
Scala


// Retourner une liste, cette fois-ci la liste originale
// ne sera pas modifiée.
def revertedList=languages.reverse()
revertedList.each{ println it }

=>
Scala
Python
Perl
Lisp
Java
Groovy
Clojure

// 3 Dépiler le dernier élément
def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"]
println  languages.pop()
=> Python

// 4 Concatenation
def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"]
def newLanguages=["Ruby","Goo","Javascript"]

languages+=newLanguages
println languages
=> [Java, Groovy, Scala, Lisp, Clojure, Perl, Python, Ruby, Goo, Javascript]

languages-=newLanguages
println languages
=> [Java, Groovy, Scala, Lisp, Clojure, Perl, Python]

Il est possible aussi de joindre une liste en une seule String, ou même de spécifier un séparateur par exemple. Très pratique lorsque vous souhaitez écrire une ligne au format CSV à partir d’une liste de résultats :

def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"]

println languages.join()
//JavaGroovyScalaLispClojurePerlPython

println languages.join(",")
//Java,Groovy,Scala,Lisp,Clojure,Perl,Python

Les closures peuvent aussi être utilisées pour rechercher un élément rapidement dans une liste. Imaginons que vous souhaitez retrouver l’ensemble des noms commençant par la lettre J :

def languages=["Java","Groovy","Scala","Lisp","Clojure","JRuby","Jython"]
def resultList = languages.findAll {it.startsWith("J")}
resultList.each{println it}

=>Java
JRuby
Jython

Les listes de chiffres sont faciles à manipuler, il est possible d’additionner la série, de rechercher la valeur maximum ou minimum :

def ages=[23,34,45,12,46,21,42,56,18]

println ages.max()
=> 56
println ages.min()
=> 12
println ages.sum()
=> 297
println "Moyenne: " + ages.sum()/ages.size()
=>33

La méthode collect permet de créer une nouvelle liste en concaténant un Objet à chacun des éléments de la liste initiale.

def ages=[23,34,45]
def resultList=ages.collect{ it += " ans"}
resultList.each{println it}

=>23 ans
34 ans
45 ans

L’opérateur Spread (*)

L’opérateur Spread (marqué avec une astérisque *) est un opérateur courant utilisé pour exécuter une méthode sur chacun des éléments d’une liste, ou pour aussi distribuer les éléments d’une liste à une méthode. Il y a 2 variantes. L’opérateur spread seul (*) et l’opérateur spread-dot (noté *.).
L’opérateur spread seul peut être utilisé pour passer une liste d’argument à une méthode. Il va itérer chacun des éléments et les passer un à un. C’est peu commun donc je n’en parlerai pas plus ici. L’opérateur spread-dot est plus courant. Dans l’exemple ci-dessous, le caractère *. signifie : prend chacun des éléments de la liste et effectue un appel à la méthode toUpperCase, stocke le tout dans une nouvelle liste.

def languages=["Java","Groovy","Goo"]

// L'opérateur Spread dot
def resultList=languages*.toUpperCase()

// Affiche la nouvelle liste
resultList.each{println it}

=> JAVA,
GROOVY,
GOO

Conclusion

Voilà c’est tout pour ce matin. Nous verrons la suite demain. Passez une bonne journée !

6 commentaires »

  • Romain a dit:

    Sympa ce post ! J’imagine qu’il y aura d’autres séances de gymnastique ! Au moins, ça permettra à ceux qui ont pris comme bonne résolution 2010 de faire du sport, de la tenir !

    Sinon, dans les codes, il faut faire attention. Le « <<" se transforme en "< <", ce qui n'est pas correct, of course… (peut-être un bug du syntax highlighter ?)

  • Nicolas Martignole a dit:

    @Romaintaz : c’est corrigé. J’ai mis & lt; et c’est passé

  • Florian a dit:

    Très bonne présentation de certaines particularités de Groovy ! Pour info, l’itération sur le range marche aussi sur la Groovy Web Console.

  • Les tweets qui mentionnent Le Touilleur Express » Blog Archive » Gym avec Groovy, exercice 1 -- Topsy.com a dit:

    [...] Ce billet était mentionné sur Twitter par Guillaume Laforge, Nicolas Martignole, finalspy, finalspy, lbois et des autres. lbois a dit: Shared article: Gym avec Groovy, exercice 1 http://bit.ly/7i6QoF (via @glaforge ) [...]

  • redFishSyndrom a dit:

    euh, et Davina elle s’est cachée derrière un intersect()?? ;-)

  • Raphaël Brugier a dit:

    Bonsoir,

    excellente idée que cet exercice quotidien! J’aime beaucoup le style d’écriture (comme toujours ici :)

    Une remarque cependant, pour l’affichage des résultats des commandes je trouve plus explicite d’utiliser les assert (comme sur le wiki de Groovy ou les groovy goodness. Question d’habitude certainement :)

    Bonne continuation !

    Nb : Le site de groovy n’est pas groovy.org comme l’indique les liens de l’article mais http://groovy.codehaus.org (c’est corrigé)