SlideShare a Scribd company logo
Milou fait un régime
Guava - Lombok
todo
SPONSORS
@thierryleriche

Thierry Leriche-Dessirier




icauda.com

Consultant JEE freelance
Professeur de Génie Logiciel à l’ESIEA
Rédacteur pour Programmez
Rédacteur pour Developpez.com
Cours

Forums

FAQ

News

Interviews

Critiques

Articles / tutoriels

Agendas

Magazine
13 OOO OOO pages vues par mois
5 500 000 visites par mois
2 500 000 visites 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
DOG

public class Dog {

private
private
private
private
private
private
private
private
private
private
...

Integer
String
String
SexeEnum
Date
String
Boolean
Double
Double
List<String>

id ;
name ;
fullName ;
sex ;
birthday ;
race ;
lof ;
weight ;
size ;
colors ;

5

















id
name
fullName
sex
birthday
race
lof
weight
size
Colors

Constructeurs
Getters / setters
toString ()
equals ()
hashCode ()
compareTo ()

















id
name
fullName
sex
birthday
race
lof
weight
size
Colors

clic clic
démo

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 ?...







Constructeurs
Getters / setters
toString ()
equals ()
hashCode ()
compareTo ()

10 attributs











id
name
fullName
sex
birthday
race
lof
weight
size
Colors

 210 lignes
Java

10 attributs
210 lignes de code
Va chercher Guava 






toString ()
equals ()
hashCode ()
compareTo ()

Commons  FAQ 1-2
Base

Objects
Java 5

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 + "]";
}

5
Simple, efficace et bien pourri 

 toString ()
Java 5

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);

5

return sb.toString();

}
Mieux mais sans plus 

 toString ()
Guava

public String toString() {
return Objects.toStringHelper(this)
.add("id", id)
.add("name", name)
.add("fullName", fullName)
...
.add("colors", colors)
.toString();
}

G
Builder

 toString ()
Java 5

birthday, fullname, name, race et sex
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;

5

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;
}
Carrément illisible 

 equals ()
Guava

birthday, fullname, name, race et sex

public boolean equals(Object obj) {
if (!(obj instanceof Dog)) return false;
Dog other = (Dog) obj;

G

return Objects.equal(birthday, other.birthday)
&& Objects.equal(fullname, other.fullname)
&& Objects.equal(name, other.name)
&& Objects.equal(race, other.race)
&& sex == other.sex;
}

 equals ()
Java 5

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;
}

 hashCode ()

5
Guava

birthday, fullname, name, race et sex

public int hashCode() {

return Objects.hashCode(birthday, fullName,
name, race, sex);

}

 hasCode()

G
Java 5

name, fullname, birthday, weight, size, 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;
}

...
}

 compareTo ()

5
name.compareTo(other.name)

Vs

other.name.compareTo(name)

 compareTo ()
name, fullname, birthday, weight, size, race et sex
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 ()
Lombok

en action
Régime

Annotations de base
Régime

 @NoArgsConstructor /
@RequiredArgsConstructor /
@AllArgsConstructor  constructeurs
 @Getter / @Setter
 @ToString
 @EqualsAndHashCode
 @Data  @Getter + @Setter + @ToString +
@EqualsAndHashCode + @RequiredArgsConstructor
Régime
clic clic
démo

 @NoArgsConstructor /
@RequiredArgsConstructor /
@AllArgsConstructor
 @Getter / @Setter
 @ToString
 @EqualsAndHashCode
 @Data
Java
Lombok

10 attributs
210 lignes de code

12 lignes + 2-3 @ + compareTo()
Factory

@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);

L
name, sex
Factory

@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);

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);
}
Trucs pratiques

Se simplifier la vie
Pratique







@Cleanup
@Synchronized
@SneakyThrows
@Log
@Delegate

 val
Ressources

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) {
...
}
}
...

5
Ressources

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;
...
}

L
Délombok

Revenir sans la lib
Délombok

java -jar lombok.jar delombok src -d src-delomboked
<properties>
<lombok.sourceDirectory>
${project.basedir}/src/main/java
</lombok.sourceDirectory>
...

XML

<build>
<groupId>org.projectlombok</groupId>
<artifactId>maven-lombok-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
</execution>
</executions>
...

mvn lombok:delombok
Délombok

5

@Data
public class Dog {
private Integer id;
public class Dog {
private String name;
private Integer id;
private String fullName;
private String name;
private SexeEnum sex;
private String fullName;
private Date birthday;
...
private String race;
private List<String> colors;
private Boolean lof;
private Double weight;
public DogLombok() {
private Double size;
}
private List<String> colors;
@java.lang.Override
}
@java.lang.SuppressWarnings("all")
public boolean equals(final java.lang.Obje
if (o == this) return true;
if (o == null) return false;
mvn
lombok:delombok
if (o.getClass() != this.getClass()) ret
final Dog other = (Dog)o;
if (this.getId() == null ? other.getId()
...

5

@java.lang.Override
@java.lang.SuppressWarnings("all")
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = result * PRIME + (this.getId()
Lombok-pg

Annotations supplémentaires
Annotations Pg


















 @Builder
@Action
 @LazyGetter
@Function
 @FluentSetter
@EnumId
 @Predicate
@Rethrow / @Rethrows
@Singleton
@AutoGenMethodStub
@BoundPropertySupport / @BoundSetter
@DoPrivileged
@ExtensionMethod
@ListenerSupport
@WriteLock / @ReadLock
@Await / @Signal / @AwaitBeforeAndSignalAfter
@Sanitize.Normalize / .With
@SwingInvokeLater / @SwingInvokeAndWait
@Validate.NotEmpty / .NotNull / .With
@VisibleForTesting
Fluent

@FluentSetter
@Getter
public class Dog {
private Integer id ;
private String name ;
private String fullName ;
...

 DogLombok dog = new DogLombok();
dog.name("Milou").sex(MALE);

println( dog.getName());
println( dog.getSex());

//  Milou
//  MALE

L
Builder

@Builder
@Getter
public class Dog {
private Integer id ;
private String name ;
private String fullName ;
...

 Dog dog = Dog.dog().name("Milou").sex(MALE).build();

println( dog.getName());
println( dog.getSex());

//  Milou
//  MALE

L
extension

L

@ExtensionMethod({ Dog.class, MyDogExtensionClass.class })
public class DogWithExtension {
public void foo() {
Dog milou = new Dog("Milou", 12.5, ...);
boolean isTooFat = milou.isTooFat();
}

}
class MyDogExtensionClass {
public static boolean isTooFat(final Dog dog) {
double imc = dog.getWeight() / pow(dog.getSize(), 2);
return 25 < imc;
}

}

Avec paramètres  FAQ 9
 http://blog.developpez.com/todaystip/p11165/dev/java/extensionmethod-de-lombok-pg/
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
Java 5

< new Vs static factories >
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();

5

Map<String, Integer> ages = new HashMap<String, Integer>();
< new Vs static factories >

Java 5

5

List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();

dur dur ?

Map<String, Integer> ages = new HashMap<String, Integer>();

Map<String, List<String>> trucs =
new HashMap<String, List<String>>();

5

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 = ...
Java 5

< new Vs static factories >
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();

5
7

Java 7

Map<String, Integer> ages = new HashMap<String, Integer>();
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();

Qui utilise Java 7 en prod ?
Java 5

< new Vs static factories >
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();

5
7
G

Java 7

Map<String, Integer> ages = new HashMap<String, Integer>();
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();

Guava

Qui utilise Java 7 en prod ?
List<Integer> primeNumbers = newArrayList();

Set<String> colors = newTreeSet();
Map<String, Integer> ages = newHashMap();

Dès maintenant !
Java 5

< new Vs static factories >
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();

5
7
G

Java 7

Map<String, Integer> ages = new HashMap<String, Integer>();
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();

Guava

Qui utilise Java 7 en prod ?
List<Integer> primeNumbers = newArrayList();

Set<String> colors = newTreeSet();
Map<String, Integer> ages = newHashMap();

Lombok

Dès maintenant !

var primeNumbers = new ArrayList<Integer>();
-> primeNumbers.size();
...

L
List of dogs

< new Vs static factories >

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, ...));

[Milou,
Rintintin,
Volt,
Lassie,
Pluto,
Medor]

G
Immutables

Pour que ça ne change pas
immutable

Quand ?
immutable

Quand ?
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.
Java 5

< unmodifiables Vs immutables >
Set<Integer> temp =
new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7));
Set<Integer> primes = Collections.unmodifiableSet(temp);
Java 5

< unmodifiables Vs immutables >
Set<Integer> temp =
new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7));

