SlideShare a Scribd company logo
1 of 145
Download to read offline
Milou fait un régime
Guava - Lombok
SPONSORS
Thierry Leriche-Dessirier
icauda.com
 Consultant JEE freelance
 Professeur de Génie Logiciel à l’ESIEA
 Rédacteur pour Programmez
 Rédacteur pour Developpez.com
@thierryleriche
Cours
FAQ
Interviews
Articles / tutoriels
Magazine
Forums
News
Agendas
Critiques
13 OOO OOO pages vues par mois
5 500 000visites par mois
2 500 000visites uniques par mois
5 000 messages forum par jour
Agenda
 Milou est trop lourd (intro)
 Lombok (et Lombok-pg) en action
 Tour d’horizon de Guava
Milou est trop lourd (et doit faire un régime)
I am Milou
public class Dog {
private Integer id ;
private String name ;
private String fullName ;
private SexeEnum sex ;
private Date birthday ;
private String race ;
private Boolean lof ;
private Double weight ;
private Double size ;
private List<String> colors ;
...
DOG
5
 id
 name
 fullName
 sex
 birthday
 race
 lof
 weight
 size
 Colors
 Constructeurs
 Getters / setters
 toString ()
 equals ()
 hashCode ()
 compareTo ()
clic clic
démo
 id
 name
 fullName
 sex
 birthday
 race
 lof
 weight
 size
 Colors
 Constructeurs
 Getters / setters
 toString ()
 equals ()
 hashCode ()
 compareTo ()
public class Dog
implements Comparable<Dog> {
...
@Override
public int compareTo(Dog other) {
int result = 0;
result = name.compareTo(other.name);
if (result != 0) {
return result;
}
...
}
Code très limite… NPE ?...
 id
 name
 fullName
 sex
 birthday
 race
 lof
 weight
 size
 Colors
 Constructeurs
 Getters / setters
 toString ()
 equals ()
 hashCode ()
 compareTo ()
 210 lignes10 attributs
210lignes de code
10attributs
Java
VachercherGuava
 toString ()
 equals ()
 hashCode ()
 compareTo ()
Commons  FAQ 1-2
Base
Objects
public String toString() {
return "Dog [id=" + id
+ ", name=" + name
+ ", fullName=" + fullName
+ ", sex=" + sex
+ ", birthday=" + birthday
+ ", race=" + race
+ ", lof=" + lof
+ ", weight=" + weight
+ ", size=" + size
+ ", colors=" + colors + "]";
}
Java5
5
 toString ()
Simple, efficace et bien pourri 
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Dog.class.getSimpleName())
.append("[id=").append(id)
.append(", name=").append(name)
.append(", fullName=").append(fullName)
...
.append(", colors=").append(colors);
return sb.toString();
}
Java5
5
 toString ()
Mieux mais sans plus 
public String toString() {
return Objects.toStringHelper(this)
.add("id", id)
.add("name", name)
.add("fullName", fullName)
...
.add("colors", colors)
.toString();
}
Guava
G
 toString ()
Builder
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Dog other = (Dog) obj;
if (birthday == null) {
if (other.birthday != null) return false;
} else if (!birthday.equals(other.birthday)) return false;
if (fullName == null) {
if (other.fullName != null) return false;
...
} else if (!race.equals(other.race)) return false;
if (sex != other.sex) return false;
return true;
}
Java5
5
 equals ()
birthday, fullname, name, race et sex
Carrément illisible 
public boolean equals(Object obj) {
if (!(obj instanceof Dog)) return false;
Dog other = (Dog) obj;
return Objects.equal(birthday, other.birthday)
&& Objects.equal(fullname, other.fullname)
&& Objects.equal(name, other.name)
&& Objects.equal(race, other.race)
&& sex == other.sex;
}
Guava
G
 equals ()
birthday, fullname, name, race et sex
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((birthday == null) ? 0 : birthday.hashCode());
result = prime * result
+ ((fullName == null) ? 0 : fullName.hashCode());
result = prime * result
+ ((name == null) ? 0 : name.hashCode());
result = prime * result
+ ((race == null) ? 0 : race.hashCode());
result = prime * result
+ ((sex == null) ? 0 : sex.hashCode());
return result;
}
Java5
5
 hashCode ()
birthday, fullname, name, race et sex
public int hashCode() {
return Objects.hashCode(birthday, fullName,
name, race, sex);
}
Guava
G
 hasCode()
birthday, fullname, name, race et sex
public int compareTo(Dog other) {
int result = 0;
result = name.compareTo(other.name);
if (result != 0) {
return result;
}
result = fullname.compareTo(other.fullname);
if (result != 0) {
return result;
}
...
}
Java5
5
 compareTo ()
name, fullname, birthday, weight, size, race et sex
name.compareTo(other.name)
 compareTo ()
other.name.compareTo(name)
Vs
public int compareTo(Dog other) {
return ComparisonChain.start()
.compare(name, other.name)
.compare(fullName, other.fullName)
.compare(birthday, other.birthday)
.compare(weight, other.weight)
.compare(size, other.size)
.compare(race, other.race)
.compare(sex, other.sex)
.result();
}
Guava
G
 compareTo ()
name, fullname, birthday, weight, size, race et sex
Lombok
en action
Régime
Annotations de base
 @NoArgsConstructor /
@RequiredArgsConstructor /
@AllArgsConstructor  constructeurs
 @Getter / @Setter
 @ToString
 @EqualsAndHashCode
 @Data  @Getter + @Setter + @ToString +
@EqualsAndHashCode + @RequiredArgsConstructor
Régime
clic clic
démo
Régime  @NoArgsConstructor /
@RequiredArgsConstructor /
@AllArgsConstructor
 @Getter / @Setter
 @ToString
 @EqualsAndHashCode
 @Data
210lignes de code
10attributs
Java
12lignes + 2-3@ + compareTo()Lombok
name, sex

@RequiredArgsConstructor(staticName = "of")
public class Dog {
private Integer id;
@NonNull private String name; 
private String fullName;
@NonNull private SexeEnum sex; 
private Date birthday;
...
Dog dog = Dog.of("Milou", MALE);
Factory L
name, sex

private Dog(@NonNull final String name,
@NonNull final SexeEnum sex) {
if (name == null) throw new NullPointerException("name");
if (sex == null) throw new NullPointerException("sex");
this.name = name;
this.sex = sex;
}
public static Dog of(@NonNull final String name,
@NonNull final SexeEnum sex) {
return new Dog(name, sex);
}
@RequiredArgsConstructor(staticName = "of")
public class Dog {
private Integer id;
@NonNull private String name; 
private String fullName;
@NonNull private SexeEnum sex; 
private Date birthday;
...
Dog dog = Dog.of("Milou", MALE);
Factory L
Trucs pratiques
Se simplifier la vie
 @Cleanup
 @Synchronized
 @SneakyThrows
 @Log
 @Delegate
 val
Pratique
public void lireJava6(String from) {
InputStream in = null;
try {
in = new FileInputStream(from);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1)
break;
...
}
} catch (Exception e) {
...
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
...
}
}
...
Ressources 5
public void lire(String from) throws IOException {
@Cleanup
InputStream in = new FileInputStream(from);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1)
break;
...
}
}
Ressources L
Délombok
Revenir sans la lib
Délombok<properties>
<lombok.sourceDirectory>
${project.basedir}/src/main/java
</lombok.sourceDirectory>
...
<build>
<groupId>org.projectlombok</groupId>
<artifactId>maven-lombok-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
</execution>
</executions>
...
mvn lombok:delombok
java -jar lombok.jar delombok src -d src-delomboked
XML
Délombok@Data
public class Dog {
private Integer id;
private String name;
private String fullName;
private SexeEnum sex;
private Date birthday;
private String race;
private Boolean lof;
private Double weight;
private Double size;
private List<String> colors;
}
5public class Dog {
private Integer id;
private String name;
private String fullName;
...
private List<String> colors;
public DogLombok() {
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public boolean equals(final java.lang.Obje
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != this.getClass()) ret
final Dog other = (Dog)o;
if (this.getId() == null ? other.getId()
...
@java.lang.Override
@java.lang.SuppressWarnings("all")
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = result * PRIME + (this.getId()
mvn
lombok:delombok
5
Lombok-pg
Annotations supplémentaires
 @Action
 @Function
 @EnumId
 @Rethrow / @Rethrows
 @Singleton
 @AutoGenMethodStub
 @BoundPropertySupport / @BoundSetter
 @DoPrivileged
 @ExtensionMethod
 @ListenerSupport
 @WriteLock / @ReadLock
 @Await / @Signal / @AwaitBeforeAndSignalAfter
 @Sanitize.Normalize / .With
 @SwingInvokeLater / @SwingInvokeAndWait
 @Validate.NotEmpty / .NotNull / .With
 @VisibleForTesting
AnnotationsPg
 @Builder
 @LazyGetter
 @FluentSetter
 @Predicate

@FluentSetter
@Getter
public class Dog {
private Integer id ;
private String name ;
private String fullName ;
...
DogLombok dog = new DogLombok();
dog.name("Milou").sex(MALE);
Fluent
println( dog.getName()); //  Milou
println( dog.getSex()); //  MALE
L

@Builder
@Getter
public class Dog {
private Integer id ;
private String name ;
private String fullName ;
...
Dog dog = Dog.dog().name("Milou").sex(MALE).build();
Builder
println( dog.getName()); //  Milou
println( dog.getSex()); //  MALE
L
@ExtensionMethod({ Dog.class, MyDogExtensionClass.class })
public class DogWithExtension {
public void foo() {
Dog milou = new Dog("Milou", 12.5, ...);
boolean isTooFat = milou.isTooFat();
}
}
extension L
Avec paramètres  FAQ 9
 http://blog.developpez.com/todaystip/p11165/dev/java/extensionmethod-de-lombok-pg/
class MyDogExtensionClass {
public static boolean isTooFat(final Dog dog) {
double imc = dog.getWeight() / pow(dog.getSize(), 2);
return 31 < imc;
}
}
Lombok or not Lombok ?
Avantages et inconvénients
Pro/Cons
 Byte code modifié 
 Version en 0.x
 Documentation des prog ?
 Magique ?
 Compacité
 Lecture simplifiée
 Code normée
 Délombok (pour essayer)
Guava
tour d’horizon
Factory Methods
Les choses que j’aime
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();
Java5
5
< new Vs static factories >
Java5
Map<String, List<String>> trucs =
new HashMap<String, List<String>>();
Map<? extends Person, Map<String, List<String>>> trucs =
new TreeMap<? extends Person, Map<String, List<String>>>();
Map<? extends Wrapper<String, Sex, Person>, Map<String,
List<Set<Adress<String, Integer, Country>>>>> trucs = ...
durdur?
5
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();
5
< new Vs static factories >
Java5
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();
Java7
Qui utilise Java 7 en prod ?
7
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();
5
< new Vs static factories >
Java5Java7
Qui utilise Java 7 en prod ?
List<Integer> primeNumbers = newArrayList();
Set<String> colors = newTreeSet();
Map<String, Integer> ages = newHashMap();
Guava
Dès maintenant !
G
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();
5
7
< new Vs static factories >
Java5Java7
Qui utilise Java 7 en prod ?
List<Integer> primeNumbers = newArrayList();
Set<String> colors = newTreeSet();
Map<String, Integer> ages = newHashMap();
Guava
Dès maintenant !
G
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();
5
7
var primeNumbers = new ArrayList<Integer>();
-> primeNumbers.size();
...
Lombok
< new Vs static factories >
L
List<Dog> dogs = newArrayList(
new Dog("Milou", 12.5, MALE, ...),
new Dog("Rintintin", 45.0, MALE, ...),
new Dog("Volt", 10.3, MALE, ...),
new Dog("Lassie", 45.0, FEMALE, ...),
new Dog("Pluto", 22.0, MALE, ...),
new Dog("Medor", 35.6, MALE, ...));
Listofdogs
G
[Milou,
Rintintin,
Volt,
Lassie,
Pluto,
Medor]
< new Vs static factories >
Immutables
Pour que ça ne change pas
Quand ?
immutable
Quand ?
immutable
mutable
On se demande souvent si une liste doit être immutable mais
c’est prendre le problème dans le mauvais sens. La plupart du
temps, ce qu’il faut vraiment se demander, c’est si la liste a
besoin d’être mutable.
Java5Set<Integer> temp =
new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7));
Set<Integer> primes = Collections.unmodifiableSet(temp);
< unmodifiables Vs immutables >
Java5
Set<Integer> primes = ImmutableSet.of(1, 2, 3, 5, 7);
Set<Integer> temp =
new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7));
Set<Integer> primes = Collections.unmodifiableSet(temp);
Guava
< unmodifiables Vs immutables >
G
OfImmutableSet.of(E e1)
ImmutableSet.of(E e1, E e2)
ImmutableSet.of(E e1, E e2, E e3)
ImmutableSet.of(E e1, E e2, E e3, E e4)
ImmutableSet.of(E e1, E e2, E e3, E e4, E e5)
ImmutableSet.of(E e1, E e2, E e3, E e4, E e5, E e6, E...)
Ne prend pas de null
Of
ImmutableSet.of()
Vide
Map et List  FAQ 4
< unmodifiables Vs immutables >
G
 http://blog.developpez.com/guava/p10589/collection/title-212/
Java5public class Dog {
private String name;
...
private List<String> colors;
public Dog(String name, List<String> colors) {
this.name = name;
...
this.colors = Collections.unmodifiableList(
new ArrayList<String>(colors));
}
public List<String> getColors() {
return colors;
}
5
< Copie de défense >
Guavapublic class Dog {
private String name;
...
private ImmutableList<String> colors;
public Dog(String name, List<String> colors) {
this.name = name;
...
this.colors = ImmutableList.copyOf(colors);
}
public ImmutableList<String> getColors() {
return colors;
}
G
Message clair
< Copie de défense >
Collections en plus
Multimap, Bipap, Multiset, Table
Java5Map<String, List<String>> dogFavoriteColors =
new HashMap<String, List<String>>();
5
< Multi Map >
List<String> milouColors = dogFavoriteColors.get("Milou");
if(milouColors == null) {
milouColors = new ArrayList<String>();
dogFavoriteColors.put("Milou",milouColors);
}
milouColors.add("Vert");
5
Java5Map<String, List<String>> dogFavoriteColors =
new HashMap<String, List<String>>();
5
< Multi Map >
List<String> milouColors = dogFavoriteColors.get("Milou");
if(milouColors == null) {
milouColors = new ArrayList<String>();
dogFavoriteColors.put("Milou",milouColors);
}
milouColors.add("Vert");
5
Guava
Multimap<String, String> dogFavoriteColors =
HashMultimap.create();
dogFvoriteColors2.put("Milou", "Jaune");
dogFavoriteColors2.put("Milou", "Rouge");
G
< Bi Map >
GuavaBiMap<String, Dog> tatouages = HashBiMap.create();
tatouages.put("ABC123", new Dog("Milou") );
tatouages.put("MBD324", new Dog("Volt") );
tatouages.put("JFT672", new Dog("Lassie") );
ABC123=Milou
MDB324=Volt
JFT672=LassieIl est possible de changer la valeur associée à une clé mais pas
d'avoir deux clés avec la même valeur (IllegalArgumentException).
println( tatouages );
Une map bijective
{ABC123=Milou,
MBD324=Volt,
JFT672=Lassie}
G
println( tatouages.inverse() );
{Milou=ABC123,
Volt=MBD324,
Lassie=JFT672}
< Multi Set >
Guava
Multiset<Integer> ages = HashMultiset.create();
ages.add(2);
ages.add(3);
ages.add(7);
ages.add(11);
ages.add(3);
ages.add(5);
println( ages );
println( ages.count(3) )
[2, 3 x 2, 5, 7, 11]
2
G
Base
Préconditions, joiner, splitter, optional
 toString ()
 equals ()
 hashCode ()
 compareTo ()
public class Dog {
private Integer id ;
private String name ;
private String fullName ;
...
public Dog(String name, String fullName, ...) {
if(name == null) {
throw new NPE("Le nom bla bla");
}
if(fullName == null) {
throw new NPE("bla bla");
}
...
this.name = name;
this.fullName = fullName;
...
}
DOG 5
< Preconditions >
import static com.google.common.base.Preconditions.*;
public class Dog {
private Integer id ;
private String name ;
private String fullName ;
...
public Dog(String name, String fullName, ...) {
this.name = checkNotNull(name, "bla bla");
this.fullName = checkNotNull(fullName, "bla bla");
...
}
DOG G
< Preconditions >
checkNotNull()  NPE
checkArgument()  IAE
checkState()  ISE
Joiner
String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));
List<String> dogNames = newArrayList("Lassie", "Volt", "Milou");
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String name : dogNames) {
if(name != null || name.trim().isEmpty()) {
continue;
}
if (!first) {
sb.append(", ");
}
sb.append(name);
first = false;
}
String names = sb.toString();
Java classique
G"Lassie, Volt, Milou"
Joiner
String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));
String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", null, "Milou"));
 NPE 
G"Lassie, Volt, Milou"
Joiner
String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));
String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", null, "Milou"));
String names = Joiner.on(", ")
.skipNulls()
.join(newArrayList("Lassie", "Volt", null, "Milou"));
"Lassie, Volt, Milou"
 NPE 