Guava

Set<Integer> primes = Collections.unmodifiableSet(temp);

Set<Integer> primes = ImmutableSet.of(1, 2, 3, 5, 7);

G
Of

< unmodifiables Vs immutables >
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E

e1)
e1,
e1,
e1,
e1,
e1,

E
E
E
E
E

e2)
e2,
e2,
e2,
e2,

E
E
E
E

G

e3)
e3, E e4)
e3, E e4, E e5)
e3, E e4, E e5, E e6, E...)

Of

Ne prend pas de null

ImmutableSet.of()
Vide

Map et List  FAQ 4
 http://blog.developpez.com/guava/p10589/collection/title-212/
Java 5

< Copie de défense >
public 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
Guava

< Copie de défense >
public 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;
}

Message clair

G
Collections en plus

Multimap, Bipap, Multiset, Table
Java 5

< Multi Map >
Map<String, List<String>> dogFavoriteColors =
new HashMap<String, List<String>>();

5
5

List<String> milouColors = dogFavoriteColors.get("Milou");
if(milouColors == null) {
milouColors = new ArrayList<String>();
dogFavoriteColors.put("Milou",milouColors);
}
milouColors.add("Vert");
Java 5

< Multi Map >
Map<String, List<String>> dogFavoriteColors =
new HashMap<String, List<String>>();

5
5

Guava

List<String> milouColors = dogFavoriteColors.get("Milou");
if(milouColors == null) {
milouColors = new ArrayList<String>();
dogFavoriteColors.put("Milou",milouColors);
}
milouColors.add("Vert");

Multimap<String, String> dogFavoriteColors =
HashMultimap.create();

dogFvoriteColors2.put("Milou", "Jaune");
dogFavoriteColors2.put("Milou", "Rouge");

G
Guava

< Bi Map >
BiMap<String, Dog> tatouages = HashBiMap.create();
tatouages.put("ABC123", new Dog("Milou") );
tatouages.put("MBD324", new Dog("Volt") );
tatouages.put("JFT672", new Dog("Lassie") );
println( tatouages );

{ABC123=Milou,
MBD324=Volt,
JFT672=Lassie}

ABC123=Milou
MDB324=Volt
JFT672=Lassie

println( tatouages.inverse() );

Une map bijective

{Milou=ABC123,
Volt=MBD324,
Lassie=JFT672}

Il est possible de changer la valeur associée à une clé mais pas
d'avoir deux clés avec la même valeur (IllegalArgumentException).

G
Guava

< Multi Set >
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 );

[2, 3 x 2, 5, 7, 11]

println( ages.count(3) )

2

G
Base

Préconditions, joiner, splitter, optional





toString ()
equals ()
hashCode ()
compareTo ()
DOG

< Preconditions >
public class Dog {
private Integer
private String
private String
...

id ;
name ;
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;
...
}

5
DOG

< Preconditions >
import static com.google.common.base.Preconditions.*;

public class Dog {
private Integer
private String
private String
...

id ;
name ;
fullName ;

G

public Dog(String name, String fullName, ...) {
this.name = checkNotNull(name, "bla bla");
this.fullName = checkNotNull(fullName, "bla bla");
...
}

checkNotNull()  NPE
checkArgument()  IAE
checkState()
 ISE
Joiner

String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));

"Lassie, Volt, Milou"

G

Java classique
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();
Joiner

String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));

"Lassie, Volt, Milou"

G

String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", null, "Milou"));

 NPE 
Joiner

String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));

"Lassie, Volt, Milou"

G

String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", null, "Milou"));

 NPE 

G

String names = Joiner.on(", ")
.skipNulls()
.join(newArrayList("Lassie", "Volt", null, "Milou"));

"Lassie, Volt, Milou"
Joiner

String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", "Milou"));

"Lassie, Volt, Milou"

G

String names = Joiner.on(", ")
.join(newArrayList("Lassie", "Volt", null, "Milou"));

 NPE 

G
G

String names = Joiner.on(", ")
.skipNulls()
.join(newArrayList("Lassie", "Volt", null, "Milou"));

"Lassie, Volt, Milou"

String names = Joiner.on(", ")
.useForNull("Anonymous"))
.join(newArrayList("Lassie", "Volt", null, "Milou"));

"Lassie, Volt, Anonymous, Milou"

 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(",")
[ "Lassie",
.split("Lassie, Volt, ,Milou"); "Volt",

" ",
"Milou" ]
Splitter

Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, Milou");

[ "Lassie",
"Volt",
"Milou" ]

Iterable<String> dogNames =
Splitter.on(",")
[ "Lassie",
.split("Lassie, Volt, ,Milou"); "Volt",

" ",
"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
[ "Lassie",
.trimResults()
"Volt",
.split("Lassie, Volt, ,Milou"); "",

"Milou" ]
Splitter

Iterable<String> dogNames =
Splitter.on(",")
.split("Lassie, Volt, Milou");

[ "Lassie",
"Volt",
"Milou" ]

Iterable<String> dogNames =
Splitter.on(",")
[ "Lassie",
.split("Lassie, Volt, ,Milou"); "Volt",

" ",
"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
[ "Lassie",
.trimResults()
"Volt",
.split("Lassie, Volt, ,Milou"); "",

"Milou" ]
Iterable<String> dogNames =
Splitter.on(",")
.trimResults()
[ "Lassie",
.omitEmptyStrings()
.split("Lassie, Volt, ,Milou"); "Volt",

"Milou" ]

 http://blog.developpez.com/guava/p11045/annotation/splitter-pour-separer-des-items/

G
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);
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() );
 http://blog.developpez.com/guava/p11163/base/le-wrapper-optional-de-guava/
Functional Programming

todo
Super chien

Dog
Super Chien

public class SuperChien implements SuperHero {
private
private
private
private

String
double
Set<String>
Set<String>

surnom ;
poids ;
couleursCostume ;
pouvoirs ;

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.
Transformation

< Transformation >
List<SuperChien> superChiens =
Lists.transform(dogs,
new Function<Dog, SuperChien>() {
@Override
public SuperChien apply(Dog dog) {
SuperChien chien = new SuperChien();

G

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

< Transformation >
List<SuperChien> superChiens =
Lists.transform(dogs, new Function<Dog, SuperChien>() {
@Override
public SuperChien apply(Dog dog) {
SuperChien chien = new SuperChien();
...
return chien;
}
});

G

 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(...
< Filtre >

Filtre

G

Predicate<Dog> malePredicate =
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}
}
Iterable<Dog> maleDogs =
Iterables.filter(dogs, malePredicate);

[Milou,
Rintintin,
Volt,
Pluto,
Medor]

G
Filtre

< Filtre >
Predicate<Dog> malePredicate =
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}
}
Iterable<Dog> maleDogs =
Iterables.filter(dogs, malePredicate);

[Milou,
Rintintin,
Volt,
Pluto,
Medor]

Dog firstMaleDog =
Iterables.find(dogs, malePredicate);

Milou

G

G
G
Filtre

< Filtre >
Predicate<Dog> malePredicate =
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}
}
Iterable<Dog> maleDogs =
Iterables.filter(dogs, malePredicate);

[Milou,
Rintintin,
Volt,
Pluto,
Medor]

Dog firstMaleDog =
Iterables.find(dogs, malePredicate);

Milou

G

G
G

Dog firstMaleDog =
Iterables.find(femaleDogs, malePredicate, DEFAULT_DOG );

Default dog
Pas fluent

< Fluent or not fluent ? >
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);

G
G
G
[Milou,
Rintintin,
Volt,
Pluto,
Medor]
Pas fluent

< Fluent or not fluent ? >

Iterable<FullDog> maleDogs =
Iterables.filter(dogs, malePredicate);

Fluent

Iterable<String> maleNames =
Iterables.transform(maleDogs, nameFunction);

List<String> maleNames2 =
FluentIterable.from(dogs)
.filter(malePredicate)
.transform(nameFunction)
.toImmutableList();

G

G
Guava 12.0

 http://blog.developpez.com/guava/p11092/annotation/fluentiterable-surmon-chien-guava/

[Milou,
Rintintin,
Volt,
Pluto,
Medor]
Cache

todo
Web Service

< Memoization >

public class DogService {
@Inject
private PetShopWebService service;
public Integer getNumberDogsSoldYesterday() {
return service.checkSales( "dog" );
}

5
Web Service

< Memoization >

Cache manuel

public class DogService {
@Inject
private PetShopWebService service;
public Integer getNumberDogsSoldYesterday() {
return service.checkSales( "dog" );
}

private Integer nbOfDogsSold;

public Integer getNumberDogsSoldYesterday() {
if (nbOfDogsSold == null) {
nbOfDogsSold = service.checkSales( "dog" );
}
return nbOfDogsSold;
}

5

5

Double check null…
Guava

< Memoization >

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();
}

G
Guava

< Memoization >

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();
}

G
Web Service

< Cache >

public class DogService {
@Inject
private PetShopWebService service;
private Map<String, Dog> dogMap = Maps.newHashMap();

5

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;
}
Quid du timeout ? Max ?
Guava

< Cache >

public class DogService {
@Inject
private PetShopWebService service;

G

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
}
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

< Is in list ? >

int NB_OF_DOGS = 100000;

contains

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);
}
final Dog milou = new Dog();
milou.setName("Milou");
...
boolean isInList = dogs.contains(milou);

5

5

false (14 ms)

dogs.add(milou);
boolean isInList = dogs.contains(milou);

true (14 ms)
Bloom filter

< Is in list ? >
Funnel<Dog> dogFunnel = new Funnel<Dog>() {
public void funnel(Dogdog, PrimitiveSink sink) {
sink.putString(dog.getName())
.putString(dog.getFullName())
.putString(dog.getRace());
}};

G

BloomFilter<Dog> bloom =
BloomFilter.create(dogFunnel, NB_OF_DOGS, 0.01);

for (int i = 0; i < NB_OF_DOGS; i++) {
...
bloom.put(dog);
boolean isInList = bloom.mightContain(milou);

false (0 ms)
bloom.put(milou);
boolean isInList = bloom.mightContain(milou);
Guava 13

true (0 ms)

 http://blog.developpez.com/guava/p11149/collection/bloom-filter-de-guava-13/
Guava or not Guava ?

Avantages et inconvénients
Pro / Cons

 Ne pas en abuser…

 Utile
 Bonnes pratiques
LIENS

@thierryleriche
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
 http://icauda.com/cours.html

(articles)
(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)
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
toString

Régime : la méthode Commons ?
public String toString() {
return new ToStringBuilder(this)
.append("id", id)
.append("name", name)
.append("fullName", fullName)
...
.append("colors", colors)
.toString();
}

2

L
equals

Régime : la méthode Commons ?
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();

2

}

L
hashCode

Régime : la méthode Commons ?
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(birthday)
.append(fullname)
.append(name)
.append(race)
.append(sex)
.toHashCode();
}

2

L
compareTo

Régime : la méthode Commons ?
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();
}

2

L
Transformation

Fonctionnal prog Vs boucle for : quand ?
List<SuperChien> superChiens = newArrayList(
Lists.transform(dogs, new Function<Dog, SuperChien>() {
@Override
public SuperChien apply(Dog dog) {
SuperChien chien = new SuperChien();
...
return chien;
}
}));

3

Vs

G

List<SuperChien> superChiens = newArrayList();
for(Dog dog : dogs) {
SuperChien chien = new SuperChien();
...
superChiens.add(chien);
}

G

http://code.google.com/p/guava-libraries/wiki/FunctionalExplained
of

Créer des Maps
public static final ImmutableMap<String, Integer>
AGES = ImmutableMap.of("Milou", 32,
"Volt", 7,
"Pluto", 37,
"Lassie", 17);

Builder

G

4

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();

G
Java 5

Charsets
String name = "Milou";

try {
byte[] bytes = name.getBytes("UTF-8");

5

} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}

Guava

Ca n’arrive jamais cette exception 

5

String name = "Milou";
byte[] bytes = name.getBytes(Charsets.UTF_8);

G
Converter Spring
import org.springframework...Converter;

G

@Component("dogToChienConverter")
public class DogToChienConverter
implements Converter<List<Dog>,
List<SuperChien>> {

6

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;
}

Lazy or not lazy ?
Orderings

7
Licences
 Lombok :
 Lombok-pg :
 Guava :

Apache License 2.0

 Commons :

8

MIT License
MIT License

Apache License 2.0
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

}
}
class MyOtherClass {
public static <T> void print(final T value) {
System.out.println(value);
}
}

9

On peut mettre autre chose qu’un "Object", par exemple un
"Arrays" , un "Dog" , etc.

L
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();
s2.print("vide");

//  null
//  vide

}
}

9

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);
}

L
< Chrono >

Guava Java 5

long start = new Date().getTime();
foo(); // traitement long (ou pas)
long end = new Date().getTime();

5

long duration = end - start; // 11 ms

Stopwatch sw = new Stopwatch();
sw.start();
foo(); // traitement long (ou pas)
sw.stop();
long duration = sw.elapsedMillis(); // 11 ms

10

G

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
public class Dog implements Comparable<Dog> {

private Integer id ;
private String name ;
private String fullName ;

5

...
@Override
public int compareTo(Dog dog) {
return ...;
}

12

implements List ? aie aie aie
Impl
@AutoGenMethodStub
public class Dog implements Comparable<Dog> {
private Integer id ;
private String name ;
private String fullName ;
...

12

L
Seconde liste

And, or, in…
List<Dog> dogs2 = newArrayList(
new Dog("Rintintin", 45.0, MALE, ...),

13

new Dog("Pluto", 22.0, MALE, ...),
new Dog("Lulu", 35.6, MALE, ...));

[Rintintin,
Pluto,
Lulu]
Liste 2 : dogs2

[Milou,
Rintintin,
Volt,
Lassie,
Pluto,
Medor]
Liste 1 : dogs

G
And, or, in...

And, or, in…

G

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

G

import static com.google.common.base.Predicates.or;

[Milou,
Rintintin,
Volt,
Lassie,
Pluto,
Medor]

Liste 2 : dogs2

13

Liste 1 : dogs

boolean isTintinInOne =
or( in(dogs), in(dogs2) )
.apply(new Dog("Tintin");

false

[Rintintin,
Pluto,
Lulu]
Partition
Limit

Partition, limit
List<List<FullDog>> partition =
Lists.partition(dogs, 4);

[Milou,
Rintintin,
Volt,
Lassie]

[Pluto,
Medor]

List<FullDog> first4Dogs =
newArrayList(Iterables.limit(dogs, 4));

14

[Milou,
Rintintin,
Volt,
Lassie]

G

G
Java
Guava

Inférence de type
List<Integer> primeNumbers = new ArrayList<Integer>();

List<Integer> primeNumbers = newArrayList();

public static <E> ArrayList<E> newArrayList() {
return new ArrayList<E>();
}

15
 http://blog.developpez.com/guava/p11334/collection/inference-de-type-avec-guava
Coût du bloom
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();

16

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
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

16

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
Guava

< Table >
// Sexe, couleur, nom

G

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");

17
Guava

< Table >
// Sexe, couleur, nom

G

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 }

17

Map<String, String> femaleRow = dogTable.row(FEMALE);
println( femaleRow )

{ noir=Lassie, blanc=Pupuce }
Guava

< Table >
// 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 )

17

{ FEMALE=Pupuce, MALE=Milou }

Map<SexeEnum, String> jauneColumn
= dogTable.column("jaune");
println( jauneColumn )

{ MALE=Pluto }
Pas d’écrasement des getters existants
@Data
public class MicroDog {
private String name;
private Integer age;
public String getName() {
return "*" + name + "*";
}
}

18

@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
Ressources

< I/O >
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) {
...
}
}
...

5
Java 7

< I/O >
public void lireJava7(String from) {
try(InputStream in = new FileInputStream(from)) {
...
while (true) {
...
}
}
}

7
Guava

< I/O >
Todo

G
Concurrent / future

todo
Todo

More Related Content

What's hot

Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3
Mohamed Nabil, MSc.
 
Designing with Groovy Traits - Gr8Conf India
Designing with Groovy Traits - Gr8Conf IndiaDesigning with Groovy Traits - Gr8Conf India
Designing with Groovy Traits - Gr8Conf India
Naresha K
 
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
 
Understanding Prototypal Inheritance
Understanding Prototypal InheritanceUnderstanding Prototypal Inheritance
Understanding Prototypal Inheritance
Guy Royse
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygook
Pawel Szulc
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
jonycse
 
Functional programming in java
Functional programming in javaFunctional programming in java
Functional programming in java
John Ferguson Smart Limited
 
Text analysis using python
Text analysis using pythonText analysis using python
Text analysis using python
Vijay Ramachandran
 
Discovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic GroovyDiscovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic Groovy
Naresha K
 