G"Lassie, Volt, Milou"
G
Joiner
String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));
String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", null, "Milou"));
String names = Joiner.on(", ")
.skipNulls()
.join(newArrayList("Lassie", "Volt", null, "Milou"));
"Lassie, Volt, Milou"
 NPE 
String names = Joiner.on(", ")
.useForNull("Anonymous"))
.join(newArrayList("Lassie", "Volt", null, "Milou"));
"Lassie, Volt, Anonymous, Milou"
G"Lassie, Volt, Milou"
G
G
 http://blog.developpez.com/guava/p11054/base/joiner-pour-assembler-des-items/
Splitter
Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, Milou");
[ "Lassie",
"Volt",
"Milou" ]
Splitter
Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, Milou");
[ "Lassie",
"Volt",
"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, ,Milou");
[ "Lassie",
"Volt",
" ",
"Milou" ]
Splitter
Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, Milou");
[ "Lassie",
"Volt",
"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, ,Milou");
[ "Lassie",
"Volt",
" ",
"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
.trimResults()
.split("Lassie, Volt, ,Milou");
[ "Lassie",
"Volt",
"",
"Milou" ]
Splitter
Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, Milou");
[ "Lassie",
"Volt",
"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, ,Milou");
[ "Lassie",
"Volt",
" ",
"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
.trimResults()
.split("Lassie, Volt, ,Milou");
Iterable<String> dogNames =
Splitter.on(",")
.trimResults()
.omitEmptyStrings()
.split("Lassie, Volt, ,Milou");
G[ "Lassie",
"Volt",
"Milou" ]
 http://blog.developpez.com/guava/p11045/annotation/splitter-pour-separer-des-items/
[ "Lassie",
"Volt",
"",
"Milou" ]
Optional
Wrapper Optional <T>
Dog dog = new Dog("Milou", ...);
Optional<Dog> opt = Optional.of(dog);
assertTrue( opt.isPresent() );
assertEquals( "Milou", opt.get().getName() );
Optional
Wrapper Optional <T>
Dog dog = new Dog("Milou", ...);
Optional<Dog> opt = Optional.of(dog);
assertTrue( opt.isPresent() );
assertEquals( "Milou", opt.get().getName() );
Optional<Dog> opt = Optional.absent();
assertFalse( opt.isPresent() );
opt.get();  ISE
Optional
Wrapper Optional <T>
Dog dog = new Dog("Milou", ...);
Optional<Dog> opt = Optional.of(dog);
assertTrue( opt.isPresent() );
assertEquals( "Milou", opt.get().getName() );
Optional<Dog> opt = Optional.absent();
assertFalse( opt.isPresent() );
opt.get();  ISE
Dog dog = null;
Optional<Dog> opt = Optional.of(dog);  NPE
Optional<Dog> opt = Optional.fromNullable(dog);
 http://blog.developpez.com/guava/p11163/base/le-wrapper-optional-de-guava/
Optional
Wrapper Optional <T>
Dog dog = new Dog("Milou", ...);
Optional<Dog> opt = Optional.of(dog);
assertTrue( opt.isPresent() );
assertEquals( "Milou", opt.get().getName() );
Optional<Dog> opt = Optional.absent();
assertFalse( opt.isPresent() );
opt.get();  ISE
Dog dog = null;
Optional<Dog> opt = Optional.of(dog);  NPE
Optional<Dog> opt = Optional.fromNullable(dog);
Dog dog = null;
Optional<Dog> opt = Optional.fromNullable(dog);
Dog dog2 = opt.or( new Dog("noname", ...) );
assertEquals( "noname", dog2.getName() );
Functional Programming
todo
Super chien
Dog
public class SuperChien implements SuperHero {
private String surnom ;
private double poids ;
private Set<String> couleursCostume ;
private Set<String> pouvoirs ;
...
SuperChien
5
Les héros peuvent avoir plusieurs costumes donc je
n’utilise pas un ImmutableSet. Idem pour les pouvoirs
dont la liste augmente avec l’expérience.
TransformationList<SuperChien> superChiens =
Lists.transform(dogs,
new Function<Dog, SuperChien>() {
@Override
public SuperChien apply(Dog dog) {
SuperChien chien = new SuperChien();
chien.setSurnom("Super " + dog.getName());
chien.setPoids(dog.getWeight());
chien.setCouleursCostume(newHashSet(dog.getColors()))
chien.setPouvoirs(newHashSet("Code en Java", "Vole"))
...
return chien;
}
});
[Super Milou,
Super Rintintin,
Super Volt,
Super Lassie,
Super Pluto,
Super Medor]
< Transformation >
G
List<SuperChien> superChiens =
Lists.transform(dogs, new Function<Dog, SuperChien>() {
@Override
public SuperChien apply(Dog dog) {
SuperChien chien = new SuperChien();
...
return chien;
}
});
 Vue (lazy)
 size / isEmpty dispo 
 Pas pour traitements répétés   FAQ 3
List<SuperChien> chiens = newArrayList(Lists.transform(...
ImmutableList<SuperChien> chiens =
ImmutableList.copyOf(Lists.transform(...
Transformation
< Transformation >
G
FiltrePredicate<Dog> malePredicate =
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}
}
Iterable<Dog> maleDogs =
Iterables.filter(dogs, malePredicate);
< Filtre >
G
G[Milou,
Rintintin,
Volt,
Pluto,
Medor]
FiltrePredicate<Dog> malePredicate =
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}
}
Iterable<Dog> maleDogs =
Iterables.filter(dogs, malePredicate);
Dog firstMaleDog =
Iterables.find(dogs, malePredicate);
< Filtre >
G
G
[Milou,
Rintintin,
Volt,
Pluto,
Medor]
GMilou
FiltrePredicate<Dog> malePredicate =
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}
}
Iterable<Dog> maleDogs =
Iterables.filter(dogs, malePredicate);
Dog firstMaleDog =
Iterables.find(dogs, malePredicate);
Dog firstMaleDog =
Iterables.find(femaleDogs, malePredicate, DEFAULT_DOG );
Default dog
< Filtre >
G
G
GMilou
[Milou,
Rintintin,
Volt,
Pluto,
Medor]
Pasfluent
Predicate<Dog> malePredicate =
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}};
Function<FullDog, String> nameFunction =
new Function<FullDog, String>() {
public String apply(FullDog dog) {
return dog.getName();
}};
Iterable<FullDog> maleDogs =
Iterables.filter(dogs, malePredicate);
Iterable<String> maleNames =
Iterables.transform(maleDogs, nameFunction);
[Milou,
Rintintin,
Volt,
Pluto,
Medor]
< Fluent or not fluent ? >
G
G
G
Pasfluent
Iterable<FullDog> maleDogs =
Iterables.filter(dogs, malePredicate);
Iterable<String> maleNames =
Iterables.transform(maleDogs, nameFunction);
[Milou,
Rintintin,
Volt,
Pluto,
Medor]
List<String> maleNames2 =
FluentIterable.from(dogs)
.filter(malePredicate)
.transform(nameFunction)
.toImmutableList();
Fluent
Guava 12.0
< Fluent or not fluent ? >
G
G
 http://blog.developpez.com/guava/p11092/annotation/fluentiterable-sur-