Natural Language Processing and Python
Natural Language Processing and PythonNatural Language Processing and Python
Natural Language Processing and Python
anntp
 
Android & Kotlin - The code awakens #02
Android & Kotlin - The code awakens #02Android & Kotlin - The code awakens #02
Android & Kotlin - The code awakens #02
Omar Miatello
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
Andrei Solntsev
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
José Paumard
 
Autumn collection JavaOne 2014
Autumn collection JavaOne 2014Autumn collection JavaOne 2014
Autumn collection JavaOne 2014
José Paumard
 
Kotlin : Happy Development
Kotlin : Happy DevelopmentKotlin : Happy Development
Kotlin : Happy Development
Md Sazzad Islam
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming language
Pawel Szulc
 
Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03
Omar Miatello
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
José Paumard
 
NLTK in 20 minutes
NLTK in 20 minutesNLTK in 20 minutes
NLTK in 20 minutes
Jacob Perkins
 

What's hot (19)

Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3
 
Designing with Groovy Traits - Gr8Conf India
Designing with Groovy Traits - Gr8Conf IndiaDesigning with Groovy Traits - Gr8Conf India
Designing with Groovy Traits - Gr8Conf India
 
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
 
Understanding Prototypal Inheritance
Understanding Prototypal InheritanceUnderstanding Prototypal Inheritance
Understanding Prototypal Inheritance
 
Real world gobbledygook
Real world gobbledygookReal world gobbledygook
Real world gobbledygook
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
 
Functional programming in java
Functional programming in javaFunctional programming in java
Functional programming in java
 
Text analysis using python
Text analysis using pythonText analysis using python
Text analysis using python
 
Discovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic GroovyDiscovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic Groovy
 
Natural Language Processing and Python
Natural Language Processing and PythonNatural Language Processing and Python
Natural Language Processing and Python
 
Android & Kotlin - The code awakens #02
Android & Kotlin - The code awakens #02Android & Kotlin - The code awakens #02
Android & Kotlin - The code awakens #02
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Autumn collection JavaOne 2014
Autumn collection JavaOne 2014Autumn collection JavaOne 2014
Autumn collection JavaOne 2014
 
Kotlin : Happy Development
Kotlin : Happy DevelopmentKotlin : Happy Development
Kotlin : Happy Development
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming language
 
Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03Android & Kotlin - The code awakens #03
Android & Kotlin - The code awakens #03
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
NLTK in 20 minutes
NLTK in 20 minutesNLTK in 20 minutes
NLTK in 20 minutes
 

Viewers also liked

Beautifulspectacle 121125025854-phpapp02
Beautifulspectacle 121125025854-phpapp02Beautifulspectacle 121125025854-phpapp02
Beautifulspectacle 121125025854-phpapp02
mohan kumar
 
Présentation Café de la Terre (collectif jardinier MTL, QB, CA)
Présentation Café de la Terre (collectif jardinier MTL, QB, CA)Présentation Café de la Terre (collectif jardinier MTL, QB, CA)
Présentation Café de la Terre (collectif jardinier MTL, QB, CA)
Vladimir Ilich Lopez Flores
 
Gwenegan bui, dans la tempête bretonne libération
Gwenegan bui, dans la tempête bretonne   libérationGwenegan bui, dans la tempête bretonne   libération
Gwenegan bui, dans la tempête bretonne libération
graves146
 
Portail immobilier prox-immo.fr
Portail immobilier prox-immo.frPortail immobilier prox-immo.fr
Portail immobilier prox-immo.fr
ancelduval
 
retail-Articles de Paris
retail-Articles de Parisretail-Articles de Paris
retail-Articles de Parisap-slideshare
 
Décret interdiction du téléphone au volant
Décret interdiction du téléphone au volantDécret interdiction du téléphone au volant
Décret interdiction du téléphone au volantGeoffroy Nasset
 
Duolith pour site (1)
Duolith pour site (1)Duolith pour site (1)
Duolith pour site (1)casimir91
 
Positive Thought Processes
Positive Thought ProcessesPositive Thought Processes
Positive Thought Processes
Craig Galloway
 
Enquête chauffeurs vtc 02-14 - bilan général
Enquête chauffeurs vtc   02-14 - bilan généralEnquête chauffeurs vtc   02-14 - bilan général
Enquête chauffeurs vtc 02-14 - bilan général
Etudiant EGE
 
Dossier W - Prévention des IST chez les prostitués
Dossier W - Prévention des IST chez les prostituésDossier W - Prévention des IST chez les prostitués
Dossier W - Prévention des IST chez les prostitués
MNH Mutuelle Nationale des Hospitaliers
 
Cinquain Poems Mrs. Lambertson's 4th Grade Class
Cinquain Poems Mrs. Lambertson's 4th Grade ClassCinquain Poems Mrs. Lambertson's 4th Grade Class
Cinquain Poems Mrs. Lambertson's 4th Grade Class
Amanda Ingalls
 
Information metier hotellerie restauration management du personnel de cuisine...
Information metier hotellerie restauration management du personnel de cuisine...Information metier hotellerie restauration management du personnel de cuisine...
Information metier hotellerie restauration management du personnel de cuisine...
Emploi Hotellerie Restauration
 
Rac fnh-diesel-v6
Rac fnh-diesel-v6Rac fnh-diesel-v6
Rac fnh-diesel-v6RAC-F
 
Programme de 18 jours
Programme de 18 joursProgramme de 18 jours
Programme de 18 jours
Ideotour Vietnam
 
Projet 2de A
Projet 2de AProjet 2de A
Béta code start&stop
Béta code start&stopBéta code start&stop
Béta code start&stop
mikaelgautier
 
Présentation Steve Wozniak
Présentation Steve WozniakPrésentation Steve Wozniak
Présentation Steve Wozniakqsdfghjk
 

Viewers also liked (20)

Beautifulspectacle 121125025854-phpapp02
Beautifulspectacle 121125025854-phpapp02Beautifulspectacle 121125025854-phpapp02
Beautifulspectacle 121125025854-phpapp02
 
Présentation Café de la Terre (collectif jardinier MTL, QB, CA)
Présentation Café de la Terre (collectif jardinier MTL, QB, CA)Présentation Café de la Terre (collectif jardinier MTL, QB, CA)
Présentation Café de la Terre (collectif jardinier MTL, QB, CA)
 
Gwenegan bui, dans la tempête bretonne libération
Gwenegan bui, dans la tempête bretonne   libérationGwenegan bui, dans la tempête bretonne   libération
Gwenegan bui, dans la tempête bretonne libération
 
Présentation2
Présentation2Présentation2
Présentation2
 
Portail immobilier prox-immo.fr
Portail immobilier prox-immo.frPortail immobilier prox-immo.fr
Portail immobilier prox-immo.fr
 
retail-Articles de Paris
retail-Articles de Parisretail-Articles de Paris
retail-Articles de Paris
 
Décret interdiction du téléphone au volant
Décret interdiction du téléphone au volantDécret interdiction du téléphone au volant
Décret interdiction du téléphone au volant
 
Duolith pour site (1)
Duolith pour site (1)Duolith pour site (1)
Duolith pour site (1)
 
Positive Thought Processes
Positive Thought ProcessesPositive Thought Processes
Positive Thought Processes
 
Enquête chauffeurs vtc 02-14 - bilan général
Enquête chauffeurs vtc   02-14 - bilan généralEnquête chauffeurs vtc   02-14 - bilan général
Enquête chauffeurs vtc 02-14 - bilan général
 
Dossier W - Prévention des IST chez les prostitués
Dossier W - Prévention des IST chez les prostituésDossier W - Prévention des IST chez les prostitués
Dossier W - Prévention des IST chez les prostitués
 
Cinquain Poems Mrs. Lambertson's 4th Grade Class
Cinquain Poems Mrs. Lambertson's 4th Grade ClassCinquain Poems Mrs. Lambertson's 4th Grade Class
Cinquain Poems Mrs. Lambertson's 4th Grade Class
 
Information metier hotellerie restauration management du personnel de cuisine...
Information metier hotellerie restauration management du personnel de cuisine...Information metier hotellerie restauration management du personnel de cuisine...
Information metier hotellerie restauration management du personnel de cuisine...
 
Rac fnh-diesel-v6
Rac fnh-diesel-v6Rac fnh-diesel-v6
Rac fnh-diesel-v6
 
digitalevent réunir
digitalevent réunirdigitalevent réunir
digitalevent réunir
 
Présentation réf nat
Présentation réf natPrésentation réf nat
Présentation réf nat
 
Programme de 18 jours
Programme de 18 joursProgramme de 18 jours
Programme de 18 jours
 
Projet 2de A
Projet 2de AProjet 2de A
Projet 2de A
 
Béta code start&stop
Béta code start&stopBéta code start&stop
Béta code start&stop
 
Présentation Steve Wozniak
Présentation Steve WozniakPrésentation Steve Wozniak
Présentation Steve Wozniak
 

Similar to Guava et Lombok au Brezth JUG

Soirée Guava et Lombok avec Thierry Leriche
Soirée Guava et Lombok avec Thierry LericheSoirée Guava et Lombok avec Thierry Leriche
Soirée Guava et Lombok avec Thierry Leriche
Normandy JUG
 
Milou fait un régime Guava Lombok
Milou fait un régime Guava LombokMilou fait un régime Guava Lombok
Milou fait un régime Guava Lombok
Lorraine JUG
 
201209 Lombok & Guava
201209 Lombok & Guava201209 Lombok & Guava
201209 Lombok & Guava
lyonjug
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
HamletDRC
 
Kotlin intro
Kotlin introKotlin intro
Kotlin intro
Elifarley Cruz
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
Seri Moth
 
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
Kostas Saidis
 
Code generating beans in Java
Code generating beans in JavaCode generating beans in Java
Code generating beans in Java
Stephen Colebourne
 
Kotlin, a modern language for modern times
Kotlin, a modern language for modern timesKotlin, a modern language for modern times
Kotlin, a modern language for modern times
Sergi Martínez
 
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
loffenauer
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
Stoyan Stefanov
 
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
hwilming
 
Unleashing kotlin's power
Unleashing kotlin's powerUnleashing kotlin's power
Unleashing kotlin's power
Eury Perez Beltre
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
HamletDRC
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java Developers
Andres Almiray
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVM
Andres Almiray
 
Introduction To Groovy
Introduction To GroovyIntroduction To Groovy
Introduction To Groovy
manishkp84
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
Thijs Suijten
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
Thijs Suijten
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. Experience
Mike Fogus
 

Similar to Guava et Lombok au Brezth JUG (20)

Soirée Guava et Lombok avec Thierry Leriche
Soirée Guava et Lombok avec Thierry LericheSoirée Guava et Lombok avec Thierry Leriche
Soirée Guava et Lombok avec Thierry Leriche
 
Milou fait un régime Guava Lombok
Milou fait un régime Guava LombokMilou fait un régime Guava Lombok
Milou fait un régime Guava Lombok
 
201209 Lombok & Guava
201209 Lombok & Guava201209 Lombok & Guava
201209 Lombok & Guava
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
Kotlin intro
Kotlin introKotlin intro
Kotlin intro
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
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
 
Code generating beans in Java
Code generating beans in JavaCode generating beans in Java
Code generating beans in Java
 
Kotlin, a modern language for modern times
Kotlin, a modern language for modern timesKotlin, a modern language for modern times
Kotlin, a modern language for modern times
 
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
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
 
Unleashing kotlin's power
Unleashing kotlin's powerUnleashing kotlin's power
Unleashing kotlin's power
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java Developers
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVM
 
Introduction To Groovy
Introduction To GroovyIntroduction To Groovy
Introduction To Groovy
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. Experience
 

More from Thierry Leriche-Dessirier

Disc l'essentiel
Disc l'essentielDisc l'essentiel
Disc l'essentiel
Thierry Leriche-Dessirier
 
Rapport DISC Pro de Lucie Durand
Rapport DISC Pro de Lucie DurandRapport DISC Pro de Lucie Durand
Rapport DISC Pro de Lucie Durand
Thierry Leriche-Dessirier
 
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)
Thierry Leriche-Dessirier
 
Memento DISC Influent (English)
Memento DISC Influent (English)Memento DISC Influent (English)
Memento DISC Influent (English)
Thierry Leriche-Dessirier
 
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
Thierry Leriche-Dessirier
 
Memento DISC Stable
Memento DISC StableMemento DISC Stable
Memento DISC Stable
Thierry Leriche-Dessirier
 
Memento DISC Influent
Memento DISC InfluentMemento DISC Influent
Memento DISC Influent
Thierry Leriche-Dessirier
 
Memento DISC Dominant
Memento DISC DominantMemento DISC Dominant
Memento DISC Dominant
Thierry Leriche-Dessirier
 
Memento Disc Consciencieux
Memento Disc ConsciencieuxMemento Disc Consciencieux
Memento Disc Consciencieux
Thierry Leriche-Dessirier
 
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
Thierry Leriche-Dessirier
 
Management en couleur avec DISC
Management en couleur avec DISCManagement en couleur avec DISC
Management en couleur avec DISC
Thierry Leriche-Dessirier
 
Les algorithmes de tri
Les algorithmes de triLes algorithmes de tri
Les algorithmes de tri
Thierry Leriche-Dessirier
 
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
Thierry Leriche-Dessirier
 
Puzzle 2 (4x4)
Puzzle 2 (4x4)Puzzle 2 (4x4)
Guava et Lombok au Lorraine JUG
Guava et Lombok au Lorraine JUGGuava et Lombok au Lorraine JUG
Guava et Lombok au Lorraine JUG
Thierry Leriche-Dessirier
 
Guava au Paris JUG
Guava au Paris JUGGuava au Paris JUG
Guava au Paris JUG
Thierry Leriche-Dessirier
 
Memento java
Memento javaMemento 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
Thierry Leriche-Dessirier
 

More from Thierry Leriche-Dessirier (19)

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 et Lombok au Lorraine JUG
Guava et Lombok au Lorraine JUGGuava et Lombok au Lorraine JUG
Guava et Lombok au Lorraine JUG
 
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

一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理
一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理
一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理
kmzsy4kn
 
一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理
一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理
一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理
10h6bbc4
 
一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理
一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理
一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理
twqryq79
 
一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理
一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理
一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理
ynrtjotp
 
Intel-Centrino-Mobile-Technology-guidelines
Intel-Centrino-Mobile-Technology-guidelinesIntel-Centrino-Mobile-Technology-guidelines
Intel-Centrino-Mobile-Technology-guidelines
EricHo305923
 
一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理
一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理
一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理
aprhf21y
 
一比一原版马来西亚世纪大学毕业证成绩单一模一样
一比一原版马来西亚世纪大学毕业证成绩单一模一样一比一原版马来西亚世纪大学毕业证成绩单一模一样
一比一原版马来西亚世纪大学毕业证成绩单一模一样
k4krdgxx
 
一比一原版(UW毕业证书)华盛顿大学毕业证如何办理
一比一原版(UW毕业证书)华盛顿大学毕业证如何办理一比一原版(UW毕业证书)华盛顿大学毕业证如何办理
一比一原版(UW毕业证书)华盛顿大学毕业证如何办理
i990go7o
 
欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】
欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】
欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】
jafiradnan336
 
一比一原版马里兰大学毕业证(UMD毕业证书)如何办理
一比一原版马里兰大学毕业证(UMD毕业证书)如何办理一比一原版马里兰大学毕业证(UMD毕业证书)如何办理
一比一原版马里兰大学毕业证(UMD毕业证书)如何办理
9lq7ultg
 
一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理
一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理
一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理
k4krdgxx
 
原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样
原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样
原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样
hw2xf1m
 
modular-kitchen home plan civil engineering.pdf
modular-kitchen home plan civil engineering.pdfmodular-kitchen home plan civil engineering.pdf
modular-kitchen home plan civil engineering.pdf
RashmitaSwain3
 
一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理
一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理
一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理
ubogumo
 
一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理
一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理
一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理
zv943dhb
 
一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理
一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理
一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理
340qn0m1
 
一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理
一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理
一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理
ka3y2ukz
 
一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理
一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理
一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理
21uul8se
 
一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理
一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理
一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理
67n7f53
 
一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理
一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理
一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理
w26izoeb
 

Recently uploaded (20)

一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理
一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理
一比一原版(KPU毕业证)加拿大昆特兰理工大学毕业证如何办理
 
一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理
一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理
一比一原版澳洲莫纳什大学毕业证(Monash学位证)如何办理
 
一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理
一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理
一比一原版美国加州大学戴维斯分校毕业证(ucdavis学位证)如何办理
 
一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理
一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理
一比一原版(爱大毕业证)美国爱荷华大学毕业证如何办理
 