mon-chien-guava/
Cache
todo
WebService
public class DogService {
@Inject
private PetShopWebService service;
public Integer getNumberDogsSoldYesterday() {
return service.checkSales( "dog" );
}
< Memoization >
5
WebService
public class DogService {
@Inject
private PetShopWebService service;
public Integer getNumberDogsSoldYesterday() {
return service.checkSales( "dog" );
}
< Memoization >
5Cachemanuel
private Integer nbOfDogsSold;
public Integer getNumberDogsSoldYesterday() {
if (nbOfDogsSold == null) {
nbOfDogsSold = service.checkSales( "dog" );
}
return nbOfDogsSold;
}
5
Double check null…
Guava
public class DogService {
@Inject
private PetShopWebService service;
private Supplier<Integer> nbOfDogsSoldSupplier =
Suppliers.memoize(
new Supplier<Integer>() {
public Integer get() {
return service.checkSales( "dog" );
}
});
public Integer getNumberDogsSoldYesterday() {
return nbOfDogsSoldSupplier.get();
}
< Memoization >
G
Guava
public class DogService {
@Inject
private PetShopWebService service;
private Supplier<Integer> nbOfDogsSoldSupplier =
Suppliers.memoizeWithExpiration(
new Supplier<Integer>() {
public Integer get() {
return service.checkSales( "dog" );
}
}, 1, TimeUnit.DAYS );
public Integer getNumberDogsSoldYesterday() {
return nbOfDogsSoldSupplier.get();
}
< Memoization >
G
WebService
public class DogService {
@Inject
private PetShopWebService service;
private Map<String, Dog> dogMap = Maps.newHashMap();
public Dog getDog(String name) {
Dog dog = dogMap.get(name);
if(dog == null) {
dog = service.getAnimal( "dog", name ); // type-name
dogMap.put( name, dog );
}
return dog;
}
< Cache >
5
Quid du timeout ? Max ?
Guava
public class DogService {
@Inject
private PetShopWebService service;
private LoadingCache<String, Dog> dogCache =
CacheBuilder.newBuilder()
.maximumSize(2000)
.expireAfterWrite(30, TimeUnit.MINUTES)
.build(new CacheLoader<String, Dog>() {
public Dog load(String key) {
return service.getAnimal( "dog", key );
}
});
public Dog getDog(String name) {
return dogCache.get( name ); // + try-catch
}
< Cache >
G
Hash
Fantôme
Hash
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
.putInt(123)
.putString("Milou")
.hash();
byte[] bytes = hc.asBytes();
 md5
 Murmur3 128 bits
 Murmur3 32 bits
 Sha1
 Sha256
 Sha512
 goodFastHash
G
Préparation
int NB_OF_DOGS = 100000;
List<Dog> dogs = newArrayList();
Random rand = new Random();
for (int i = 0; i < NB_OF_DOGS; i++) {
Dog dog = new Dog();
dog.setName("abc" + rand.nextInt(999));
...
dogs.add(dog);
}
dogs.add(milou);
boolean isInList = dogs.contains(milou);
true (14 ms)
final Dog milou = new Dog();
milou.setName("Milou");
...
boolean isInList = dogs.contains(milou);
false (14 ms)
contains
< Is in list ? >
5
5
Bloomfilter
Funnel<Dog> dogFunnel = new Funnel<Dog>() {
public void funnel(Dogdog, PrimitiveSink sink) {
sink.putString(dog.getName())
.putString(dog.getFullName())
.putString(dog.getRace());
}};
BloomFilter<Dog> bloom =
BloomFilter.create(dogFunnel, NB_OF_DOGS, 0.01);
for (int i = 0; i < NB_OF_DOGS; i++) {
...
bloom.put(dog);
bloom.put(milou);
boolean isInList = bloom.mightContain(milou);
true (0 ms)
boolean isInList = bloom.mightContain(milou);
false (0 ms)
< Is in list ? >
G
 http://blog.developpez.com/guava/p11149/collection/bloom-filter-de-guava-13/
Guava 13
Guava or not Guava ?
Avantages et inconvénients
Pro/Cons
 Ne pas en abuser…
 Utile
 Bonnes pratiques
LIENS
Guava
 http://code.google.com/p/guava-libraries
Lombok
 http://projectlombok.org
Lombok-pg
 https://github.com/peichhorn/lombok-pg
ICAUDA
http://icauda.com
http://icauda.com/articles.html (articles)
http://icauda.com/cours.html (slides)
Blog Guava
http://blog.developpez.com/guava
« Simplifier le code de vos beans Java à l'aide
de Commons Lang, Guava et Lombok »
http://thierry-leriche-dessirier.developpez.com/tutoriels/
java/simplifier-code-guava-lombok (article)
@thierryleriche
MERCI
FAQ/Bonus
1. Guava Vs Commons
2. Régime façon Apache
3. Fonctionnal prog Vs boucle for
4. Créer des Maps
5. Charsets
6. Converter Spring
7. Orderings
8. Licences
9. Extension avec valeurs
10. Chrono
11. CharMatcher
12. Impl
13. And, or, in…
14. Partition, limit
15. Inférence de type
16. Coût du bloom
17. Table
18. Ecrasement des getters existants
Guava Vs Commons ?
http://tinyurl.com/guava-vs-apache
1
Régime : la méthode Commons ?
2
public String toString() {
return new ToStringBuilder(this)
.append("id", id)
.append("name", name)
.append("fullName", fullName)
...
.append("colors", colors)
.toString();
}
toString
L
Régime : la méthode Commons ?
2
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof Dog)) return false;
Dog other = (Dog) obj;
return new EqualsBuilder()
.append(birthday, other.birthday)
.append(fullname, other.fullname)
.append(name, other.name)
.append(race, other.race)
.append(sex, other.sex)
.isEquals();
}
equals
L
Régime : la méthode Commons ?
2
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(birthday)
.append(fullname)
.append(name)
.append(race)
.append(sex)
.toHashCode();
}
hashCode
L
Régime : la méthode Commons ?
2
public int compareTo(Dog other) {
return new CompareToBuilder()
.append(name, other.name)
.append(fullname, other.fullname)
.append(birthday, other.birthday)
...
.append(sex, other.sex)
.toComparison();
}
compareTo
L
List<SuperChien> superChiens = newArrayList();
for(Dog dog : dogs) {
SuperChien chien = new SuperChien();
...
superChiens.add(chien);
}
List<SuperChien> superChiens = newArrayList(
Lists.transform(dogs, new Function<Dog, SuperChien>() {
@Override
public SuperChien apply(Dog dog) {
SuperChien chien = new SuperChien();
...
return chien;
}
}));
Transformation
Fonctionnal prog Vs boucle for : quand ?
http://code.google.com/p/guava-libraries/wiki/FunctionalExplained
Vs
3
G
G
Créer des Maps
4
of
public static final ImmutableMap<String, Integer>
AGES = new ImmutableMap.Builder<String, Integer>()
.put("Milou", 32)
.put("Volt", 7)
.put("Pluto", 37)
.put("Lassie", 17)
.put("Medor", 5)
.put("Croquette", 8)
.put("Loulou", 2)
...
.build();
public static final ImmutableMap<String, Integer>
AGES = ImmutableMap.of("Milou", 32,
"Volt", 7,
"Pluto", 37,
"Lassie", 17);
Builder
G
G
Charsets
5
Java5
String name = "Milou";
byte[] bytes = name.getBytes(Charsets.UTF_8);
String name = "Milou";
try {
byte[] bytes = name.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
Guava
Ca n’arrive jamais cette exception 
5
G
import org.springframework...Converter;
@Component("dogToChienConverter")
public class DogToChienConverter
implements Converter<List<Dog>,
List<SuperChien>> {
public List<SuperChien> convert(List<Dog> dogs) {
List<SuperChien> chiens = newArrayList(transform(dogs,
new Function<Dog, SuperChien>() {
public SuperChien apply(Dog dog) {
...
return chien;
}
}));
return chiens;
}
6
Converter Spring
Lazy or not lazy ?
G
Orderings
7
Licences
8
 Lombok : MIT License
 Lombok-pg : MIT License
 Guava : Apache License 2.0
 Commons : Apache License 2.0
@ExtensionMethod({ Object.class, MyOtherClass.class })
public class DogWithExtension {
public void foo() {
String s1 = "toto";
s1.print(); //  toto
String s2 = null;
s2.print(); //  null
}
}
class MyOtherClass {
public static <T> void print(final T value) {
System.out.println(value);
}
}
L
On peut mettre autre chose qu’un "Object", par exemple un
"Arrays" , un "Dog" , etc.
9
Extension avec valeurs
@ExtensionMethod({ Object.class, MyOtherClass.class })
public class DogWithExtension {
public void foo() {
String s1 = "toto";
s1.print(); //  toto
String s2 = null;
s2.print(); //  null
s2.print("vide"); //  vide
}
}
class MyOtherClass {
public static <T> void print(final T value) {
System.out.println(value);
}
public static void print(String value, String other) {
if (value == null || value.isEmpty()) {
System.out.println(other);
} else {
System.out.println(value);
}
9
Extension avec valeurs
L
long start = new Date().getTime();
foo(); // traitement long (ou pas)
long end = new Date().getTime();
long duration = end - start; // 11 ms
Java5 5
< Chrono >
10
Stopwatch sw = new Stopwatch();
sw.start();
foo(); // traitement long (ou pas)
sw.stop();
long duration = sw.elapsedMillis(); // 11 ms
G
Guava
long nano = sw.elapsedTime(NANOSECONDS); // 11179739 ns
long micro = sw.elapsedTime(MICROSECONDS); // 11179 us
long millis = sw.elapsedTime(MILLISECONDS); // 11 ms
 http://blog.developpez.com/guava/p11160/base/le-stop-watch-de-guava/
CharMatcher
11
Impl
12
public class Dog implements Comparable<Dog> {
private Integer id ;
private String name ;
private String fullName ;
...
@Override
public int compareTo(Dog dog) {
return ...;
}
implements List ? aie aie aie
5
Impl
12
@AutoGenMethodStub
public class Dog implements Comparable<Dog> {
private Integer id ;
private String name ;
private String fullName ;
...
L
List<Dog> dogs2 = newArrayList(
new Dog("Rintintin", 45.0, MALE, ...),
new Dog("Pluto", 22.0, MALE, ...),
new Dog("Lulu", 35.6, MALE, ...));
Secondeliste
G
[Rintintin,
Pluto,
Lulu]
[Milou,
Rintintin,
Volt,
Lassie,
Pluto,
Medor]
Liste 2 : dogs2
Liste 1 : dogs
13
And, or, in…
And, or, in…
13
And,or,in... import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.in;
boolean isRintintinInBoth =
and( in(dogs), in(dogs2) )
.apply(new Dog("Rintintin"));
true
import static com.google.common.base.Predicates.or;
boolean isTintinInOne =
or( in(dogs), in(dogs2) )
.apply(new Dog("Tintin");
false
G
G
[Rintintin,
Pluto,
Lulu]
[Milou,
Rintintin,
Volt,
Lassie,
Pluto,
Medor]
Liste2:dogs2
Liste1:dogs
Partition, limit
14
PartitionList<List<FullDog>> partition =
Lists.partition(dogs, 4);
[Milou,
Rintintin,
Volt,
Lassie]
[Pluto,
Medor]
List<FullDog> first4Dogs =
newArrayList(Iterables.limit(dogs, 4));
[Milou,
Rintintin,
Volt,
Lassie]
G
G
Limit
Inférence de type
15
Java
List<Integer> primeNumbers = new ArrayList<Integer>();
List<Integer> primeNumbers = newArrayList();
Guava
public static <E> ArrayList<E> newArrayList() {
return new ArrayList<E>();
}
 http://blog.developpez.com/guava/p11334/collection/inference-de-type-avec-guava
Coût du bloom
16
final List<Dog> dogs = Lists.newArrayList();
final Funnel<Dog> dogFunnel = new Funnel<Dog>() {
@Override
public void funnel(Dog dog, PrimitiveSink sink) {
sink.putString(dog.getName())
.putString(dog.getFullName())
.putString(dog.getRace());
}
};
BloomFilter<Dog> bloom
= BloomFilter.create(dogFunnel, NB_OF_DOGS, 0.01);
final Random rand = new Random();
Stopwatch sw = new Stopwatch();
sw.start();
for (int i = 0; i < NB_OF_DOGS; i++) {
final DogGuava dog = new DogGuava(...);
dogs.add(dog);
}
long duration1 = sw.elapsedTime(MICROSECONDS);
Coût du bloom
16
for (Dog dog : dogs) {
bloom.put(dog);
}
long duration2 = sw.elapsedTime(MICROSECONDS);
boolean inside = dogs.contains(milou);
long duration3 = sw.elapsedTime(MICROSECONDS);
Chiens Add to list Add to bloom Recherche
1 828 17 971 430
10 938 26 643 749
100 2 159 21 859 754
1 000 9 312 49 564 1 192
10 000 42 232 126 505 5 613
100 000 156 065 261 168 14 353
1 000 000 1 594 113 775 300 41 904
< Table >
Guava
// Sexe, couleur, nom
Table<SexeEnum, String, String> dogTable
= HashBasedTable.create();
dogTable.put(MALE, "jaune", "Pluto");
dogTable.put(MALE, "blanc", "Milou");
dogTable.put(MALE, "noir", "Medor");
dogTable.put(FEMALE, "noir", "Lassie");
dogTable.put(FEMALE, "blanc", "Pupuce");
G
17
< Table >
Guava
// Sexe, couleur, nom
Table<SexeEnum, String, String> dogTable
= HashBasedTable.create();
dogTable.put(MALE, "jaune", "Pluto");
dogTable.put(MALE, "blanc", "Milou");
dogTable.put(MALE, "noir", "Medor");
dogTable.put(FEMALE, "noir", "Lassie");
dogTable.put(FEMALE, "blanc", "Pupuce");
Map<String, String> maleRow = dogTable.row(MALE);
println( maleRow )
{ jaune=Pluto, noir=Medor, blanc=Milou }
G
Map<String, String> femaleRow = dogTable.row(FEMALE);
println( femaleRow )
{ noir=Lassie, blanc=Pupuce }
17
< Table >
Guava
// Sexe, couleur, nom
Table<SexeEnum, String, String> dogTable
= HashBasedTable.create();
dogTable.put(MALE, "jaune", "Pluto");
dogTable.put(MALE, "blanc", "Milou");
dogTable.put(MALE, "noir", "Medor");
dogTable.put(FEMALE, "noir", "Lassie");
dogTable.put(FEMALE, "blanc", "Pupuce");
Map<SexeEnum, String> blancColumn
= dogTable.column("blanc");
println( blancColumn )
{ FEMALE=Pupuce, MALE=Milou }
Map<SexeEnum, String> jauneColumn
= dogTable.column("jaune");
println( jauneColumn )
{ MALE=Pluto }
17
Pas d’écrasement des getters existants
18
@Data
public class MicroDog {
private String name;
private Integer age;
public String getName() {
return "*" + name + "*";
}
}
@Test
public void testGetterExistant() {
final String name = "Milou";
final String requiredName = "*Milou*";
final MicroDog dog = new MicroDog();
dog.setName(name);
assertEquals(requiredName, dog.getName());
}
Slides en préparation
I/O
todo
public void lireJava6(String from) {
InputStream in = null;
try {
in = new FileInputStream(from);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1)
break;
...
}
} catch (Exception e) {
...
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
...
}
}
...
Ressources 5
< I/O >
public void lireJava7(String from) {
try(InputStream in = new FileInputStream(from)) {
...
while (true) {
...
}
}
}
Java7 7
< I/O >
Todo
Guava G
< I/O >
Concurrent / future
todo
Todo

More Related Content

What's hot

Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygookPawel Szulc
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slidejonycse
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenPawel Szulc
 
Introduction To Groovy
Introduction To GroovyIntroduction To Groovy
Introduction To Groovymanishkp84
 
Monads asking the right question
Monads  asking the right questionMonads  asking the right question
Monads asking the right questionPawel Szulc
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorFedor Lavrentyev
 
awesome groovy
awesome groovyawesome groovy
awesome groovyPaul King
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVMAndres Almiray
 
BangaloreJUG introduction to kotlin
BangaloreJUG   introduction to kotlinBangaloreJUG   introduction to kotlin
BangaloreJUG introduction to kotlinChandra Sekhar Nayak
 
Sociagrams: How to design a social machine
Sociagrams: How to design a social machineSociagrams: How to design a social machine
Sociagrams: How to design a social machineUlrik Lyngs
 
functional groovy
functional groovyfunctional groovy
functional groovyPaul King
 

What's hot (20)

Functional programming in java
Functional programming in javaFunctional programming in java
Functional programming in java
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygook
 
Hammurabi
HammurabiHammurabi
Hammurabi
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
 
10 classes
10 classes10 classes
10 classes
 
F bound-types
F bound-typesF bound-types
F bound-types
 
Functional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heavenFunctional Programming & Event Sourcing - a pair made in heaven
Functional Programming & Event Sourcing - a pair made in heaven
 
Introduction To Groovy
Introduction To GroovyIntroduction To Groovy
Introduction To Groovy
 
Monads asking the right question
Monads  asking the right questionMonads  asking the right question
Monads asking the right question
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
 
awesome groovy
awesome groovyawesome groovy
awesome groovy
 
Prolog 7-Languages
Prolog 7-LanguagesProlog 7-Languages
Prolog 7-Languages
 
Alastair Butler - 2015 - Round trips with meaning stopovers
Alastair Butler - 2015 - Round trips with meaning stopoversAlastair Butler - 2015 - Round trips with meaning stopovers
Alastair Butler - 2015 - Round trips with meaning stopovers
 
The Groovy Way
The Groovy WayThe Groovy Way
The Groovy Way
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVM
 
BangaloreJUG introduction to kotlin
BangaloreJUG   introduction to kotlinBangaloreJUG   introduction to kotlin
BangaloreJUG introduction to kotlin
 
Sociagrams: How to design a social machine
Sociagrams: How to design a social machineSociagrams: How to design a social machine
Sociagrams: How to design a social machine
 
functional groovy
functional groovyfunctional groovy
functional groovy
 
Polyglot JVM
Polyglot JVMPolyglot JVM
Polyglot JVM
 

Viewers also liked

Le revenu mensuel placements
Le revenu mensuel placementsLe revenu mensuel placements
Le revenu mensuel placementsbeatrice.chenevat
 
Table ronde: éco-tourisme: la structuration d'une offre éco-responsable
Table ronde: éco-tourisme: la structuration d'une offre éco-responsableTable ronde: éco-tourisme: la structuration d'une offre éco-responsable
Table ronde: éco-tourisme: la structuration d'une offre éco-responsablepaysdaix
 
993 169-p50-bassdef infrarouge
993 169-p50-bassdef infrarouge993 169-p50-bassdef infrarouge
993 169-p50-bassdef infrarougeBen Fethi
 
War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...
War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...
War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...WarRam
 
Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12
Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12
Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12Jo Anis
 
Le tour du monde
Le tour du mondeLe tour du monde
Le tour du monde0441492h
 
Leprogressiste2226
Leprogressiste2226Leprogressiste2226
Leprogressiste2226Jo Anis
 
Bilan sarkozy dans le finistère
Bilan sarkozy dans le finistèreBilan sarkozy dans le finistère
Bilan sarkozy dans le finistèregraves146
 
Terminale 3.
Terminale 3.Terminale 3.
Terminale 3.bombonia
 
Ansam asam le_journal_du_balisier_de_saint_joseph[1]
Ansam asam le_journal_du_balisier_de_saint_joseph[1]Ansam asam le_journal_du_balisier_de_saint_joseph[1]
Ansam asam le_journal_du_balisier_de_saint_joseph[1]Jo Anis
 

Viewers also liked (20)

Le revenu mensuel placements
Le revenu mensuel placementsLe revenu mensuel placements
Le revenu mensuel placements
 
Table ronde: éco-tourisme: la structuration d'une offre éco-responsable
Table ronde: éco-tourisme: la structuration d'une offre éco-responsableTable ronde: éco-tourisme: la structuration d'une offre éco-responsable
Table ronde: éco-tourisme: la structuration d'une offre éco-responsable
 
Perte et vol de mobile
Perte et vol de mobilePerte et vol de mobile
Perte et vol de mobile
 
993 169-p50-bassdef infrarouge
993 169-p50-bassdef infrarouge993 169-p50-bassdef infrarouge
993 169-p50-bassdef infrarouge
 
War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...
War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...
War Ram - Lettre d'information sur le cyberespace et la cybersécurité - Mars ...
 
Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12
Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12
Discours Manuéla MONDESIR- Rentrée du Balisier du 22 Sept. 12
 
Test initial VII FR
Test initial VII FRTest initial VII FR
Test initial VII FR
 
PostgreSQL Meetup Nantes #2
PostgreSQL Meetup Nantes #2PostgreSQL Meetup Nantes #2
PostgreSQL Meetup Nantes #2
 
Programme de 14 Jours
Programme de 14 JoursProgramme de 14 Jours
Programme de 14 Jours
 
Le tour du monde
Le tour du mondeLe tour du monde
Le tour du monde
 
Trimestriel mars 2014
Trimestriel mars 2014Trimestriel mars 2014
Trimestriel mars 2014
 
Journal decampagne18fev 2
Journal decampagne18fev 2Journal decampagne18fev 2
Journal decampagne18fev 2
 
Leprogressiste2226
Leprogressiste2226Leprogressiste2226
Leprogressiste2226
 
Débuter avec Twitter (2012)
Débuter avec Twitter (2012)Débuter avec Twitter (2012)
Débuter avec Twitter (2012)
 
Bilan sarkozy dans le finistère
Bilan sarkozy dans le finistèreBilan sarkozy dans le finistère
Bilan sarkozy dans le finistère
 
Programme de 15 jours
Programme de 15 joursProgramme de 15 jours
Programme de 15 jours
 
Memoi re
Memoi reMemoi re
Memoi re
 
Programme de 18 jours !
Programme de 18 jours ! Programme de 18 jours !
Programme de 18 jours !
 
Terminale 3.
Terminale 3.Terminale 3.
Terminale 3.
 
Ansam asam le_journal_du_balisier_de_saint_joseph[1]
Ansam asam le_journal_du_balisier_de_saint_joseph[1]Ansam asam le_journal_du_balisier_de_saint_joseph[1]
Ansam asam le_journal_du_balisier_de_saint_joseph[1]
 

Similar to Guava et Lombok au Bordeaux JUG

No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokusHamletDRC
 
Kotlin : Happy Development
Kotlin : Happy DevelopmentKotlin : Happy Development
Kotlin : Happy DevelopmentMd Sazzad Islam
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java DevelopersAndres Almiray
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. ExperienceMike Fogus
 
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Codemotion
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Wsloffenauer
 
Eclipsecon08 Introduction To Groovy
Eclipsecon08 Introduction To GroovyEclipsecon08 Introduction To Groovy
Eclipsecon08 Introduction To GroovyAndres Almiray
 
JDD 2016 - Philippe Charrière - Golo, The Tiny Language That Gives Super Powers
JDD 2016 - Philippe Charrière -  Golo, The Tiny Language That Gives Super PowersJDD 2016 - Philippe Charrière -  Golo, The Tiny Language That Gives Super Powers
JDD 2016 - Philippe Charrière - Golo, The Tiny Language That Gives Super PowersPROIDEA
 
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018 Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018 Codemotion
 
Scala == Effective Java
Scala == Effective JavaScala == Effective Java
Scala == Effective JavaScalac
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystemApache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystemKostas Saidis
 
BEKK Teknologiradar - Kotlin
BEKK Teknologiradar - KotlinBEKK Teknologiradar - Kotlin
BEKK Teknologiradar - KotlinVegard Veiset
 
Greach 2015 AST – Groovy Transformers: More than meets the eye!
Greach 2015   AST – Groovy Transformers: More than meets the eye!Greach 2015   AST – Groovy Transformers: More than meets the eye!
Greach 2015 AST – Groovy Transformers: More than meets the eye!Iván López Martín
 

Similar to Guava et Lombok au Bordeaux JUG (20)

Unleashing kotlin's power
Unleashing kotlin's powerUnleashing kotlin's power
Unleashing kotlin's power
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
Kotlin : Happy Development
Kotlin : Happy DevelopmentKotlin : Happy Development
Kotlin : Happy Development
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
Kotlin intro
Kotlin introKotlin intro
Kotlin intro
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java Developers
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. Experience
 
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 
Eclipsecon08 Introduction To Groovy
Eclipsecon08 Introduction To GroovyEclipsecon08 Introduction To Groovy
Eclipsecon08 Introduction To Groovy
 
JDD 2016 - Philippe Charrière - Golo, The Tiny Language That Gives Super Powers
JDD 2016 - Philippe Charrière -  Golo, The Tiny Language That Gives Super PowersJDD 2016 - Philippe Charrière -  Golo, The Tiny Language That Gives Super Powers
JDD 2016 - Philippe Charrière - Golo, The Tiny Language That Gives Super Powers
 
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018 Meetup di GDG Italia - Leonardo Pirro -  Codemotion Rome 2018
Meetup di GDG Italia - Leonardo Pirro - Codemotion Rome 2018
 
Scala == Effective Java
Scala == Effective JavaScala == Effective Java
Scala == Effective Java
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystemApache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystem
 
F# for C# Programmers
F# for C# ProgrammersF# for C# Programmers
F# for C# Programmers
 
BEKK Teknologiradar - Kotlin
BEKK Teknologiradar - KotlinBEKK Teknologiradar - Kotlin
BEKK Teknologiradar - Kotlin
 
Greach 2015 AST – Groovy Transformers: More than meets the eye!
Greach 2015   AST – Groovy Transformers: More than meets the eye!Greach 2015   AST – Groovy Transformers: More than meets the eye!
Greach 2015 AST – Groovy Transformers: More than meets the eye!
 

More from Thierry Leriche-Dessirier

More from Thierry Leriche-Dessirier (18)

Disc l'essentiel
Disc l'essentielDisc l'essentiel
Disc l'essentiel
 
Rapport DISC Pro de Lucie Durand
Rapport DISC Pro de Lucie DurandRapport DISC Pro de Lucie Durand
Rapport DISC Pro de Lucie Durand
 
Rapport de test DISC de Groupe (Laurent Duval)
Rapport de test DISC de Groupe (Laurent Duval)Rapport de test DISC de Groupe (Laurent Duval)
Rapport de test DISC de Groupe (Laurent Duval)
 
Memento DISC Influent (English)
Memento DISC Influent (English)Memento DISC Influent (English)
Memento DISC Influent (English)
 
Le management en couleurs avec le DISC
Le management en couleurs avec le DISCLe management en couleurs avec le DISC
Le management en couleurs avec le DISC
 
Memento DISC Stable
Memento DISC StableMemento DISC Stable
Memento DISC Stable
 
Memento DISC Influent
Memento DISC InfluentMemento DISC Influent
Memento DISC Influent
 
Memento DISC Dominant
Memento DISC DominantMemento DISC Dominant
Memento DISC Dominant
 
Memento Disc Consciencieux
Memento Disc ConsciencieuxMemento Disc Consciencieux
Memento Disc Consciencieux
 
Management en couleur avec DISC à Agile Tour Paris 2015
Management en couleur avec DISC à Agile Tour Paris 2015Management en couleur avec DISC à Agile Tour Paris 2015
Management en couleur avec DISC à Agile Tour Paris 2015
 
Management en couleur avec DISC
Management en couleur avec DISCManagement en couleur avec DISC
Management en couleur avec DISC
 
Les algorithmes de tri
Les algorithmes de triLes algorithmes de tri
Les algorithmes de tri
 
Cours de Génie Logiciel / ESIEA 2016-17
Cours de Génie Logiciel / ESIEA 2016-17Cours de Génie Logiciel / ESIEA 2016-17
Cours de Génie Logiciel / ESIEA 2016-17
 
Puzzle 2 (4x4)
Puzzle 2 (4x4)Puzzle 2 (4x4)
Puzzle 2 (4x4)
 
Guava au Paris JUG
Guava au Paris JUGGuava au Paris JUG
Guava au Paris JUG
 
Memento scrum-equipe
Memento scrum-equipeMemento scrum-equipe
Memento scrum-equipe
 
Memento java
Memento javaMemento java
Memento java
 
Cours de Génie Logiciel / ESIEA 2013-2014
Cours de Génie Logiciel / ESIEA 2013-2014 Cours de Génie Logiciel / ESIEA 2013-2014
Cours de Génie Logiciel / ESIEA 2013-2014
 

Recently uploaded

办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一
办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一
办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一Fi L
 
办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一
办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一
办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一F La
 
Pharmaceutical Packaging for the elderly.pdf
Pharmaceutical Packaging for the elderly.pdfPharmaceutical Packaging for the elderly.pdf
Pharmaceutical Packaging for the elderly.pdfAayushChavan5
 
Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)
Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)
Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)jennyeacort
 
How to Be Famous in your Field just visit our Site
How to Be Famous in your Field just visit our SiteHow to Be Famous in your Field just visit our Site
How to Be Famous in your Field just visit our Sitegalleryaagency
 
2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degreeyuu sss
 
PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024
PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024
PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024CristobalHeraud
 
昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档
昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档
昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档208367051
 
韩国SKKU学位证,成均馆大学毕业证书1:1制作
韩国SKKU学位证,成均馆大学毕业证书1:1制作韩国SKKU学位证,成均馆大学毕业证书1:1制作
韩国SKKU学位证,成均馆大学毕业证书1:1制作7tz4rjpd
 
西北大学毕业证学位证成绩单-怎么样办伪造
西北大学毕业证学位证成绩单-怎么样办伪造西北大学毕业证学位证成绩单-怎么样办伪造
西北大学毕业证学位证成绩单-怎么样办伪造kbdhl05e
 
'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,
'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,
'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,Aginakm1
 
Architecture case study India Habitat Centre, Delhi.pdf
Architecture case study India Habitat Centre, Delhi.pdfArchitecture case study India Habitat Centre, Delhi.pdf
Architecture case study India Habitat Centre, Delhi.pdfSumit Lathwal
 
ARt app | UX Case Study
ARt app | UX Case StudyARt app | UX Case Study
ARt app | UX Case StudySophia Viganò
 
DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...
DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...
DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...Rishabh Aryan
 
Passbook project document_april_21__.pdf
Passbook project document_april_21__.pdfPassbook project document_april_21__.pdf
Passbook project document_april_21__.pdfvaibhavkanaujia
 
3D Printing And Designing Final Report.pdf
3D Printing And Designing Final Report.pdf3D Printing And Designing Final Report.pdf
3D Printing And Designing Final Report.pdfSwaraliBorhade
 
办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一
办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一
办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一z xss
 
Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...
Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...
Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...Yantram Animation Studio Corporation
 
原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档208367051
 

Recently uploaded (20)

办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一
办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一
办理学位证(TheAuckland证书)新西兰奥克兰大学毕业证成绩单原版一比一
 
办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一
办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一
办理(宾州州立毕业证书)美国宾夕法尼亚州立大学毕业证成绩单原版一比一
 
Pharmaceutical Packaging for the elderly.pdf
Pharmaceutical Packaging for the elderly.pdfPharmaceutical Packaging for the elderly.pdf
Pharmaceutical Packaging for the elderly.pdf
 
Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)
Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)
Call Us ✡️97111⇛47426⇛Call In girls Vasant Vihar༒(Delhi)
 
How to Be Famous in your Field just visit our Site
How to Be Famous in your Field just visit our SiteHow to Be Famous in your Field just visit our Site
How to Be Famous in your Field just visit our Site
 
2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
2024新版美国旧金山州立大学毕业证成绩单pdf电子版制作修改#毕业文凭制作#回国入职#diploma#degree
 
PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024
PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024
PORTFOLIO DE ARQUITECTURA CRISTOBAL HERAUD 2024
 
昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档
昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档
昆士兰大学毕业证(UQ毕业证)#文凭成绩单#真实留信学历认证永久存档
 
韩国SKKU学位证,成均馆大学毕业证书1:1制作
韩国SKKU学位证,成均馆大学毕业证书1:1制作韩国SKKU学位证,成均馆大学毕业证书1:1制作
韩国SKKU学位证,成均馆大学毕业证书1:1制作
 
西北大学毕业证学位证成绩单-怎么样办伪造
西北大学毕业证学位证成绩单-怎么样办伪造西北大学毕业证学位证成绩单-怎么样办伪造
西北大学毕业证学位证成绩单-怎么样办伪造
 
'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,
'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,
'CASE STUDY OF INDIRA PARYAVARAN BHAVAN DELHI ,
 
Architecture case study India Habitat Centre, Delhi.pdf
Architecture case study India Habitat Centre, Delhi.pdfArchitecture case study India Habitat Centre, Delhi.pdf
Architecture case study India Habitat Centre, Delhi.pdf
 
ARt app | UX Case Study
ARt app | UX Case StudyARt app | UX Case Study
ARt app | UX Case Study
 
DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...
DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...
DAKSHIN BIHAR GRAMIN BANK: REDEFINING THE DIGITAL BANKING EXPERIENCE WITH A U...
 
Passbook project document_april_21__.pdf
Passbook project document_april_21__.pdfPassbook project document_april_21__.pdf
Passbook project document_april_21__.pdf
 
Call Girls in Pratap Nagar, 9953056974 Escort Service
Call Girls in Pratap Nagar,  9953056974 Escort ServiceCall Girls in Pratap Nagar,  9953056974 Escort Service
Call Girls in Pratap Nagar, 9953056974 Escort Service
 
3D Printing And Designing Final Report.pdf
3D Printing And Designing Final Report.pdf3D Printing And Designing Final Report.pdf
3D Printing And Designing Final Report.pdf
 
办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一
办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一
办理(UC毕业证书)查尔斯顿大学毕业证成绩单原版一比一
 
Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...
Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...
Unveiling the Future: Columbus, Ohio Condominiums Through the Lens of 3D Arch...
 
原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档
原版1:1定制堪培拉大学毕业证(UC毕业证)#文凭成绩单#真实留信学历认证永久存档
 

Guava et Lombok au Bordeaux JUG