Intel-Centrino-Mobile-Technology-guidelines
Intel-Centrino-Mobile-Technology-guidelinesIntel-Centrino-Mobile-Technology-guidelines
Intel-Centrino-Mobile-Technology-guidelines
 
一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理
一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理
一比一原版(brunel毕业证书)布鲁内尔大学毕业证如何办理
 
一比一原版马来西亚世纪大学毕业证成绩单一模一样
一比一原版马来西亚世纪大学毕业证成绩单一模一样一比一原版马来西亚世纪大学毕业证成绩单一模一样
一比一原版马来西亚世纪大学毕业证成绩单一模一样
 
一比一原版(UW毕业证书)华盛顿大学毕业证如何办理
一比一原版(UW毕业证书)华盛顿大学毕业证如何办理一比一原版(UW毕业证书)华盛顿大学毕业证如何办理
一比一原版(UW毕业证书)华盛顿大学毕业证如何办理
 
欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】
欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】
欧洲杯买球-欧洲杯买球买球网好的网站-欧洲杯买球哪里有正规的买球网站|【​网址​🎉ac123.net🎉​】
 
一比一原版马里兰大学毕业证(UMD毕业证书)如何办理
一比一原版马里兰大学毕业证(UMD毕业证书)如何办理一比一原版马里兰大学毕业证(UMD毕业证书)如何办理
一比一原版马里兰大学毕业证(UMD毕业证书)如何办理
 
一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理
一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理
一比一原版(Deakin毕业证书)澳洲迪肯大学毕业证文凭如何办理
 
原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样
原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样
原版制作(MDIS毕业证书)新加坡管理发展学院毕业证学位证一模一样
 
modular-kitchen home plan civil engineering.pdf
modular-kitchen home plan civil engineering.pdfmodular-kitchen home plan civil engineering.pdf
modular-kitchen home plan civil engineering.pdf
 
一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理
一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理
一比一原版(lu毕业证书)英国拉夫堡大学毕业证如何办理
 
一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理
一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理
一比一原版(UCB毕业证)英国伯明翰大学学院毕业证如何办理
 
一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理
一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理
一比一原版(LSE毕业证书)伦敦政治经济学院毕业证如何办理
 
一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理
一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理
一比一原版(Brunel毕业证)英国布鲁内尔大学毕业证如何办理
 
一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理
一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理
一比一原版(NU毕业证书)诺森比亚大学毕业证如何办理
 
一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理
一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理
一比一原版(OU毕业证)美国俄克拉荷马大学毕业证如何办理
 
一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理
一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理
一比一原版(McGill毕业证)加拿大麦吉尔大学毕业证如何办理
 