  • 1. Milou fait un régime Guava - Lombok
  • 3. Thierry Leriche-Dessirier icauda.com  Consultant JEE freelance  Professeur de Génie Logiciel à l’ESIEA  Rédacteur pour Programmez  Rédacteur pour Developpez.com @thierryleriche
  • 5. 13 OOO OOO pages vues par mois 5 500 000visites par mois 2 500 000visites uniques par mois 5 000 messages forum par jour
  • 6. Agenda  Milou est trop lourd (intro)  Lombok (et Lombok-pg) en action  Tour d’horizon de Guava
  • 7. Milou est trop lourd (et doit faire un régime) I am Milou
  • 8. public class Dog { private Integer id ; private String name ; private String fullName ; private SexeEnum sex ; private Date birthday ; private String race ; private Boolean lof ; private Double weight ; private Double size ; private List<String> colors ; ... DOG 5
  • 9.  id  name  fullName  sex  birthday  race  lof  weight  size  Colors  Constructeurs  Getters / setters  toString ()  equals ()  hashCode ()  compareTo ()
  • 10. clic clic démo  id  name  fullName  sex  birthday  race  lof  weight  size  Colors  Constructeurs  Getters / setters  toString ()  equals ()  hashCode ()  compareTo ()
  • 11. public class Dog implements Comparable<Dog> { ... @Override public int compareTo(Dog other) { int result = 0; result = name.compareTo(other.name); if (result != 0) { return result; } ... } Code très limite… NPE ?...
  • 12.  id  name  fullName  sex  birthday  race  lof  weight  size  Colors  Constructeurs  Getters / setters  toString ()  equals ()  hashCode ()  compareTo ()  210 lignes10 attributs
  • 14. VachercherGuava  toString ()  equals ()  hashCode ()  compareTo () Commons  FAQ 1-2
  • 16. public String toString() { return "Dog [id=" + id + ", name=" + name + ", fullName=" + fullName + ", sex=" + sex + ", birthday=" + birthday + ", race=" + race + ", lof=" + lof + ", weight=" + weight + ", size=" + size + ", colors=" + colors + "]"; } Java5 5  toString () Simple, efficace et bien pourri 
  • 17. public String toString() { StringBuilder sb = new StringBuilder(); sb.append(Dog.class.getSimpleName()) .append("[id=").append(id) .append(", name=").append(name) .append(", fullName=").append(fullName) ... .append(", colors=").append(colors); return sb.toString(); } Java5 5  toString () Mieux mais sans plus 
  • 18. public String toString() { return Objects.toStringHelper(this) .add("id", id) .add("name", name) .add("fullName", fullName) ... .add("colors", colors) .toString(); } Guava G  toString () Builder
  • 19. public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Dog other = (Dog) obj; if (birthday == null) { if (other.birthday != null) return false; } else if (!birthday.equals(other.birthday)) return false; if (fullName == null) { if (other.fullName != null) return false; ... } else if (!race.equals(other.race)) return false; if (sex != other.sex) return false; return true; } Java5 5  equals () birthday, fullname, name, race et sex Carrément illisible 
  • 20. public boolean equals(Object obj) { if (!(obj instanceof Dog)) return false; Dog other = (Dog) obj; return Objects.equal(birthday, other.birthday) && Objects.equal(fullname, other.fullname) && Objects.equal(name, other.name) && Objects.equal(race, other.race) && sex == other.sex; } Guava G  equals () birthday, fullname, name, race et sex
  • 21. public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((birthday == null) ? 0 : birthday.hashCode()); result = prime * result + ((fullName == null) ? 0 : fullName.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((race == null) ? 0 : race.hashCode()); result = prime * result + ((sex == null) ? 0 : sex.hashCode()); return result; } Java5 5  hashCode () birthday, fullname, name, race et sex
  • 22. public int hashCode() { return Objects.hashCode(birthday, fullName, name, race, sex); } Guava G  hasCode() birthday, fullname, name, race et sex
  • 23. public int compareTo(Dog other) { int result = 0; result = name.compareTo(other.name); if (result != 0) { return result; } result = fullname.compareTo(other.fullname); if (result != 0) { return result; } ... } Java5 5  compareTo () name, fullname, birthday, weight, size, race et sex
  • 25. public int compareTo(Dog other) { return ComparisonChain.start() .compare(name, other.name) .compare(fullName, other.fullName) .compare(birthday, other.birthday) .compare(weight, other.weight) .compare(size, other.size) .compare(race, other.race) .compare(sex, other.sex) .result(); } Guava G  compareTo () name, fullname, birthday, weight, size, race et sex
  • 28.  @NoArgsConstructor / @RequiredArgsConstructor / @AllArgsConstructor  constructeurs  @Getter / @Setter  @ToString  @EqualsAndHashCode  @Data  @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor Régime
  • 29. clic clic démo Régime  @NoArgsConstructor / @RequiredArgsConstructor / @AllArgsConstructor  @Getter / @Setter  @ToString  @EqualsAndHashCode  @Data
  • 30. 210lignes de code 10attributs Java 12lignes + 2-3@ + compareTo()Lombok
  • 31. name, sex  @RequiredArgsConstructor(staticName = "of") public class Dog { private Integer id; @NonNull private String name;  private String fullName; @NonNull private SexeEnum sex;  private Date birthday; ... Dog dog = Dog.of("Milou", MALE); Factory L
  • 32. name, sex  private Dog(@NonNull final String name, @NonNull final SexeEnum sex) { if (name == null) throw new NullPointerException("name"); if (sex == null) throw new NullPointerException("sex"); this.name = name; this.sex = sex; } public static Dog of(@NonNull final String name, @NonNull final SexeEnum sex) { return new Dog(name, sex); } @RequiredArgsConstructor(staticName = "of") public class Dog { private Integer id; @NonNull private String name;  private String fullName; @NonNull private SexeEnum sex;  private Date birthday; ... Dog dog = Dog.of("Milou", MALE); Factory L
  • 34.  @Cleanup  @Synchronized  @SneakyThrows  @Log  @Delegate  val Pratique
  • 35. public void lireJava6(String from) { InputStream in = null; try { in = new FileInputStream(from); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; ... } } catch (Exception e) { ... } finally { if (in != null) { try { in.close(); } catch (Exception e) { ... } } ... Ressources 5
  • 36. public void lire(String from) throws IOException { @Cleanup InputStream in = new FileInputStream(from); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; ... } } Ressources L
  • 39. Délombok@Data public class Dog { private Integer id; private String name; private String fullName; private SexeEnum sex; private Date birthday; private String race; private Boolean lof; private Double weight; private Double size; private List<String> colors; } 5public class Dog { private Integer id; private String name; private String fullName; ... private List<String> colors; public DogLombok() { } @java.lang.Override @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Obje if (o == this) return true; if (o == null) return false; if (o.getClass() != this.getClass()) ret final Dog other = (Dog)o; if (this.getId() == null ? other.getId() ... @java.lang.Override @java.lang.SuppressWarnings("all") public int hashCode() { final int PRIME = 31; int result = 1; result = result * PRIME + (this.getId() mvn lombok:delombok 5
  • 41.  @Action  @Function  @EnumId  @Rethrow / @Rethrows  @Singleton  @AutoGenMethodStub  @BoundPropertySupport / @BoundSetter  @DoPrivileged  @ExtensionMethod  @ListenerSupport  @WriteLock / @ReadLock  @Await / @Signal / @AwaitBeforeAndSignalAfter  @Sanitize.Normalize / .With  @SwingInvokeLater / @SwingInvokeAndWait  @Validate.NotEmpty / .NotNull / .With  @VisibleForTesting AnnotationsPg  @Builder  @LazyGetter  @FluentSetter  @Predicate
  • 42.  @FluentSetter @Getter public class Dog { private Integer id ; private String name ; private String fullName ; ... DogLombok dog = new DogLombok(); dog.name("Milou").sex(MALE); Fluent println( dog.getName()); //  Milou println( dog.getSex()); //  MALE L
  • 43.  @Builder @Getter public class Dog { private Integer id ; private String name ; private String fullName ; ... Dog dog = Dog.dog().name("Milou").sex(MALE).build(); Builder println( dog.getName()); //  Milou println( dog.getSex()); //  MALE L
  • 44. @ExtensionMethod({ Dog.class, MyDogExtensionClass.class }) public class DogWithExtension { public void foo() { Dog milou = new Dog("Milou", 12.5, ...); boolean isTooFat = milou.isTooFat(); } } extension L Avec paramètres  FAQ 9  http://blog.developpez.com/todaystip/p11165/dev/java/extensionmethod-de-lombok-pg/ class MyDogExtensionClass { public static boolean isTooFat(final Dog dog) { double imc = dog.getWeight() / pow(dog.getSize(), 2); return 31 < imc; } }
  • 45. Lombok or not Lombok ? Avantages et inconvénients
  • 46. Pro/Cons  Byte code modifié   Version en 0.x  Documentation des prog ?  Magique ?  Compacité  Lecture simplifiée  Code normée  Délombok (pour essayer)
  • 49. List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); Java5 5 < new Vs static factories >
  • 50. Java5 Map<String, List<String>> trucs = new HashMap<String, List<String>>(); Map<? extends Person, Map<String, List<String>>> trucs = new TreeMap<? extends Person, Map<String, List<String>>>(); Map<? extends Wrapper<String, Sex, Person>, Map<String, List<Set<Adress<String, Integer, Country>>>>> trucs = ... durdur? 5 List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); 5 < new Vs static factories >
  • 51. Java5 List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); Java7 Qui utilise Java 7 en prod ? 7 List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); 5 < new Vs static factories >
  • 52. Java5Java7 Qui utilise Java 7 en prod ? List<Integer> primeNumbers = newArrayList(); Set<String> colors = newTreeSet(); Map<String, Integer> ages = newHashMap(); Guava Dès maintenant ! G List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); 5 7 < new Vs static factories >
  • 53. Java5Java7 Qui utilise Java 7 en prod ? List<Integer> primeNumbers = newArrayList(); Set<String> colors = newTreeSet(); Map<String, Integer> ages = newHashMap(); Guava Dès maintenant ! G List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); 5 7 var primeNumbers = new ArrayList<Integer>(); -> primeNumbers.size(); ... Lombok < new Vs static factories > L
  • 54. List<Dog> dogs = newArrayList( new Dog("Milou", 12.5, MALE, ...), new Dog("Rintintin", 45.0, MALE, ...), new Dog("Volt", 10.3, MALE, ...), new Dog("Lassie", 45.0, FEMALE, ...), new Dog("Pluto", 22.0, MALE, ...), new Dog("Medor", 35.6, MALE, ...)); Listofdogs G [Milou, Rintintin, Volt, Lassie, Pluto, Medor] < new Vs static factories >
  • 55. Immutables Pour que ça ne change pas
  • 57. Quand ? immutable mutable On se demande souvent si une liste doit être immutable mais c’est prendre le problème dans le mauvais sens. La plupart du temps, ce qu’il faut vraiment se demander, c’est si la liste a besoin d’être mutable.
  • 58. Java5Set<Integer> temp = new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7)); Set<Integer> primes = Collections.unmodifiableSet(temp); < unmodifiables Vs immutables >
  • 59. Java5 Set<Integer> primes = ImmutableSet.of(1, 2, 3, 5, 7); Set<Integer> temp = new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7)); Set<Integer> primes = Collections.unmodifiableSet(temp); Guava < unmodifiables Vs immutables > G
  • 60. OfImmutableSet.of(E e1) ImmutableSet.of(E e1, E e2) ImmutableSet.of(E e1, E e2, E e3) ImmutableSet.of(E e1, E e2, E e3, E e4) ImmutableSet.of(E e1, E e2, E e3, E e4, E e5) ImmutableSet.of(E e1, E e2, E e3, E e4, E e5, E e6, E...) Ne prend pas de null Of ImmutableSet.of() Vide Map et List  FAQ 4 < unmodifiables Vs immutables > G  http://blog.developpez.com/guava/p10589/collection/title-212/
  • 61. Java5public class Dog { private String name; ... private List<String> colors; public Dog(String name, List<String> colors) { this.name = name; ... this.colors = Collections.unmodifiableList( new ArrayList<String>(colors)); } public List<String> getColors() { return colors; } 5 < Copie de défense >
  • 62. Guavapublic class Dog { private String name; ... private ImmutableList<String> colors; public Dog(String name, List<String> colors) { this.name = name; ... this.colors = ImmutableList.copyOf(colors); } public ImmutableList<String> getColors() { return colors; } G Message clair < Copie de défense >
  • 63. Collections en plus Multimap, Bipap, Multiset, Table
  • 64. Java5Map<String, List<String>> dogFavoriteColors = new HashMap<String, List<String>>(); 5 < Multi Map > List<String> milouColors = dogFavoriteColors.get("Milou"); if(milouColors == null) { milouColors = new ArrayList<String>(); dogFavoriteColors.put("Milou",milouColors); } milouColors.add("Vert"); 5
  • 65. Java5Map<String, List<String>> dogFavoriteColors = new HashMap<String, List<String>>(); 5 < Multi Map > List<String> milouColors = dogFavoriteColors.get("Milou"); if(milouColors == null) { milouColors = new ArrayList<String>(); dogFavoriteColors.put("Milou",milouColors); } milouColors.add("Vert"); 5 Guava Multimap<String, String> dogFavoriteColors = HashMultimap.create(); dogFvoriteColors2.put("Milou", "Jaune"); dogFavoriteColors2.put("Milou", "Rouge"); G
  • 66. < Bi Map > GuavaBiMap<String, Dog> tatouages = HashBiMap.create(); tatouages.put("ABC123", new Dog("Milou") ); tatouages.put("MBD324", new Dog("Volt") ); tatouages.put("JFT672", new Dog("Lassie") ); ABC123=Milou MDB324=Volt JFT672=LassieIl est possible de changer la valeur associée à une clé mais pas d'avoir deux clés avec la même valeur (IllegalArgumentException). println( tatouages ); Une map bijective {ABC123=Milou, MBD324=Volt, JFT672=Lassie} G println( tatouages.inverse() ); {Milou=ABC123, Volt=MBD324, Lassie=JFT672}
  • 67. < Multi Set > Guava Multiset<Integer> ages = HashMultiset.create(); ages.add(2); ages.add(3); ages.add(7); ages.add(11); ages.add(3); ages.add(5); println( ages ); println( ages.count(3) ) [2, 3 x 2, 5, 7, 11] 2 G
  • 69.  toString ()  equals ()  hashCode ()  compareTo ()
  • 70. public class Dog { private Integer id ; private String name ; private String fullName ; ... public Dog(String name, String fullName, ...) { if(name == null) { throw new NPE("Le nom bla bla"); } if(fullName == null) { throw new NPE("bla bla"); } ... this.name = name; this.fullName = fullName; ... } DOG 5 < Preconditions >
  • 71. import static com.google.common.base.Preconditions.*; public class Dog { private Integer id ; private String name ; private String fullName ; ... public Dog(String name, String fullName, ...) { this.name = checkNotNull(name, "bla bla"); this.fullName = checkNotNull(fullName, "bla bla"); ... } DOG G < Preconditions > checkNotNull()  NPE checkArgument()  IAE checkState()  ISE
  • 72. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); List<String> dogNames = newArrayList("Lassie", "Volt", "Milou"); StringBuilder sb = new StringBuilder(); boolean first = true; for (String name : dogNames) { if(name != null || name.trim().isEmpty()) { continue; } if (!first) { sb.append(", "); } sb.append(name); first = false; } String names = sb.toString(); Java classique G"Lassie, Volt, Milou"
  • 73. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", null, "Milou"));  NPE  G"Lassie, Volt, Milou"
  • 74. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", null, "Milou")); String names = Joiner.on(", ") .skipNulls() .join(newArrayList("Lassie", "Volt", null, "Milou")); "Lassie, Volt, Milou"  NPE  G"Lassie, Volt, Milou" G
  • 75. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", null, "Milou")); String names = Joiner.on(", ") .skipNulls() .join(newArrayList("Lassie", "Volt", null, "Milou")); "Lassie, Volt, Milou"  NPE  String names = Joiner.on(", ") .useForNull("Anonymous")) .join(newArrayList("Lassie", "Volt", null, "Milou")); "Lassie, Volt, Anonymous, Milou" G"Lassie, Volt, Milou" G G  http://blog.developpez.com/guava/p11054/base/joiner-pour-assembler-des-items/
  • 76. Splitter Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, Milou"); [ "Lassie", "Volt", "Milou" ]
  • 77. Splitter Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, Milou"); [ "Lassie", "Volt", "Milou" ] Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, ,Milou"); [ "Lassie", "Volt", " ", "Milou" ]
  • 78. Splitter Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, Milou"); [ "Lassie", "Volt", "Milou" ] Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, ,Milou"); [ "Lassie", "Volt", " ", "Milou" ] Iterable<String> dogNames = Splitter.on(",") .trimResults() .split("Lassie, Volt, ,Milou"); [ "Lassie", "Volt", "", "Milou" ]
  • 79. Splitter Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, Milou"); [ "Lassie", "Volt", "Milou" ] Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, ,Milou"); [ "Lassie", "Volt", " ", "Milou" ] Iterable<String> dogNames = Splitter.on(",") .trimResults() .split("Lassie, Volt, ,Milou"); Iterable<String> dogNames = Splitter.on(",") .trimResults() .omitEmptyStrings() .split("Lassie, Volt, ,Milou"); G[ "Lassie", "Volt", "Milou" ]  http://blog.developpez.com/guava/p11045/annotation/splitter-pour-separer-des-items/ [ "Lassie", "Volt", "", "Milou" ]
  • 80. Optional Wrapper Optional <T> Dog dog = new Dog("Milou", ...); Optional<Dog> opt = Optional.of(dog); assertTrue( opt.isPresent() ); assertEquals( "Milou", opt.get().getName() );
  • 81. Optional Wrapper Optional <T> Dog dog = new Dog("Milou", ...); Optional<Dog> opt = Optional.of(dog); assertTrue( opt.isPresent() ); assertEquals( "Milou", opt.get().getName() ); Optional<Dog> opt = Optional.absent(); assertFalse( opt.isPresent() ); opt.get();  ISE
  • 82. Optional Wrapper Optional <T> Dog dog = new Dog("Milou", ...); Optional<Dog> opt = Optional.of(dog); assertTrue( opt.isPresent() ); assertEquals( "Milou", opt.get().getName() ); Optional<Dog> opt = Optional.absent(); assertFalse( opt.isPresent() ); opt.get();  ISE Dog dog = null; Optional<Dog> opt = Optional.of(dog);  NPE Optional<Dog> opt = Optional.fromNullable(dog);
  • 83.  http://blog.developpez.com/guava/p11163/base/le-wrapper-optional-de-guava/ Optional Wrapper Optional <T> Dog dog = new Dog("Milou", ...); Optional<Dog> opt = Optional.of(dog); assertTrue( opt.isPresent() ); assertEquals( "Milou", opt.get().getName() ); Optional<Dog> opt = Optional.absent(); assertFalse( opt.isPresent() ); opt.get();  ISE Dog dog = null; Optional<Dog> opt = Optional.of(dog);  NPE Optional<Dog> opt = Optional.fromNullable(dog); Dog dog = null; Optional<Dog> opt = Optional.fromNullable(dog); Dog dog2 = opt.or( new Dog("noname", ...) ); assertEquals( "noname", dog2.getName() );
  • 86. public class SuperChien implements SuperHero { private String surnom ; private double poids ; private Set<String> couleursCostume ; private Set<String> pouvoirs ; ... SuperChien 5 Les héros peuvent avoir plusieurs costumes donc je n’utilise pas un ImmutableSet. Idem pour les pouvoirs dont la liste augmente avec l’expérience.
  • 87. TransformationList<SuperChien> superChiens = Lists.transform(dogs, new Function<Dog, SuperChien>() { @Override public SuperChien apply(Dog dog) { SuperChien chien = new SuperChien(); chien.setSurnom("Super " + dog.getName()); chien.setPoids(dog.getWeight()); chien.setCouleursCostume(newHashSet(dog.getColors())) chien.setPouvoirs(newHashSet("Code en Java", "Vole")) ... return chien; } }); [Super Milou, Super Rintintin, Super Volt, Super Lassie, Super Pluto, Super Medor] < Transformation > G
  • 88. List<SuperChien> superChiens = Lists.transform(dogs, new Function<Dog, SuperChien>() { @Override public SuperChien apply(Dog dog) { SuperChien chien = new SuperChien(); ... return chien; } });  Vue (lazy)  size / isEmpty dispo   Pas pour traitements répétés   FAQ 3 List<SuperChien> chiens = newArrayList(Lists.transform(... ImmutableList<SuperChien> chiens = ImmutableList.copyOf(Lists.transform(... Transformation < Transformation > G
  • 89. FiltrePredicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; } } Iterable<Dog> maleDogs = Iterables.filter(dogs, malePredicate); < Filtre > G G[Milou, Rintintin, Volt, Pluto, Medor]
  • 90. FiltrePredicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; } } Iterable<Dog> maleDogs = Iterables.filter(dogs, malePredicate); Dog firstMaleDog = Iterables.find(dogs, malePredicate); < Filtre > G G [Milou, Rintintin, Volt, Pluto, Medor] GMilou
  • 91. FiltrePredicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; } } Iterable<Dog> maleDogs = Iterables.filter(dogs, malePredicate); Dog firstMaleDog = Iterables.find(dogs, malePredicate); Dog firstMaleDog = Iterables.find(femaleDogs, malePredicate, DEFAULT_DOG ); Default dog < Filtre > G G GMilou [Milou, Rintintin, Volt, Pluto, Medor]
  • 92. Pasfluent Predicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; }}; Function<FullDog, String> nameFunction = new Function<FullDog, String>() { public String apply(FullDog dog) { return dog.getName(); }}; Iterable<FullDog> maleDogs = Iterables.filter(dogs, malePredicate); Iterable<String> maleNames = Iterables.transform(maleDogs, nameFunction); [Milou, Rintintin, Volt, Pluto, Medor] < Fluent or not fluent ? > G G G
  • 93. Pasfluent Iterable<FullDog> maleDogs = Iterables.filter(dogs, malePredicate); Iterable<String> maleNames = Iterables.transform(maleDogs, nameFunction); [Milou, Rintintin, Volt, Pluto, Medor] List<String> maleNames2 = FluentIterable.from(dogs) .filter(malePredicate) .transform(nameFunction) .toImmutableList(); Fluent Guava 12.0 < Fluent or not fluent ? > G G  http://blog.developpez.com/guava/p11092/annotation/fluentiterable-sur- mon-chien-guava/
  • 95. WebService public class DogService { @Inject private PetShopWebService service; public Integer getNumberDogsSoldYesterday() { return service.checkSales( "dog" ); } < Memoization > 5
  • 96. WebService public class DogService { @Inject private PetShopWebService service; public Integer getNumberDogsSoldYesterday() { return service.checkSales( "dog" ); } < Memoization > 5Cachemanuel private Integer nbOfDogsSold; public Integer getNumberDogsSoldYesterday() { if (nbOfDogsSold == null) { nbOfDogsSold = service.checkSales( "dog" ); } return nbOfDogsSold; } 5 Double check null…
  • 97. Guava public class DogService { @Inject private PetShopWebService service; private Supplier<Integer> nbOfDogsSoldSupplier = Suppliers.memoize( new Supplier<Integer>() { public Integer get() { return service.checkSales( "dog" ); } }); public Integer getNumberDogsSoldYesterday() { return nbOfDogsSoldSupplier.get(); } < Memoization > G
  • 98. Guava public class DogService { @Inject private PetShopWebService service; private Supplier<Integer> nbOfDogsSoldSupplier = Suppliers.memoizeWithExpiration( new Supplier<Integer>() { public Integer get() { return service.checkSales( "dog" ); } }, 1, TimeUnit.DAYS ); public Integer getNumberDogsSoldYesterday() { return nbOfDogsSoldSupplier.get(); } < Memoization > G
  • 99. WebService public class DogService { @Inject private PetShopWebService service; private Map<String, Dog> dogMap = Maps.newHashMap(); public Dog getDog(String name) { Dog dog = dogMap.get(name); if(dog == null) { dog = service.getAnimal( "dog", name ); // type-name dogMap.put( name, dog ); } return dog; } < Cache > 5 Quid du timeout ? Max ?
  • 100. Guava public class DogService { @Inject private PetShopWebService service; private LoadingCache<String, Dog> dogCache = CacheBuilder.newBuilder() .maximumSize(2000) .expireAfterWrite(30, TimeUnit.MINUTES) .build(new CacheLoader<String, Dog>() { public Dog load(String key) { return service.getAnimal( "dog", key ); } }); public Dog getDog(String name) { return dogCache.get( name ); // + try-catch } < Cache > G
  • 102. Hash HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putInt(123) .putString("Milou") .hash(); byte[] bytes = hc.asBytes();  md5  Murmur3 128 bits  Murmur3 32 bits  Sha1  Sha256  Sha512  goodFastHash G
  • 103. Préparation int NB_OF_DOGS = 100000; List<Dog> dogs = newArrayList(); Random rand = new Random(); for (int i = 0; i < NB_OF_DOGS; i++) { Dog dog = new Dog(); dog.setName("abc" + rand.nextInt(999)); ... dogs.add(dog); } dogs.add(milou); boolean isInList = dogs.contains(milou); true (14 ms) final Dog milou = new Dog(); milou.setName("Milou"); ... boolean isInList = dogs.contains(milou); false (14 ms) contains < Is in list ? > 5 5
  • 104. Bloomfilter Funnel<Dog> dogFunnel = new Funnel<Dog>() { public void funnel(Dogdog, PrimitiveSink sink) { sink.putString(dog.getName()) .putString(dog.getFullName()) .putString(dog.getRace()); }}; BloomFilter<Dog> bloom = BloomFilter.create(dogFunnel, NB_OF_DOGS, 0.01); for (int i = 0; i < NB_OF_DOGS; i++) { ... bloom.put(dog); bloom.put(milou); boolean isInList = bloom.mightContain(milou); true (0 ms) boolean isInList = bloom.mightContain(milou); false (0 ms) < Is in list ? > G  http://blog.developpez.com/guava/p11149/collection/bloom-filter-de-guava-13/ Guava 13
  • 105. Guava or not Guava ? Avantages et inconvénients
  • 106. Pro/Cons  Ne pas en abuser…  Utile  Bonnes pratiques
  • 107. LIENS
  • 109. ICAUDA http://icauda.com http://icauda.com/articles.html (articles) http://icauda.com/cours.html (slides) Blog Guava http://blog.developpez.com/guava « Simplifier le code de vos beans Java à l'aide de Commons Lang, Guava et Lombok » http://thierry-leriche-dessirier.developpez.com/tutoriels/ java/simplifier-code-guava-lombok (article) @thierryleriche
  • 110. MERCI
  • 111. FAQ/Bonus 1. Guava Vs Commons 2. Régime façon Apache 3. Fonctionnal prog Vs boucle for 4. Créer des Maps 5. Charsets 6. Converter Spring 7. Orderings 8. Licences 9. Extension avec valeurs 10. Chrono 11. CharMatcher 12. Impl 13. And, or, in… 14. Partition, limit 15. Inférence de type 16. Coût du bloom 17. Table 18. Ecrasement des getters existants
  • 112. Guava Vs Commons ? http://tinyurl.com/guava-vs-apache 1
  • 113. Régime : la méthode Commons ? 2 public String toString() { return new ToStringBuilder(this) .append("id", id) .append("name", name) .append("fullName", fullName) ... .append("colors", colors) .toString(); } toString L
  • 114. Régime : la méthode Commons ? 2 public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Dog)) return false; Dog other = (Dog) obj; return new EqualsBuilder() .append(birthday, other.birthday) .append(fullname, other.fullname) .append(name, other.name) .append(race, other.race) .append(sex, other.sex) .isEquals(); } equals L
  • 115. Régime : la méthode Commons ? 2 public int hashCode() { return new HashCodeBuilder(17, 37) .append(birthday) .append(fullname) .append(name) .append(race) .append(sex) .toHashCode(); } hashCode L
  • 116. Régime : la méthode Commons ? 2 public int compareTo(Dog other) { return new CompareToBuilder() .append(name, other.name) .append(fullname, other.fullname) .append(birthday, other.birthday) ... .append(sex, other.sex) .toComparison(); } compareTo L
  • 117. List<SuperChien> superChiens = newArrayList(); for(Dog dog : dogs) { SuperChien chien = new SuperChien(); ... superChiens.add(chien); } List<SuperChien> superChiens = newArrayList( Lists.transform(dogs, new Function<Dog, SuperChien>() { @Override public SuperChien apply(Dog dog) { SuperChien chien = new SuperChien(); ... return chien; } })); Transformation Fonctionnal prog Vs boucle for : quand ? http://code.google.com/p/guava-libraries/wiki/FunctionalExplained Vs 3 G G
  • 118. Créer des Maps 4 of public static final ImmutableMap<String, Integer> AGES = new ImmutableMap.Builder<String, Integer>() .put("Milou", 32) .put("Volt", 7) .put("Pluto", 37) .put("Lassie", 17) .put("Medor", 5) .put("Croquette", 8) .put("Loulou", 2) ... .build(); public static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Milou", 32, "Volt", 7, "Pluto", 37, "Lassie", 17); Builder G G
  • 119. Charsets 5 Java5 String name = "Milou"; byte[] bytes = name.getBytes(Charsets.UTF_8); String name = "Milou"; try { byte[] bytes = name.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new AssertionError(e); } Guava Ca n’arrive jamais cette exception  5 G
  • 120. import org.springframework...Converter; @Component("dogToChienConverter") public class DogToChienConverter implements Converter<List<Dog>, List<SuperChien>> { public List<SuperChien> convert(List<Dog> dogs) { List<SuperChien> chiens = newArrayList(transform(dogs, new Function<Dog, SuperChien>() { public SuperChien apply(Dog dog) { ... return chien; } })); return chiens; } 6 Converter Spring Lazy or not lazy ? G
  • 122. Licences 8  Lombok : MIT License  Lombok-pg : MIT License  Guava : Apache License 2.0  Commons : Apache License 2.0
  • 123. @ExtensionMethod({ Object.class, MyOtherClass.class }) public class DogWithExtension { public void foo() { String s1 = "toto"; s1.print(); //  toto String s2 = null; s2.print(); //  null } } class MyOtherClass { public static <T> void print(final T value) { System.out.println(value); } } L On peut mettre autre chose qu’un "Object", par exemple un "Arrays" , un "Dog" , etc. 9 Extension avec valeurs
  • 124. @ExtensionMethod({ Object.class, MyOtherClass.class }) public class DogWithExtension { public void foo() { String s1 = "toto"; s1.print(); //  toto String s2 = null; s2.print(); //  null s2.print("vide"); //  vide } } class MyOtherClass { public static <T> void print(final T value) { System.out.println(value); } public static void print(String value, String other) { if (value == null || value.isEmpty()) { System.out.println(other); } else { System.out.println(value); } 9 Extension avec valeurs L
  • 125. long start = new Date().getTime(); foo(); // traitement long (ou pas) long end = new Date().getTime(); long duration = end - start; // 11 ms Java5 5 < Chrono > 10 Stopwatch sw = new Stopwatch(); sw.start(); foo(); // traitement long (ou pas) sw.stop(); long duration = sw.elapsedMillis(); // 11 ms G Guava long nano = sw.elapsedTime(NANOSECONDS); // 11179739 ns long micro = sw.elapsedTime(MICROSECONDS); // 11179 us long millis = sw.elapsedTime(MILLISECONDS); // 11 ms  http://blog.developpez.com/guava/p11160/base/le-stop-watch-de-guava/
  • 127. Impl 12 public class Dog implements Comparable<Dog> { private Integer id ; private String name ; private String fullName ; ... @Override public int compareTo(Dog dog) { return ...; } implements List ? aie aie aie 5
  • 128. Impl 12 @AutoGenMethodStub public class Dog implements Comparable<Dog> { private Integer id ; private String name ; private String fullName ; ... L
  • 129. List<Dog> dogs2 = newArrayList( new Dog("Rintintin", 45.0, MALE, ...), new Dog("Pluto", 22.0, MALE, ...), new Dog("Lulu", 35.6, MALE, ...)); Secondeliste G [Rintintin, Pluto, Lulu] [Milou, Rintintin, Volt, Lassie, Pluto, Medor] Liste 2 : dogs2 Liste 1 : dogs 13 And, or, in…
  • 130. And, or, in… 13 And,or,in... import static com.google.common.base.Predicates.and; import static com.google.common.base.Predicates.in; boolean isRintintinInBoth = and( in(dogs), in(dogs2) ) .apply(new Dog("Rintintin")); true import static com.google.common.base.Predicates.or; boolean isTintinInOne = or( in(dogs), in(dogs2) ) .apply(new Dog("Tintin"); false G G [Rintintin, Pluto, Lulu] [Milou, Rintintin, Volt, Lassie, Pluto, Medor] Liste2:dogs2 Liste1:dogs
  • 131. Partition, limit 14 PartitionList<List<FullDog>> partition = Lists.partition(dogs, 4); [Milou, Rintintin, Volt, Lassie] [Pluto, Medor] List<FullDog> first4Dogs = newArrayList(Iterables.limit(dogs, 4)); [Milou, Rintintin, Volt, Lassie] G G Limit
  • 132. Inférence de type 15 Java List<Integer> primeNumbers = new ArrayList<Integer>(); List<Integer> primeNumbers = newArrayList(); Guava public static <E> ArrayList<E> newArrayList() { return new ArrayList<E>(); }  http://blog.developpez.com/guava/p11334/collection/inference-de-type-avec-guava
  • 133. Coût du bloom 16 final List<Dog> dogs = Lists.newArrayList(); final Funnel<Dog> dogFunnel = new Funnel<Dog>() { @Override public void funnel(Dog dog, PrimitiveSink sink) { sink.putString(dog.getName()) .putString(dog.getFullName()) .putString(dog.getRace()); } }; BloomFilter<Dog> bloom = BloomFilter.create(dogFunnel, NB_OF_DOGS, 0.01); final Random rand = new Random(); Stopwatch sw = new Stopwatch(); sw.start(); for (int i = 0; i < NB_OF_DOGS; i++) { final DogGuava dog = new DogGuava(...); dogs.add(dog); } long duration1 = sw.elapsedTime(MICROSECONDS);
  • 134. Coût du bloom 16 for (Dog dog : dogs) { bloom.put(dog); } long duration2 = sw.elapsedTime(MICROSECONDS); boolean inside = dogs.contains(milou); long duration3 = sw.elapsedTime(MICROSECONDS); Chiens Add to list Add to bloom Recherche 1 828 17 971 430 10 938 26 643 749 100 2 159 21 859 754 1 000 9 312 49 564 1 192 10 000 42 232 126 505 5 613 100 000 156 065 261 168 14 353 1 000 000 1 594 113 775 300 41 904
  • 135. < Table > Guava // Sexe, couleur, nom Table<SexeEnum, String, String> dogTable = HashBasedTable.create(); dogTable.put(MALE, "jaune", "Pluto"); dogTable.put(MALE, "blanc", "Milou"); dogTable.put(MALE, "noir", "Medor"); dogTable.put(FEMALE, "noir", "Lassie"); dogTable.put(FEMALE, "blanc", "Pupuce"); G 17
  • 136. < Table > Guava // Sexe, couleur, nom Table<SexeEnum, String, String> dogTable = HashBasedTable.create(); dogTable.put(MALE, "jaune", "Pluto"); dogTable.put(MALE, "blanc", "Milou"); dogTable.put(MALE, "noir", "Medor"); dogTable.put(FEMALE, "noir", "Lassie"); dogTable.put(FEMALE, "blanc", "Pupuce"); Map<String, String> maleRow = dogTable.row(MALE); println( maleRow ) { jaune=Pluto, noir=Medor, blanc=Milou } G Map<String, String> femaleRow = dogTable.row(FEMALE); println( femaleRow ) { noir=Lassie, blanc=Pupuce } 17
  • 137. < Table > Guava // Sexe, couleur, nom Table<SexeEnum, String, String> dogTable = HashBasedTable.create(); dogTable.put(MALE, "jaune", "Pluto"); dogTable.put(MALE, "blanc", "Milou"); dogTable.put(MALE, "noir", "Medor"); dogTable.put(FEMALE, "noir", "Lassie"); dogTable.put(FEMALE, "blanc", "Pupuce"); Map<SexeEnum, String> blancColumn = dogTable.column("blanc"); println( blancColumn ) { FEMALE=Pupuce, MALE=Milou } Map<SexeEnum, String> jauneColumn = dogTable.column("jaune"); println( jauneColumn ) { MALE=Pluto } 17
  • 138. Pas d’écrasement des getters existants 18 @Data public class MicroDog { private String name; private Integer age; public String getName() { return "*" + name + "*"; } } @Test public void testGetterExistant() { final String name = "Milou"; final String requiredName = "*Milou*"; final MicroDog dog = new MicroDog(); dog.setName(name); assertEquals(requiredName, dog.getName()); }
  • 141. public void lireJava6(String from) { InputStream in = null; try { in = new FileInputStream(from); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; ... } } catch (Exception e) { ... } finally { if (in != null) { try { in.close(); } catch (Exception e) { ... } } ... Ressources 5 < I/O >
  • 142. public void lireJava7(String from) { try(InputStream in = new FileInputStream(from)) { ... while (true) { ... } } } Java7 7 < I/O >
  • 145. Todo