Guava et Lombok au Brezth JUG

  • 1. Milou fait un régime Guava - Lombok todo
  • 3. @thierryleriche Thierry Leriche-Dessirier     icauda.com Consultant JEE freelance Professeur de Génie Logiciel à l’ESIEA Rédacteur pour Programmez Rédacteur pour Developpez.com
  • 5. 13 OOO OOO pages vues par mois 5 500 000 visites par mois 2 500 000 visites 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. DOG public class Dog { private private private private private private private private private private ... Integer String String SexeEnum Date String Boolean Double Double List<String> id ; name ; fullName ; sex ; birthday ; race ; lof ; weight ; size ; colors ; 5
  • 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.       Constructeurs Getters / setters toString () equals () hashCode () compareTo () 10 attributs           id name fullName sex birthday race lof weight size Colors  210 lignes
  • 14. Va chercher Guava      toString () equals () hashCode () compareTo () Commons  FAQ 1-2
  • 16. Java 5 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 + "]"; } 5 Simple, efficace et bien pourri   toString ()
  • 17. Java 5 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); 5 return sb.toString(); } Mieux mais sans plus   toString ()
  • 18. Guava public String toString() { return Objects.toStringHelper(this) .add("id", id) .add("name", name) .add("fullName", fullName) ... .add("colors", colors) .toString(); } G Builder  toString ()
  • 19. Java 5 birthday, fullname, name, race et sex public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; 5 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; } Carrément illisible   equals ()
  • 20. Guava birthday, fullname, name, race et sex public boolean equals(Object obj) { if (!(obj instanceof Dog)) return false; Dog other = (Dog) obj; G return Objects.equal(birthday, other.birthday) && Objects.equal(fullname, other.fullname) && Objects.equal(name, other.name) && Objects.equal(race, other.race) && sex == other.sex; }  equals ()
  • 21. Java 5 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; }  hashCode () 5
  • 22. Guava birthday, fullname, name, race et sex public int hashCode() { return Objects.hashCode(birthday, fullName, name, race, sex); }  hasCode() G
  • 23. Java 5 name, fullname, birthday, weight, size, 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; } ... }  compareTo () 5
  • 25. name, fullname, birthday, weight, size, race et sex 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 ()
  • 28. Régime  @NoArgsConstructor / @RequiredArgsConstructor / @AllArgsConstructor  constructeurs  @Getter / @Setter  @ToString  @EqualsAndHashCode  @Data  @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor
  • 29. Régime clic clic démo  @NoArgsConstructor / @RequiredArgsConstructor / @AllArgsConstructor  @Getter / @Setter  @ToString  @EqualsAndHashCode  @Data
  • 30. Java Lombok 10 attributs 210 lignes de code 12 lignes + 2-3 @ + compareTo()
  • 31. Factory @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); L name, sex
  • 32. Factory @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); 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); }
  • 35. Ressources 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) { ... } } ... 5
  • 36. Ressources 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; ... } L
  • 38. Délombok java -jar lombok.jar delombok src -d src-delomboked <properties> <lombok.sourceDirectory> ${project.basedir}/src/main/java </lombok.sourceDirectory> ... XML <build> <groupId>org.projectlombok</groupId> <artifactId>maven-lombok-plugin</artifactId> <executions> <execution> <phase>generate-sources</phase> </execution> </executions> ... mvn lombok:delombok
  • 39. Délombok 5 @Data public class Dog { private Integer id; public class Dog { private String name; private Integer id; private String fullName; private String name; private SexeEnum sex; private String fullName; private Date birthday; ... private String race; private List<String> colors; private Boolean lof; private Double weight; public DogLombok() { private Double size; } private List<String> colors; @java.lang.Override } @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Obje if (o == this) return true; if (o == null) return false; mvn lombok:delombok if (o.getClass() != this.getClass()) ret final Dog other = (Dog)o; if (this.getId() == null ? other.getId() ... 5 @java.lang.Override @java.lang.SuppressWarnings("all") public int hashCode() { final int PRIME = 31; int result = 1; result = result * PRIME + (this.getId()
  • 41. Annotations Pg                  @Builder @Action  @LazyGetter @Function  @FluentSetter @EnumId  @Predicate @Rethrow / @Rethrows @Singleton @AutoGenMethodStub @BoundPropertySupport / @BoundSetter @DoPrivileged @ExtensionMethod @ListenerSupport @WriteLock / @ReadLock @Await / @Signal / @AwaitBeforeAndSignalAfter @Sanitize.Normalize / .With @SwingInvokeLater / @SwingInvokeAndWait @Validate.NotEmpty / .NotNull / .With @VisibleForTesting
  • 42. Fluent @FluentSetter @Getter public class Dog { private Integer id ; private String name ; private String fullName ; ...  DogLombok dog = new DogLombok(); dog.name("Milou").sex(MALE); println( dog.getName()); println( dog.getSex()); //  Milou //  MALE L
  • 43. Builder @Builder @Getter public class Dog { private Integer id ; private String name ; private String fullName ; ...  Dog dog = Dog.dog().name("Milou").sex(MALE).build(); println( dog.getName()); println( dog.getSex()); //  Milou //  MALE L
  • 44. extension L @ExtensionMethod({ Dog.class, MyDogExtensionClass.class }) public class DogWithExtension { public void foo() { Dog milou = new Dog("Milou", 12.5, ...); boolean isTooFat = milou.isTooFat(); } } class MyDogExtensionClass { public static boolean isTooFat(final Dog dog) { double imc = dog.getWeight() / pow(dog.getSize(), 2); return 25 < imc; } } Avec paramètres  FAQ 9  http://blog.developpez.com/todaystip/p11165/dev/java/extensionmethod-de-lombok-pg/
  • 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. Java 5 < new Vs static factories > List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); 5 Map<String, Integer> ages = new HashMap<String, Integer>();
  • 50. < new Vs static factories > Java 5 5 List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); dur dur ? Map<String, Integer> ages = new HashMap<String, Integer>(); Map<String, List<String>> trucs = new HashMap<String, List<String>>(); 5 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 = ...
  • 51. Java 5 < new Vs static factories > List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); 5 7 Java 7 Map<String, Integer> ages = new HashMap<String, Integer>(); List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); Qui utilise Java 7 en prod ?
  • 52. Java 5 < new Vs static factories > List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); 5 7 G Java 7 Map<String, Integer> ages = new HashMap<String, Integer>(); List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); Guava Qui utilise Java 7 en prod ? List<Integer> primeNumbers = newArrayList(); Set<String> colors = newTreeSet(); Map<String, Integer> ages = newHashMap(); Dès maintenant !
  • 53. Java 5 < new Vs static factories > List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); 5 7 G Java 7 Map<String, Integer> ages = new HashMap<String, Integer>(); List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); Guava Qui utilise Java 7 en prod ? List<Integer> primeNumbers = newArrayList(); Set<String> colors = newTreeSet(); Map<String, Integer> ages = newHashMap(); Lombok Dès maintenant ! var primeNumbers = new ArrayList<Integer>(); -> primeNumbers.size(); ... L
  • 54. List of dogs < new Vs static factories > 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, ...)); [Milou, Rintintin, Volt, Lassie, Pluto, Medor] G
  • 55. Immutables Pour que ça ne change pas
  • 57. immutable Quand ? 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. Java 5 < unmodifiables Vs immutables > Set<Integer> temp = new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7)); Set<Integer> primes = Collections.unmodifiableSet(temp);
  • 59. Java 5 < unmodifiables Vs immutables > Set<Integer> temp = new LinkedHashSet<Integer>(Arrays.asList(1, 2, 3, 5, 7)); Guava Set<Integer> primes = Collections.unmodifiableSet(temp); Set<Integer> primes = ImmutableSet.of(1, 2, 3, 5, 7); G
  • 60. Of < unmodifiables Vs immutables > ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E e1) e1, e1, e1, e1, e1, E E E E E e2) e2, e2, e2, e2, E E E E G e3) e3, E e4) e3, E e4, E e5) e3, E e4, E e5, E e6, E...) Of Ne prend pas de null ImmutableSet.of() Vide Map et List  FAQ 4  http://blog.developpez.com/guava/p10589/collection/title-212/
  • 61. Java 5 < Copie de défense > public 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
  • 62. Guava < Copie de défense > public 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; } Message clair G
  • 63. Collections en plus Multimap, Bipap, Multiset, Table
  • 64. Java 5 < Multi Map > Map<String, List<String>> dogFavoriteColors = new HashMap<String, List<String>>(); 5 5 List<String> milouColors = dogFavoriteColors.get("Milou"); if(milouColors == null) { milouColors = new ArrayList<String>(); dogFavoriteColors.put("Milou",milouColors); } milouColors.add("Vert");
  • 65. Java 5 < Multi Map > Map<String, List<String>> dogFavoriteColors = new HashMap<String, List<String>>(); 5 5 Guava List<String> milouColors = dogFavoriteColors.get("Milou"); if(milouColors == null) { milouColors = new ArrayList<String>(); dogFavoriteColors.put("Milou",milouColors); } milouColors.add("Vert"); Multimap<String, String> dogFavoriteColors = HashMultimap.create(); dogFvoriteColors2.put("Milou", "Jaune"); dogFavoriteColors2.put("Milou", "Rouge"); G
  • 66. Guava < Bi Map > BiMap<String, Dog> tatouages = HashBiMap.create(); tatouages.put("ABC123", new Dog("Milou") ); tatouages.put("MBD324", new Dog("Volt") ); tatouages.put("JFT672", new Dog("Lassie") ); println( tatouages ); {ABC123=Milou, MBD324=Volt, JFT672=Lassie} ABC123=Milou MDB324=Volt JFT672=Lassie println( tatouages.inverse() ); Une map bijective {Milou=ABC123, Volt=MBD324, Lassie=JFT672} Il est possible de changer la valeur associée à une clé mais pas d'avoir deux clés avec la même valeur (IllegalArgumentException). G
  • 67. Guava < Multi Set > 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 ); [2, 3 x 2, 5, 7, 11] println( ages.count(3) ) 2 G
  • 70. DOG < Preconditions > public class Dog { private Integer private String private String ... id ; name ; 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; ... } 5
  • 71. DOG < Preconditions > import static com.google.common.base.Preconditions.*; public class Dog { private Integer private String private String ... id ; name ; fullName ; G public Dog(String name, String fullName, ...) { this.name = checkNotNull(name, "bla bla"); this.fullName = checkNotNull(fullName, "bla bla"); ... } checkNotNull()  NPE checkArgument()  IAE checkState()  ISE
  • 72. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); "Lassie, Volt, Milou" G Java classique 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();
  • 73. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); "Lassie, Volt, Milou" G String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", null, "Milou"));  NPE 
  • 74. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); "Lassie, Volt, Milou" G String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", null, "Milou"));  NPE  G String names = Joiner.on(", ") .skipNulls() .join(newArrayList("Lassie", "Volt", null, "Milou")); "Lassie, Volt, Milou"
  • 75. Joiner String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", "Milou")); "Lassie, Volt, Milou" G String names = Joiner.on(", ") .join(newArrayList("Lassie", "Volt", null, "Milou"));  NPE  G G String names = Joiner.on(", ") .skipNulls() .join(newArrayList("Lassie", "Volt", null, "Milou")); "Lassie, Volt, Milou" String names = Joiner.on(", ") .useForNull("Anonymous")) .join(newArrayList("Lassie", "Volt", null, "Milou")); "Lassie, Volt, Anonymous, Milou"  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(",") [ "Lassie", .split("Lassie, Volt, ,Milou"); "Volt", " ", "Milou" ]
  • 78. Splitter Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, Milou"); [ "Lassie", "Volt", "Milou" ] Iterable<String> dogNames = Splitter.on(",") [ "Lassie", .split("Lassie, Volt, ,Milou"); "Volt", " ", "Milou" ] Iterable<String> dogNames = Splitter.on(",") [ "Lassie", .trimResults() "Volt", .split("Lassie, Volt, ,Milou"); "", "Milou" ]
  • 79. Splitter Iterable<String> dogNames = Splitter.on(",") .split("Lassie, Volt, Milou"); [ "Lassie", "Volt", "Milou" ] Iterable<String> dogNames = Splitter.on(",") [ "Lassie", .split("Lassie, Volt, ,Milou"); "Volt", " ", "Milou" ] Iterable<String> dogNames = Splitter.on(",") [ "Lassie", .trimResults() "Volt", .split("Lassie, Volt, ,Milou"); "", "Milou" ] Iterable<String> dogNames = Splitter.on(",") .trimResults() [ "Lassie", .omitEmptyStrings() .split("Lassie, Volt, ,Milou"); "Volt", "Milou" ]  http://blog.developpez.com/guava/p11045/annotation/splitter-pour-separer-des-items/ G
  • 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. 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() );  http://blog.developpez.com/guava/p11163/base/le-wrapper-optional-de-guava/
  • 86. Super Chien public class SuperChien implements SuperHero { private private private private String double Set<String> Set<String> surnom ; poids ; couleursCostume ; pouvoirs ; 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. Transformation < Transformation > List<SuperChien> superChiens = Lists.transform(dogs, new Function<Dog, SuperChien>() { @Override public SuperChien apply(Dog dog) { SuperChien chien = new SuperChien(); G 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]
  • 88. Transformation < Transformation > List<SuperChien> superChiens = Lists.transform(dogs, new Function<Dog, SuperChien>() { @Override public SuperChien apply(Dog dog) { SuperChien chien = new SuperChien(); ... return chien; } }); G  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(...
  • 89. < Filtre > Filtre G Predicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; } } Iterable<Dog> maleDogs = Iterables.filter(dogs, malePredicate); [Milou, Rintintin, Volt, Pluto, Medor] G
  • 90. Filtre < Filtre > Predicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; } } Iterable<Dog> maleDogs = Iterables.filter(dogs, malePredicate); [Milou, Rintintin, Volt, Pluto, Medor] Dog firstMaleDog = Iterables.find(dogs, malePredicate); Milou G G G
  • 91. Filtre < Filtre > Predicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; } } Iterable<Dog> maleDogs = Iterables.filter(dogs, malePredicate); [Milou, Rintintin, Volt, Pluto, Medor] Dog firstMaleDog = Iterables.find(dogs, malePredicate); Milou G G G Dog firstMaleDog = Iterables.find(femaleDogs, malePredicate, DEFAULT_DOG ); Default dog
  • 92. Pas fluent < Fluent or not fluent ? > 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); G G G [Milou, Rintintin, Volt, Pluto, Medor]
  • 93. Pas fluent < Fluent or not fluent ? > Iterable<FullDog> maleDogs = Iterables.filter(dogs, malePredicate); Fluent Iterable<String> maleNames = Iterables.transform(maleDogs, nameFunction); List<String> maleNames2 = FluentIterable.from(dogs) .filter(malePredicate) .transform(nameFunction) .toImmutableList(); G G Guava 12.0  http://blog.developpez.com/guava/p11092/annotation/fluentiterable-surmon-chien-guava/ [Milou, Rintintin, Volt, Pluto, Medor]
  • 95. Web Service < Memoization > public class DogService { @Inject private PetShopWebService service; public Integer getNumberDogsSoldYesterday() { return service.checkSales( "dog" ); } 5
  • 96. Web Service < Memoization > Cache manuel public class DogService { @Inject private PetShopWebService service; public Integer getNumberDogsSoldYesterday() { return service.checkSales( "dog" ); } private Integer nbOfDogsSold; public Integer getNumberDogsSoldYesterday() { if (nbOfDogsSold == null) { nbOfDogsSold = service.checkSales( "dog" ); } return nbOfDogsSold; } 5 5 Double check null…
  • 97. Guava < Memoization > 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(); } G
  • 98. Guava < Memoization > 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(); } G
  • 99. Web Service < Cache > public class DogService { @Inject private PetShopWebService service; private Map<String, Dog> dogMap = Maps.newHashMap(); 5 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; } Quid du timeout ? Max ?
  • 100. Guava < Cache > public class DogService { @Inject private PetShopWebService service; G 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 }
  • 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 < Is in list ? > int NB_OF_DOGS = 100000; contains 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); } final Dog milou = new Dog(); milou.setName("Milou"); ... boolean isInList = dogs.contains(milou); 5 5 false (14 ms) dogs.add(milou); boolean isInList = dogs.contains(milou); true (14 ms)
  • 104. Bloom filter < Is in list ? > Funnel<Dog> dogFunnel = new Funnel<Dog>() { public void funnel(Dogdog, PrimitiveSink sink) { sink.putString(dog.getName()) .putString(dog.getFullName()) .putString(dog.getRace()); }}; G BloomFilter<Dog> bloom = BloomFilter.create(dogFunnel, NB_OF_DOGS, 0.01); for (int i = 0; i < NB_OF_DOGS; i++) { ... bloom.put(dog); boolean isInList = bloom.mightContain(milou); false (0 ms) bloom.put(milou); boolean isInList = bloom.mightContain(milou); Guava 13 true (0 ms)  http://blog.developpez.com/guava/p11149/collection/bloom-filter-de-guava-13/
  • 105. Guava or not Guava ? Avantages et inconvénients
  • 106. Pro / Cons  Ne pas en abuser…  Utile  Bonnes pratiques
  • 109. ICAUDA  http://icauda.com  http://icauda.com/articles.html  http://icauda.com/cours.html (articles) (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)
  • 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. toString Régime : la méthode Commons ? public String toString() { return new ToStringBuilder(this) .append("id", id) .append("name", name) .append("fullName", fullName) ... .append("colors", colors) .toString(); } 2 L
  • 114. equals Régime : la méthode Commons ? 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(); 2 } L
  • 115. hashCode Régime : la méthode Commons ? public int hashCode() { return new HashCodeBuilder(17, 37) .append(birthday) .append(fullname) .append(name) .append(race) .append(sex) .toHashCode(); } 2 L
  • 116. compareTo Régime : la méthode Commons ? 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(); } 2 L
  • 117. Transformation Fonctionnal prog Vs boucle for : quand ? List<SuperChien> superChiens = newArrayList( Lists.transform(dogs, new Function<Dog, SuperChien>() { @Override public SuperChien apply(Dog dog) { SuperChien chien = new SuperChien(); ... return chien; } })); 3 Vs G List<SuperChien> superChiens = newArrayList(); for(Dog dog : dogs) { SuperChien chien = new SuperChien(); ... superChiens.add(chien); } G http://code.google.com/p/guava-libraries/wiki/FunctionalExplained
  • 118. of Créer des Maps public static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Milou", 32, "Volt", 7, "Pluto", 37, "Lassie", 17); Builder G 4 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(); G
  • 119. Java 5 Charsets String name = "Milou"; try { byte[] bytes = name.getBytes("UTF-8"); 5 } catch (UnsupportedEncodingException e) { throw new AssertionError(e); } Guava Ca n’arrive jamais cette exception  5 String name = "Milou"; byte[] bytes = name.getBytes(Charsets.UTF_8); G
  • 120. Converter Spring import org.springframework...Converter; G @Component("dogToChienConverter") public class DogToChienConverter implements Converter<List<Dog>, List<SuperChien>> { 6 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; } Lazy or not lazy ?
  • 122. Licences  Lombok :  Lombok-pg :  Guava : Apache License 2.0  Commons : 8 MIT License MIT License Apache License 2.0
  • 123. 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 } } class MyOtherClass { public static <T> void print(final T value) { System.out.println(value); } } 9 On peut mettre autre chose qu’un "Object", par exemple un "Arrays" , un "Dog" , etc. L
  • 124. 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(); s2.print("vide"); //  null //  vide } } 9 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); } L
  • 125. < Chrono > Guava Java 5 long start = new Date().getTime(); foo(); // traitement long (ou pas) long end = new Date().getTime(); 5 long duration = end - start; // 11 ms Stopwatch sw = new Stopwatch(); sw.start(); foo(); // traitement long (ou pas) sw.stop(); long duration = sw.elapsedMillis(); // 11 ms 10 G 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 public class Dog implements Comparable<Dog> { private Integer id ; private String name ; private String fullName ; 5 ... @Override public int compareTo(Dog dog) { return ...; } 12 implements List ? aie aie aie
  • 128. Impl @AutoGenMethodStub public class Dog implements Comparable<Dog> { private Integer id ; private String name ; private String fullName ; ... 12 L
  • 129. Seconde liste And, or, in… List<Dog> dogs2 = newArrayList( new Dog("Rintintin", 45.0, MALE, ...), 13 new Dog("Pluto", 22.0, MALE, ...), new Dog("Lulu", 35.6, MALE, ...)); [Rintintin, Pluto, Lulu] Liste 2 : dogs2 [Milou, Rintintin, Volt, Lassie, Pluto, Medor] Liste 1 : dogs G
  • 130. And, or, in... And, or, in… G 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 G import static com.google.common.base.Predicates.or; [Milou, Rintintin, Volt, Lassie, Pluto, Medor] Liste 2 : dogs2 13 Liste 1 : dogs boolean isTintinInOne = or( in(dogs), in(dogs2) ) .apply(new Dog("Tintin"); false [Rintintin, Pluto, Lulu]
  • 131. Partition Limit Partition, limit List<List<FullDog>> partition = Lists.partition(dogs, 4); [Milou, Rintintin, Volt, Lassie] [Pluto, Medor] List<FullDog> first4Dogs = newArrayList(Iterables.limit(dogs, 4)); 14 [Milou, Rintintin, Volt, Lassie] G G
  • 132. Java Guava Inférence de type List<Integer> primeNumbers = new ArrayList<Integer>(); List<Integer> primeNumbers = newArrayList(); public static <E> ArrayList<E> newArrayList() { return new ArrayList<E>(); } 15  http://blog.developpez.com/guava/p11334/collection/inference-de-type-avec-guava
  • 133. Coût du bloom 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(); 16 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 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 16 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. Guava < Table > // Sexe, couleur, nom G 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"); 17
  • 136. Guava < Table > // Sexe, couleur, nom G 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 } 17 Map<String, String> femaleRow = dogTable.row(FEMALE); println( femaleRow ) { noir=Lassie, blanc=Pupuce }
  • 137. Guava < Table > // 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 ) 17 { FEMALE=Pupuce, MALE=Milou } Map<SexeEnum, String> jauneColumn = dogTable.column("jaune"); println( jauneColumn ) { MALE=Pluto }
  • 138. Pas d’écrasement des getters existants @Data public class MicroDog { private String name; private Integer age; public String getName() { return "*" + name + "*"; } } 18 @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. Ressources < I/O > 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) { ... } } ... 5
  • 142. Java 7 < I/O > public void lireJava7(String from) { try(InputStream in = new FileInputStream(from)) { ... while (true) { ... } } } 7
  • 145. Todo