google guava & emf @ gtug nantes

154
Google Guava 2011/04/26 Eclipse Modeling Framework & Mikaël Barbero

Upload: mikaelbarbero

Post on 15-Jan-2015

4.866 views

Category:

Technology


5 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Google Guava & EMF @ GTUG Nantes

Google Guava

2011/04/26

EclipseModelingFramework

&

Mikaël Barbero

Page 2: Google Guava & EMF @ GTUG Nantes

Introduction

1http://www.flickr.com/photos/drspam/295023450/

Page 3: Google Guava & EMF @ GTUG Nantes

About me

‣ Modeling consultant‣ Research engineer‣ Trainer‣ Conference Speaker‣ Language guy ;)

‣ Eclipse committer‣ Guava-OSGi packager‣ EMFPath lead

Page 4: Google Guava & EMF @ GTUG Nantes

Nantes

Paris

Page 5: Google Guava & EMF @ GTUG Nantes

Strategic members

Page 6: Google Guava & EMF @ GTUG Nantes

AcceleoEMFCompareATLGMFOCLMylyn IntentEEFSTP

Leading

Page 7: Google Guava & EMF @ GTUG Nantes
Page 8: Google Guava & EMF @ GTUG Nantes
Page 9: Google Guava & EMF @ GTUG Nantes
Page 10: Google Guava & EMF @ GTUG Nantes
Page 11: Google Guava & EMF @ GTUG Nantes

Available technologies

Page 12: Google Guava & EMF @ GTUG Nantes

GuavaOverview

2http://www.flickr.com/photos/slowburn/2986303105/

Page 14: Google Guava & EMF @ GTUG Nantes
Page 15: Google Guava & EMF @ GTUG Nantes

Java library used internally @

Google for years

Superset of Google

Collections

About Guava

Page 16: Google Guava & EMF @ GTUG Nantes

About Guava

Apache License v2http://www.apache.org/licenses/LICENSE-2.0

Page 17: Google Guava & EMF @ GTUG Nantes

About Guava

2007 2008 2009 2010 2011

Google Collec

tions

v0.5

Google Collec

tions

v1Guava

r03

Guava r0

8

Frequent releases (quarterly base)Latest release (r09): April, 7th

Page 18: Google Guava & EMF @ GTUG Nantes
Page 19: Google Guava & EMF @ GTUG Nantes
Page 20: Google Guava & EMF @ GTUG Nantes

Why using Guava?

Simplexity

http://www.flickr.com/photos/gio_vencato/4941064345/

Page 21: Google Guava & EMF @ GTUG Nantes

Why using Guava?

http://www.flickr.com/photos/reway2007/3300379295/

Page 22: Google Guava & EMF @ GTUG Nantes

Why using Guava?

http://www.flickr.com/photos/funtik/1175522045/

Mainstream?

Page 23: Google Guava & EMF @ GTUG Nantes

Why using Guava?

Helping others

http://www.flickr.com/photos/thearches/4381959041/

Page 24: Google Guava & EMF @ GTUG Nantes

IO Networking Concurrency

Primitive types Collections

Inside Guava

GWT compatibility is tested (see @GwtCompatible)

Page 25: Google Guava & EMF @ GTUG Nantes

Comparison withApache Commons

http://stackoverflow.com/questions/4542550/what-are-the-big-improvements-between-guava-and-apache-equivalent-libraries

More ModernBetter

DesignedBetter

Supported

Java 5

Respects JDK contracts

Best practices and patterns

Orthogonality (@Beta to test designs)

Actively developed

(- commons 3.0)

Google depends on it

(e.g., Google Guice)

Page 26: Google Guava & EMF @ GTUG Nantes

Bestrep.

Page 27: Google Guava & EMF @ GTUG Nantes

Corest of the core

3http://www.flickr.com/photos/27384147@N02/5211738745/

Page 28: Google Guava & EMF @ GTUG Nantes

public class Person { final String name, nickname; final Movie favMovie;

@Override public boolean equals(Object object) { if (object instanceof Person) { Person that = (Person) object; return Objects.equal(this.name, that.name) && Objects.equal(this.nickname, that.nickname) && Objects.equal(this.favMovie, that.favMovie); } return false; }

@Override public int hashCode() { return Objects.hashCode(name, nickname, favMovie); }}

Objects class

Example from http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 29: Google Guava & EMF @ GTUG Nantes

public class Person { final String name, nickname; final Movie favMovie;

//...

@Override public String toString() { return Objects.toStringHelper(this) .add("name", name) .add("nickname", nickname) .add("favMovie", favMovie) .toString(); }

public String preferredName() { return Objects.firstNonNull(nickname, name); }}

Objects class

Example from http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 30: Google Guava & EMF @ GTUG Nantes

Preconditions

Defensive coding

if (state != State.PLAYABLE) { throw new IllegalStateException( "Can't play movie; state is " + state);}

Preconditions.checkState(state == State.PLAYABLE, "Can't play movie; state is %s", state);

Example from http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 31: Google Guava & EMF @ GTUG Nantes

Preconditions

Defensive coding

public void setRating(StarRating rating) { if (rating == null) { throw new NullPointerException(); } this.rating = rating;}

public void setRating(StarRating rating) { this.rating = checkNotNull(rating);}

Example from http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 32: Google Guava & EMF @ GTUG Nantes

Equivalences strategies

public interface Equivalence<T> { boolean equivalent(@Nullable T a, @Nullable T b); int hash(@Nullable T t);}

Equivalence equals = Equivalences.equals();Equivalence identity = Equivalences.identity();

Equivalence<String> elementEquivalence = ...;Equivalence<Iterable<String>> pairwise = Equivalences.pairwise(elementEquivalence);Collection<String> c1, c2;pairwise.equivalent(c1, c2);

Page 33: Google Guava & EMF @ GTUG Nantes

Suppliers

public interface Supplier<T> { T get();}

Supplier<String> s = ...;Supplier<String> memoizing = Suppliers.memoize(s);Supplier<String> expiring = Suppliers.memoizeWithExpiration(s, 100, TimeUnit.SECONDS);Supplier<String> ofInstance = Suppliers.ofInstance("Always returning");

Page 34: Google Guava & EMF @ GTUG Nantes

Throwables

Throwables.getCausalChain(throwable);Throwables.getRootCause(throwable);

Throwables.getStackTraceAsString(throwable);

Throwables.propagateIfInstanceOf(throwable, IOException.class);

Throwables.propagateIfPossible(throwable);

try { someMethodThatCouldThrowAnything();} catch (IKnowWhatToDoWithThisException e) { handle(e);} catch (Throwable t) { Throwables.propagateIfPossible(t); throw new RuntimeException("unexpected", t);}

Page 35: Google Guava & EMF @ GTUG Nantes

@Annotation

@Beta

@GwtCompatible @GwtIncompatible

@VisibleForTesting

Page 36: Google Guava & EMF @ GTUG Nantes

Strings

4http://www.flickr.com/photos/gernot/2554175292/

Page 37: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

CharMatcher

StringUtil example: allAscii, collapse, collapseControlChars, collapseWhitespace, indexOfChars, lastIndexNotOf, numSharedChars, removeChars, removeCrLf, replaceChars, retainAllChars, strip, stripAndCollapse, stripNonDigits, ...

Partial cross product of two notions: (a) what's a "matching" character?

(b) what to do with those matching characters?

CharMatcher:An instance of this type represents part (a), and the operation you invoke on it represents part (b).

+1

Page 38: Google Guava & EMF @ GTUG Nantes

Getting a CharMatcher

CharMatcher.is('x') CharMatcher.isNot('_') CharMatcher.oneOf("aeiou").negate() CharMatcher.inRange('a', 'z').or(inRange('A', 'Z'))

Subclass CharMatcher, implement matches(char c)

CharMatcher.WHITESPACE (Unicode) CharMatcher.JAVA_DIGIT CharMatcher.ASCIICharMatcher.ANY

Factory methods (examples)

Predefined constants(examples)

Now check out all that you can do...http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 39: Google Guava & EMF @ GTUG Nantes

‣ boolean matchesAllOf(CharSequence)‣ boolean matchesAnyOf(CharSequence) ‣ boolean matchesNoneOf(CharSequence) ‣ int indexIn(CharSequence, int)‣ int lastIndexIn(CharSequence, int) ‣ int countIn(CharSequence) ‣ String removeFrom(CharSequence) ‣ String retainFrom(CharSequence) ‣ String trimFrom(CharSequence) ‣ String trimLeadingFrom(CharSequence) ‣ String trimTrailingFrom(CharSequence) ‣ String collapseFrom(CharSequence, char) ‣ String trimAndCollapseFrom(CharSequence, char) ‣ String replaceFrom(CharSequence, char)

Using your CharMatcher

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 40: Google Guava & EMF @ GTUG Nantes

Using your CharMatcher

http://scaramoche.blogspot.com/2010/05/googles-guava-library-tutorial-part-1.html

String string = "Scream 4";CharMatcher matcher = CharMatcher.JAVA_LETTER_OR_DIGIT;int count = matcher.countIn(string);

System.out.println("Letter or digit count: "+count);// Letter or digit count: 7

System.out.println(matcher.matchesAllOf("scream"));// true

System.out.println(matcher.matchesAllOf("scream "));// false

System.out.println(matcher.matchesNoneOf("_?=)("));// true

Page 41: Google Guava & EMF @ GTUG Nantes

Splitter

‣ regular expression ‣ result as an array ‣ its way of handling empty pieces (which is very strange)

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

",a,,b,".split(",") returns...(a) "", "a", "", "b", "" (b) null, "a", null, "b", null (c) "a", null, "b" (d) "a", "b" (e) None of the above

Mini-puzzler

+1

JDK has splitter

Page 43: Google Guava & EMF @ GTUG Nantes

Splitter

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

The default behavior is simplistic:

//yields [" foo", " ", "bar", " quux", ""] Splitter.on(',').split(" foo, ,bar, quux,");

//yields ["foo", "bar", "quux"] Splitter.on(',') .trimResults() .omitEmptyStrings() .split(" foo, ,bar, quux,");

If you want extra features, ask for them!

Page 44: Google Guava & EMF @ GTUG Nantes

Ascii, CharsetsAscii

‣Charsets.ISO_8859_1;‣Charsets.US_ASCII;‣Charsets.UTF_16;‣Charsets.UTF_16BE; ‣Charsets.UTF_16LE;‣Charsets.UTF_8;

list of bytes constants for each Char between 0x00 & 0x7F

Charsets

Guaranteed to be supported by

all Java platform implementations

try { bytes = string.getBytes("UTF-8");} catch (UnsupportedEncodingException e) { // how can this possibly happen? throw new AssertionError(e);}

No more

Page 45: Google Guava & EMF @ GTUG Nantes

Strings

boolean b = Strings.isNullOrEmpty(s);

String str = Strings.emptyToNull(s);

String str = Strings.nullToEmpty(s);

Page 46: Google Guava & EMF @ GTUG Nantes

CaseFormat

‣ LOWER_CAMEL ‣ Java variable naming convention, e.g., "lowerCamel".

‣ LOWER_HYPHEN‣ Hyphenated variable naming convention, e.g., "lower-hyphen".

‣ LOWER_UNDERSCORE ‣ C++ variable naming convention, e.g., "lower_underscore".

‣ UPPER_CAMEL ‣ Java and C++ class naming convention, e.g., "UpperCamel".

‣ UPPER_UNDERSCORE ‣ Java and C++ constant naming convention, e.g., "UPPER_UNDERSCORE".

CaseFormat.to(CaseFormat.UPPER_UNDERSCORE, s);Example

Page 47: Google Guava & EMF @ GTUG Nantes

Collections

5http://www.flickr.com/photos/tochis/1169807846/

Page 48: Google Guava & EMF @ GTUG Nantes

Ordering

Comparator is easy to implement, but a pain to use

Push the Comparator<T> interface to the next level

http://scaramoche.blogspot.com/2010/05/googles-guava-library-tutorial-part-2.html

public interface Comparator<T> {

abstract int compare(T, T);

abstract boolean equals(Object);

}

Page 49: Google Guava & EMF @ GTUG Nantes

public class Employee implements Comparable<Employee> { private final int id; private final String name; private final int yearsOfService;

public Employee(int id, String name, int yearsOfService) { this.id = id; this.name = name; this.yearsOfService = yearsOfService; }

public int getId() { return id; }

public String getName() { return name; }

public int getYearsOfService() { return yearsOfService; }

@Override public int compareTo(Employee employee) { return this.getName().compareTo(employee.getName()); }

@Override public String toString() { return Objects.toStringHelper(this) .add("id", id) .add("name", name) .add("years of service", yearsOfService) .toString(); }}

http://scaramoche.blogspot.com/2010/05/googles-guava-library-tutorial-part-2.html

Simple data class

Ordering

Page 50: Google Guava & EMF @ GTUG Nantes

Ordering

Employee anakinSk = new Employee(4, "Anakin Skywalker", 4);Employee darthVader = new Employee(3, "Darth Vader", 5);Employee hanSolo = new Employee(2, "Han Solo", 10);List <Employee> employeeList = Lists.newArrayList(anakinSk, hanSolo, darthVader);System.out.println("employee list: "+employeeList);

employee list: [Employee{id=4, name=Anakin Skywalker, years of service=4}, Employee{id=2, name=Han Solo, years of service=10}, Employee{id=3, name=Darth Vader, years of service=5}]

http://scaramoche.blogspot.com/2010/05/googles-guava-library-tutorial-part-2.html

Page 51: Google Guava & EMF @ GTUG Nantes

Ordering

Comparator<Employee> yearsComparator = new Comparator<Employee>() { @Override public int compare(Employee employee1, Employee employee2) { return (employee1.getYearsOfService() - employee2 .getYearsOfService()); }};

Comparator<Employee> idComparator = new Comparator<Employee>() { @Override public int compare(Employee employee1, Employee employee2) { return (employee1.getId() - employee2.getId()); }};

Define your own Comparator

http://scaramoche.blogspot.com/2010/05/googles-guava-library-tutorial-part-2.html

Page 52: Google Guava & EMF @ GTUG Nantes

Ordering

Ordering<Employee> orderUsingYearsComparator = Ordering.from(yearsComparator);

Create an Ordering from a Comparator

List<Employee> sortedCopy = orderUsingYearsComparator.sortedCopy(employeeList);System.out.println("sorted copy: " + sortedCopy);

Use your ordering, e.g. to sort

sorted copy: [Employee{id=4, name=Anakin Skywalker, years of service=4}, Employee{id=3, name=Darth Vader, years of service=5}, Employee{id=2, name=Han Solo, years of service=10}]

http://scaramoche.blogspot.com/2010/05/googles-guava-library-tutorial-part-2.html

Page 53: Google Guava & EMF @ GTUG Nantes

Ordering

toString() ordering

Ordering<Object> toStringOrdering = Ordering.usingToString();

Ordering<Employee> natural = Ordering.natural();

Natural ordering (Comparable<T>)

http://scaramoche.blogspot.com/2010/05/googles-guava-library-tutorial-part-2.html

Page 54: Google Guava & EMF @ GTUG Nantes

What you can do with Ordering

‣ Ordering.min(Iterable<E>) ‣ Ordering.max(Iterable<E>)‣ Ordering.leastOf(Iterable<E>, int)‣ Ordering.greatestOf(Iterable<E>, int)

‣ Ordering.isOrdered(Iterable<? extends T>)‣ Ordering.isStrictlyOrdered(Iterable<? extends T>)

‣ Ordering.binarySearch(List<? extends T>, T)

Page 55: Google Guava & EMF @ GTUG Nantes

What you can do with Ordering

‣ Ordering.sortedCopy(Iterable<E>)‣ Ordering.immutableSortedCopy(Iterable<E>)

Better than new TreeSet(Collection)

Do not discard duplicates elements

Performed sort is stable

Page 56: Google Guava & EMF @ GTUG Nantes

Ordering is configurable

‣ Ordering.reverse()‣ Ordering.lexicographical()‣ Ordering.nullsFirst()‣ Ordering.nullsLast()‣ Ordering.reverse()

[] < [1] < [1, 1] < [1, 2] < [2]

Lexicographical returns an Ordering on Iterable of T

Page 57: Google Guava & EMF @ GTUG Nantes

ObjectArrays

‣ concat(T, T[])

‣ concat(T[], T)

‣ concat(T[], T[], Class<T>)

‣ newArray(Class<T>, int)

‣ newArray(T[], int)

Page 58: Google Guava & EMF @ GTUG Nantes

Multiset & Multimap

Historically, multisets (aka bags) and multimaps emulated atop maps

Multimap = Map<K, List<V>>

Multiset = Map<K, Integer>

Page 59: Google Guava & EMF @ GTUG Nantes

When to use Multiset?

‣"I kinda want a Set except I can have duplicates"‣ card games example‣ changing to List sacrifices contains() performance ‣"Are these Lists equal, ignoring order?"‣ write a utility method for this? Histograms

‣"What distinct tags am I using on my blog, and how many times do I use each one?"

Multiset performance varies by the number

of distinct elements, not total size.

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 60: Google Guava & EMF @ GTUG Nantes

Map<String, Integer> tags = new HashMap<String, Integer>();for (BlogPost post : getAllBlogPosts()) { for (String tag : post.getTags()) {

int value = tags.containsKey(tag) ? tags.get(tag) : 0; tags.put(tag, value + 1);

}}

Multiset

distinct tags: tags.keySet()

count for "java" tag: tags.containsKey("java") ? tags.get("java") : 0;

total count: // oh crap...

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Ever done this?

Usage

Page 61: Google Guava & EMF @ GTUG Nantes

Multiset

Multiset<String> tags = HashMultiset.create();for (BlogPost post : getAllBlogPosts()) {

tags.addAll(post.getTags());}

distinct tags: tags.elementSet();

count for "java" tag: tags.count("java");

total count: tags.size();

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Would you rather do this?

Usage(hurrah)

Page 62: Google Guava & EMF @ GTUG Nantes

‣What if you need to remove/decrement?‣Don't accidentally go negative ‣Don't forget to prune! ‣(Or just use a Multiset.)

‣What about concurrency? ‣Lock the entire map just to add one tag? ‣(Or just use our ConcurrentMultiset.)

Multiset API

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

When you use a powerful library, your code can easily evolve.

Page 63: Google Guava & EMF @ GTUG Nantes

Multiset API

‣int count(Object element);

‣int add(E element, int occurrences);

‣boolean remove(Object element, int occurrences);

‣int setCount(E element, int newCount);

‣boolean setCount(E e, int oldCount, int newCount);

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 64: Google Guava & EMF @ GTUG Nantes

Multiset implementations

ImmutableMultisetHashMultisetLinkedHashMultisetTreeMultisetEnumMultisetConcurrentHashMultiset

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

+1

Page 65: Google Guava & EMF @ GTUG Nantes

When to use Multimap?

Map<Salesperson, List<Sale>> map = new HashMap<Salesperson, List<Sale>>();public void makeSale(Salesperson salesPerson, Sale sale) { List<Sale> sales = map.get(salesPerson); if (sales == null) { sales = new ArrayList<Sale>(); map.put(salesPerson, sales); } sales.add(sale);}

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Ever done this?

Page 66: Google Guava & EMF @ GTUG Nantes

When to use Multimap?

The code on the previous slide is ‣Verbose‣Bug-prone ‣Limited in functionality ‣Using the wrong abstraction

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Multimap<Salesperson, Sale> multimap = ArrayListMultimap.create();public void makeSale(Salesperson salesPerson, Sale sale) { multimap.put(salesPerson, sale);}

Would you rather do this?

Page 67: Google Guava & EMF @ GTUG Nantes

More about MultimapA collection of key-value pairs (entries), like a Map,

except that keys don't have to be unique.

{a=1, a=2, b=3, c=4, c=5, c=6}

multimap.get(key) returns a modifiable Collection view of the values associated with that key.

Sometimes you want to think of it as a Map<K, Collection<V>> -- use the asMap() view:

{a=[1, 2], b=[3], c=[4, 5, 6]}http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 68: Google Guava & EMF @ GTUG Nantes

Multimap subtypes

‣ListMultimap: the get() view implements List‣preserves the ordering of entries per key; ‣can have duplicate entries

‣SetMultimap: the get() view implements Set‣no duplicate entries, ‣ordering of entries is impl-dependent

‣SortedSetMultimap: the get() view implements SortedSet‣you get the idea

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Hmm... sounds a lot like a plain old Map<K, Collection<V>>? But wait...

Page 69: Google Guava & EMF @ GTUG Nantes

Multimap, before

public Sale getBiggestSale() { Sale biggestSale = null; for (List<Sale> sales : map.values()) { Sale myBiggestSale = Collections.max(

sales, SALE_CHARGE_COMPARATOR);

if (biggestSale == null || myBiggestSale.getCharge() > biggestSale().getCharge()) { biggestSale = myBiggestSale; } } return biggestSale;}

Now we want to find the biggest Sale.

Without Multimap:

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 70: Google Guava & EMF @ GTUG Nantes

Multimap, after

Multimap has six: ‣get(), ‣keys(), ‣keySet(), ‣values(), ‣entries(), ‣asMap().

public Sale getBiggestSale() { return Collections.max(multimap.values(), SALE_CHARGE_COMPARATOR);}

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

View collections are very powerful.

Page 71: Google Guava & EMF @ GTUG Nantes

Multimap APIMost Map methods are identical on Multimap:‣ size(), ‣ isEmpty(),‣ containsKey(), ‣ containsValue(),‣ put(), ‣ putAll(),‣ clear(),‣ values()

The others have analogues:‣ get() returns Collection<V> instead of V ‣ remove(K) becomes remove(K,V) and removeAll(K) ‣ keySet() becomes keys() (well, and keySet()) ‣ entrySet() becomes entries()

And Multimap has a few new things:‣ containsEntry(), ‣ replaceValues()

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 72: Google Guava & EMF @ GTUG Nantes

Multimap implementations

ImmutableMultimapImmutableListMultimapImmutableSetMultimap

ArrayListMultimapHashMultimap

LinkedHashMultimapLinkedListMultimap

TreeMultimap

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

ListMultimapSetMultimap

SortedSetMultimap

+1

Page 73: Google Guava & EMF @ GTUG Nantes

BiMap

aka unique-valued mapvalues are unique, as well as its keys

Has an inverse() view, which is another BiMapbimap.inverse().inverse() == bimap

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Stop creating two separate

forward and backward Maps!

+1

Page 74: Google Guava & EMF @ GTUG Nantes

BiMap Implementations

ImmutableBiMap HashBiMap EnumBiMapEnumHashBiMap

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 75: Google Guava & EMF @ GTUG Nantes

Constrained Collections/Maps

//...public Object checkElement(Object element) { if (element == null) { throw new NullPointerException(); } return element;}//...

public interface Constraint<E> { E checkElement(E element);}

Constraints.notNull()

Page 76: Google Guava & EMF @ GTUG Nantes

Constrained Collections/Maps

constrainedCollection(Collection<E>, Constraint<? super E>)

constrainedList(List<E>, Constraint<? super E>)

constrainedMultiset(Multiset<E>, Constraint<? super E>)

constrainedSet(Set<E>, Constraint<? super E>)

constrainedSortedSet(SortedSet<E>, Constraint<? super E>)

Constraints.

Page 77: Google Guava & EMF @ GTUG Nantes

MapMaker

A ConcurrentMap builder, providing any combination of these features:‣Soft or weak keys‣Soft or weak values‣Timed expiration‣On-demand computation of values

Far more powerful, easy to use than WeakHashMap

Concurrent on-demand computation is really hard

+1

Page 78: Google Guava & EMF @ GTUG Nantes

MapMaker

ConcurrentMap<User, Graph> recommendations = new MapMaker()

.concurrencyLevel(4) .softKeys()

.weakValues()

.maximumSize(10000) .expireAfterWrite(10, TimeUnit.MINUTES) .makeComputingMap( new Function<User, Graph>() { public Graph apply(User user) { return createExpensiveGraph(user); } });

Page 79: Google Guava & EMF @ GTUG Nantes

Forwarding Object/Collections

Abstract implementations of existing types delegating all method calls to its delegate()

protected abstract Object delegate();

Decorator pattern without the burden ;)

Page 80: Google Guava & EMF @ GTUG Nantes

Forwarding Collections

ForwardingCollection ForwardingConcurrentMap

ForwardingIterator ForwardingList

ForwardingListIterator ForwardingListMultimap

ForwardingMap ForwardingMapEntry ForwardingMultimap

ForwardingMultiset ForwardingObject ForwardingQueue

ForwardingSet ForwardingSetMultimap ForwardingSortedMap ForwardingSortedSet

ForwardingSortedSetMultimapForwardingTable

Page 81: Google Guava & EMF @ GTUG Nantes

Static utilitiesIn classes with name ending with an s

‣ Lists‣ Maps‣ Multimaps‣ Multisets‣ Sets‣ SortedMaps‣ Tables‣ Iterators‣ Iterables‣ Collections2

Page 82: Google Guava & EMF @ GTUG Nantes

Static factories methods

Map<String, Class<? extends Handler>> m = new HashMap<String, Class<? extends Handler>>();

Map<String, Class<? extends Handler>> m2 = Maps.newHashMap();

Guava provides these for JDK collections and for Guava collections (Multi*...)

With overloads to accept Iterables to copy elements from

Rather than typing

you type

+1

Page 83: Google Guava & EMF @ GTUG Nantes

Maps as index

Maps.uniqueIndex()

Map<Integer, Employee> m = Maps.uniqueIndex(values, new Function<Employee, Integer>() { @Override public Integer apply(Employee input) { return input.getId(); }});

+1

Page 84: Google Guava & EMF @ GTUG Nantes

Multimaps as index +1

Multimaps.index()

Multimap<Integer, Employee> m = Multimaps.index(values, new Function<Employee, Integer>() { @Override public Integer apply(Employee input) { return input.getYearsOfService(); }});

Page 85: Google Guava & EMF @ GTUG Nantes

Map differences

So you want to compute the differences between two maps

Maps.difference( Map<? extends K,? extends V>, Map<? extends K,? extends V>)

+1

Guava has it too

Difference is an immutable snapshot of the state of the maps at the time this method is called

Page 86: Google Guava & EMF @ GTUG Nantes

MapDifference API

Map<K,MapDifference.ValueDifference<V>> entriesDiffering()

Map<K,V> entriesInCommon() Map<K,V> entriesOnlyOnLeft() Map<K,V> entriesOnlyOnRight()

ValueDifference API

V leftValue() V rightValue()

Page 87: Google Guava & EMF @ GTUG Nantes

Sets union/intersection/difference

difference(Set<E>, Set<?>)

symmetricDifference(Set<? extends E>, Set<? extends E>)

union(Set<? extends E>, Set<? extends E>)

intersection(Set<E>, Set<?>)

Returns Sets.SetView<E>

+1

Page 88: Google Guava & EMF @ GTUG Nantes

Sets combinations

Set<Set<E>> powerSet(Set<E>)

Set<List<B>> cartesianProduct( List<? extends Set<? extends B>>)

while the power set of a set with size n is of size 2^n, its memory usage is only O(n)

while the cartesian product of sets of size m, n, p is a set of size m x n x p, its actual memory consumption is much smaller (m + n + p)

Page 89: Google Guava & EMF @ GTUG Nantes

Immutable collections

JDK has Collections.unmodifiableFoo wrappers

‣Unmodifiable - you can't change it

‣Immutable - it can never change, no matter what

‣Immutability is tasty!‣See Effective Java Item 15 for some of the many reasons

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 90: Google Guava & EMF @ GTUG Nantes

Immutable collections

ImmutableListImmutableSetImmutableMap

ImmutableSortedMapImmutableSortedSetImmutableMultisetImmutableMultimap

ImmutableListMultimapImmutableSetMultimap

ImmutableBiMap

+1

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 91: Google Guava & EMF @ GTUG Nantes

Immutable collections

JDK wrappers still useful for unmodifiable views of changing data. But for most purposes, use Guava’s:

‣Brand-new, standalone implementations‣Immutability guaranteed!‣Very easy to use‣See following slides

‣Slightly faster‣Null hostile‣Use less memory‣Sometimes far less (ImmutableSet, factor of 2-3x)

http://google-collections.googlecode.com/files/google-collections-svgtug-2008-08-06.pdf

Page 92: Google Guava & EMF @ GTUG Nantes

Immutable collectionsFactory methods

ImmutableXXX.of()ImmutableXXX.of(E)ImmutableXXX.of(E, E)ImmutableXXX.of(E, E, E, E...)

ImmutableXXX.copyOf(Iterable)ImmutableXXX.copyOf(Iterator)

ImmutableMap.of(1, "one", 2, "two")ImmutableMap.copyOf(Map)

small maps only (up to 5 key/value pairs)

singletons

immutable empty XXX

Builder pattern otherwise

Page 93: Google Guava & EMF @ GTUG Nantes

Constants Sets

public static final Set<Integer> LUCKY_NUMBERS; static { Set<Integer> set = new LinkedHashSet<Integer>(); set.add(4); set.add(8); set.add(15); set.add(16); set.add(23); set.add(42); LUCKY_NUMBERS = Collections.unmodifiableSet(set); }

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 94: Google Guava & EMF @ GTUG Nantes

Constants Sets

public static final Set<Integer> LUCKY_NUMBERS = Collections .unmodifiableSet( new LinkedHashSet<Integer>( Arrays.asList(4, 8, 15, 16, 23, 42)));

A little nicer. But uses four different classes! Something's weird.

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 95: Google Guava & EMF @ GTUG Nantes

Constants Sets

public static final ImmutableSet<Integer> LUCKY_NUMBERS = ImmutableSet.of(4, 8, 15, 16, 23, 42);

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Now we just say exactly what we mean. And get performance benefits as well!

We're using just one class (it implements Set)

of() method name inspired by java.util.EnumSet

Page 96: Google Guava & EMF @ GTUG Nantes

Constants Maps

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

public static final Map<String, Integer> ENGLISH_TO_INT;static { Map<String, Integer> map = new LinkedHashMap<String, Integer>(); map.put("four", 4); map.put("eight", 8); map.put("fifteen", 15); map.put("sixteen", 16); map.put("twenty-three", 23); map.put("forty-two", 42); ENGLISH_TO_INT = Collections.unmodifiableMap(map);}

Page 97: Google Guava & EMF @ GTUG Nantes

Constants Maps

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

public static final ImmutableMap<String, Integer> ENGLISH_TO_INT = ImmutableMap.<String,Integer>builder() .put("four", 4) .put("eight", 8) .put("fifteen", 15) .put("sixteen", 16) .put("twenty-three", 23) .put("forty-two", 42) .build();

Empowering the Builder Pattern!

Page 98: Google Guava & EMF @ GTUG Nantes

TableCollection with columns and rows

No more Map<T1, Map<T2,T3>>

@Beta since r07

Table<R,C,V> composed of Table.Cell<R,C,V>

6 viewsSet<Table.Cell<R,C,V>> cellSet()

Map<R,V> column(C)Set<C> columnKeySet()

Map<C,Map<R,V>> columnMap()Map<C,V> row(R)

Set<R> rowKeySet()Map<R,Map<C,V>> rowMap()

Tables.transpose() (flips row and column keys)

2 impl.

HashBasedTableTreeBasedTable

Page 99: Google Guava & EMF @ GTUG Nantes

Functionnalflavor

6

http://www.flickr.com/photos/leamarzloff/3085027173/

Page 100: Google Guava & EMF @ GTUG Nantes

in com.google.common.base package

Function<F, T> to transform a collection

Predicate<T> to filter out a collection

public interface Function<F, T> {

T apply(F from);}

public interface Predicate<T> {boolean apply(T from);

}

Page 101: Google Guava & EMF @ GTUG Nantes

in com.google.common.collect package

Iterables.filter()

Iterators.filter()

Collections2.filter()

Sets.filter()

http://www.flickr.com/photos/luis_is_rubbish_at_photography/5464233571/

Page 102: Google Guava & EMF @ GTUG Nantes

4224 128

4224 7 12813

public static void demo(Collection<Integer> c) { Predicate<Integer> isEven = new Predicate<Integer>() { @Override public boolean apply(Integer input) { return (input.intValue() % 2 == 0); } }; Collection<Integer> fCol =

Collections2.filter(c, isEven); }

Page 103: Google Guava & EMF @ GTUG Nantes

in com.google.common.collect package

Iterables.transform()

Iterators.transform()

Collections2.transform()

Lists.transform()

http://www.flickr.com/photos/brotherxii/2203037632/

Page 104: Google Guava & EMF @ GTUG Nantes

ORANGEAPPLE KIWI PEARBANANA

OrangeApple Kiwi PearBanana

public void demo(Collection<String> c) { Function<String, String> toUpperCase = new Function<String, String>() { @Override public String apply(String input) { return input.toUpperCase(); } }; Collection<String> tCol = Collections2.transform(c, toUpperCase); }

Page 105: Google Guava & EMF @ GTUG Nantes

Beware of

lazynesshttp://www.flickr.com/photos/torek/2467519466/

Page 106: Google Guava & EMF @ GTUG Nantes

Copy!

Lists.newArrayList() Lists.newLinkedList() Sets.newHashSet() Sets.newLinkedHashSet() Sets.newTreeSet()

ImmutableList.copyOf() ImmutableSet.copyOf()

or make it immutable...

http://www.flickr.com/photos/visionnewspaper/314107094/

Page 107: Google Guava & EMF @ GTUG Nantes

Predicates

Functions

composeforPredicate

andornotcompose

Compose and combine http://www.flickr.com/photos/jgscism/5484243543/

Page 108: Google Guava & EMF @ GTUG Nantes

Compose and combine

Function<String, String> toUpper = new Function<String, String>() { @Override public String apply(String input) { return input.toUpperCase(); }};

Function<Integer, String> toHexString = new Function<Integer, String>() { @Override public String apply(Integer input) { return Integer.toHexString(input.intValue()); }};

Function<Integer, String> toUpperHexString = Functions.compose(toUpper, toHexString);

Page 109: Google Guava & EMF @ GTUG Nantes

Compose and combine

Predicate<String> isEmpty = new Predicate<String>() { @Override public boolean apply(String input) { return input.length() == 0; // isEmpty() is Java6 only }};

Predicate<Object> isNull = new Predicate<Object>() { @Override public boolean apply(Object input) { return input == null; }};

Predicate<String> nullOfEmpty = Predicates.or(isNull, isEmpty);

Page 110: Google Guava & EMF @ GTUG Nantes

Maps transform & filter

Maps.filterEntries()

Maps.filterKeys()

Maps.filterValues()

Maps.transformEntries()

Maps.transformValues()

Equivalence for Multimaps

Page 111: Google Guava & EMF @ GTUG Nantes

Primitives

7

Page 112: Google Guava & EMF @ GTUG Nantes

package that helps you work with the primitive types

common.primitives

int, long, double, float, char, byte, short, and boolean

If you need help doing a primitive task:

1. check the wrapper class (e.g. java.lang.Integer)2. check java.util.Arrays3. check com.google.common.primitives4. it might not exist!

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 113: Google Guava & EMF @ GTUG Nantes

Guava doesn't do primitive-based collections; try fastutil, or trove4j, or...

common.primitives

Booleans, Bytes, Chars, Doubles, Floats, Ints, Longs and (wait for it) Shorts

Contains the classes

Each has the exact same structure (but has only the subset of operations that make sense for its type).

Many of the byte-related methods have alternate versions in the classes

SignedBytes and UnsignedBytes. (Bytes are peculiar...)

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 114: Google Guava & EMF @ GTUG Nantes

Method Longs Ints Shorts Chars Doubles Bytes S.Bytes U.Bytes Booleans

hashCode x x x x x x x

compare x x x x x x x x

checkedCast x x x x x

saturadCast x x x x x

contains x x x x x x

indexOf x x x x x x x

lastIndexOf x x x x x x x

min x x x x x x

max x x x x x x

concat x x x x x x x

join x x x x x x x

toArray x x x x x x x

asList x x x x x x x

lexComparator x x x x x x x

toByteArray x x x x

fromByteArray x x x x

The big table

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 115: Google Guava & EMF @ GTUG Nantes

IO & Network

8

http://www.flickr.com/photos/buzzingbye/222969493/

Page 116: Google Guava & EMF @ GTUG Nantes

common.iopublic interface InputSupplier<T> { T getInput() throws IOException;} public interface OutputSupplier<T> { T getOutput() throws IOException;}

2 key interfaces

Typically: InputSupplier<InputStream>, OutputSupplier<Writer>, etc.

‣ byte stream means "InputStream or OutputStream"ByteStreams utilities class

‣ char stream means "Reader or Writer."CharStreams utilities class

Terminology

This lets all Guava’s utilities be useful for many kinds of I/O.

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Page 117: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

‣byte[] toByteArray(InputStream) ‣byte[] toByteArray(InputSupplier) ‣void readFully(InputStream, byte[]) ‣void write(byte[], OutputSupplier) ‣long copy(InputStream, OutputStream) ‣long copy(InputSupplier, OutputSupplier) ‣long length(InputSupplier)‣boolean equal(InputSupplier, InputSupplier) ‣InputSupplier slice(InputSupplier, long, long) ‣InputSupplier join(InputSupplier...)

ByteStreams

CharStreams is similar, but deals in Reader, Writer, String and CharSequence (often requiring you to specify a Charset).

Page 118: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Files The Files class works one level higher than ByteStreams and CharStreams

byte[] toByteArray(File) void write(byte[], File) void write(CharSequence, File, Charset) long copy(File, File) long copy(InputSupplier, File) long copy(File, OutputSupplier) long copy(File, Charset, Appendable) long move(File, File) boolean equal(File, File)

Page 119: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

More about Files

File createTempDir() void deleteDirectoryContents(File) void deleteRecursively(File) long getChecksum(File, Checksum) byte[] getDigest(File, MessageDigest) String readFirstLine(File, Charset) List<String> readLines(File, Charset) T readLines(File, Charset, LineProcessor<T>) String toString(File, Charset)

Page 120: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

Flushables and Closeables

Closeables.closeQuietly(Closeable closeable)Closeables.close(

Closeable closeable, boolean swallowIOException) throws IOException

Flushables.flushQuietly(Flushable flushable)Flushables.flush(

Flushable flushable, boolean swallowIOException) throws IOException

Very usefull in finally blocks (avoid nesting try/catch)

Page 121: Google Guava & EMF @ GTUG Nantes

HostSpecifiersyntactically valid host specifier, suitable for use in a URI

InternetDomainName~RFC 1035, i18n DN

InetAddressesutility pertaining to Inet(4|6)Address instances

http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf

common.net

Work with literals of:‣URI‣URL‣@IP (v4/v6)

Never cause DNS services to be accessed

(JDK does...)

Page 122: Google Guava & EMF @ GTUG Nantes

Concurrency

9http://www.flickr.com/photos/kh-67/3339157498/

Page 123: Google Guava & EMF @ GTUG Nantes

Immutable* ConcurrentHashMultiset

Multimaps.synchronizedMultimap MapMaker

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Concurrency in Guava

Page 124: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

common.util.concurrent

It’s all about Future (as in java.util.concurrent)(never heard of it, go take a nap)

"A handle to an in-progress computation."

"A promise from a service to supply us with a result."

Page 125: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Future

public interface Future<V> { //... V get(); //... }

JDK Future

Guava ListenableFuture

public interface ListenableFuture<V> extends Future<V> { void addListener(Runnable r, Executor e); }

Page 126: Google Guava & EMF @ GTUG Nantes

Future with one new method: addListener

When the future is done (success, exception, cancellation), the listeners run

the killer app: "To serve as a foundation for higher-level abstractions"

See Futures

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

ListenableFuture

Page 127: Google Guava & EMF @ GTUG Nantes

When to use? Always.

(+) Most Futures methods require it. (+) It's easier than changing to ListenableFuture later. (+) Providers of utility methods won't need to provide Future and ListenableFuture variants of their methods.

(−) "ListenableFuture" is lengthier than "Future." (−) Classes like ExecutorService give you a plain Future by default.

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

ListenableFuture

Page 128: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Transform and chain

Function<QueryResult, List<Row>> rowsFunction = new Function<QueryResult, List<Row>>() { public List<Row> apply(QueryResult queryResult) { return queryResult.getRows(); }};

Future<QueryResult> queryFuture = ...; Future<List<Row>> rowsFuture = transform(queryFuture, rowsFunction);

Page 129: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Transform and chain

Function<RowKey, ListenableFuture<QueryResult>> queryFunction = new Function<RowKey, ListenableFuture<QueryResult>>() { public ListenableFuture<QueryResult> apply(RowKey rowKey) { return dataService.read(rowKey); }};

ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);ListenableFuture<QueryResult> queryFuture = chain(rowKeyFuture, queryFunction);

Page 130: Google Guava & EMF @ GTUG Nantes

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Futures

Got a Iterable<Future<V>>?

Decide what you want:

Future of List<V> List of Future<V>

Futures.allAsList()Futures.successfulAsList()

Page 131: Google Guava & EMF @ GTUG Nantes

MoreExecutors.sameThreadExecutorfor quick tasks that can run inline

MoreExecutors.getExitingExecutorServicefor "half-daemon" threads

UncaughtExceptionHandlers.systemExitfor exiting after unexpected errors

ThreadFactoryBuildernew ThreadFactoryBuilder()

.setDaemon(true)

.setNameFormat("WebRequestHandler-%d")

.build();

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Executors

Page 132: Google Guava & EMF @ GTUG Nantes

"An object with an operational state, plus asynchronous start() and stop() lifecycle methods

to transfer into and out of this state."

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Services

Example: web servers, RPC servers, monitoring initialization, ...

Page 133: Google Guava & EMF @ GTUG Nantes

AbstractExecutionThreadService One thread automatically created for you at startup

AbstractIdleService Thread only needed for startup and shutdown (e.g., service that already has its own thread)

AbstractServiceFull control over threads creation

http://guava-libraries.googlecode.com/files/guava-concurrent-slides.pdf

Services

Page 134: Google Guava & EMF @ GTUG Nantes

EMF for dummies

10http://www.flickr.com/photos/bendylan/259110679/

Page 135: Google Guava & EMF @ GTUG Nantes

"Class diagram to Super Java Bean"

Java Framework and code generation facility

(My definition)

Page 136: Google Guava & EMF @ GTUG Nantes

About those modeling things

‣It’s just about defining the entities/concepts/classes you will manipulate

‣You can define concepts in several ways‣Annotated Java classes‣XML Schema‣Ecore file‣UML Class diagram

‣You give the input to EMF, and it handles conversion and generation of the ULTIMATE POJO API

Page 137: Google Guava & EMF @ GTUG Nantes

About those modeling things

‣Thin framework layer inserted into your POJO‣you can even hide it ;)

‣The layer is as thin as imaginable and provides high power-to-weight ratio‣opposite references‣adapters‣edit‣lazy loading‣serialization (REST)‣factory‣reflective calls / metadata generation

Page 138: Google Guava & EMF @ GTUG Nantes

About those modeling things

What can you define in Ecore files?

‣Package‣Classes‣Attributes‣References

Page 139: Google Guava & EMF @ GTUG Nantes

About those modeling things

‣PackagesLogical organization

‣ClassesClassical OO concepts

‣AttributesPrimitive type fields (with cardinality)

‣ReferencesClass type fields (with cardinality), opposite, containment

Page 140: Google Guava & EMF @ GTUG Nantes

EObject?

The thin layer that changes it all

Object eGet(EStructuralFeature feature);void eSet(EStructuralFeature feature, Object newValue);boolean eIsSet(EStructuralFeature feature);void eUnset(EStructuralFeature feature);

EList<EObject> eContents();TreeIterator<EObject> eAllContents();EObject eContainer();

Page 142: Google Guava & EMF @ GTUG Nantes

EMFPath

11http://www.flickr.com/photos/eseartista/1604034788/

Page 143: Google Guava & EMF @ GTUG Nantes

Path

Page 144: Google Guava & EMF @ GTUG Nantes

Set of functions and predicates for EMF objects

Code generators for your own Ecore models

and few other utility classes

public interface Function<F, T> {

T apply(F from);

}public interface Predicate<T> {

boolean apply(T from);}

Page 145: Google Guava & EMF @ GTUG Nantes

‣ parent (eContainer)

‣ ancestor‣ ancestorOrSelf‣ child (eContents)

‣ descendant (eAllContents)

‣ descendantOrSelf‣ following‣ followingSibling‣ preceding‣ precedingSibling

Lazy EObjects containment tree walking

EObject myObject;Collection<EObject> fs = followingSibling.of(myObject);

http

://w

ww

.flic

kr.c

om/p

hoto

s/m

usic

love

natu

re/1

4459

7827

2/

Page 146: Google Guava & EMF @ GTUG Nantes

HavingIsKind/IsTypeIsAncestor/IsChild

Common predicates

public static Collection<EObject> demoHaving(Collection<EObject> c) {

return Collections2.filter(c, Having.feature(EcorePackage.Literals.ENAMED_ELEMENT__NAME,

StringPredicates.firstUpperCase) ); }

Page 147: Google Guava & EMF @ GTUG Nantes

non-EMF functions & predicates

length : Function<String, Integer>toL1Case : Function<String, String>toLowerCase : Function<String, String>toU1Case : Function<String, String>toUpperCase : Function<String, String>trim : Function<String, String>replaceAll(Pattern, String)replaceAll(String, String)replaceFirst(Pattern, String)replaceFirst(String, String)substring(int)substring(int, int)

Strings

Predicates to test ordering:equalless thangreater thanless or equalgreater or equal

Comparable

Page 148: Google Guava & EMF @ GTUG Nantes

Ecore API has been Guava-ified

‣ EObject.eResource() is wrapped as a Function in EObjectPath.eResource

‣ EObject.eIsProxy() is wrapped as a Predicate in EObjectPath.eIsProxy

‣ EClass.getESuperTypes() is wrapped as a Function in EClass.eSuperTypes

‣ EReference.isContainment() is wrapped as a Predicate in ERefrencePath.isContainment

Page 149: Google Guava & EMF @ GTUG Nantes

Ecore has been Guava-ified through a generator

that is available for your own Ecore model

+

Page 151: Google Guava & EMF @ GTUG Nantes

Recap

12http://www.flickr.com/photos/loty/326761635/

Page 152: Google Guava & EMF @ GTUG Nantes

1. Functionnal flavor of collection handling2. CharMatcher / Splitter / Joiner3. Immutable Collections4. Multimap / Multiset / Bimap5. MapMaker6. EMF is generating plain old POJO

What you should remember

about this presentation

Page 153: Google Guava & EMF @ GTUG Nantes

1. Guava is cool, powerful and the definitive extension to JDK! 2. Never write your own POJO by hand for now, use EMF!3. Always generate EMFPath classes to handle EMF objects!

What you should REALLY remember

about this presentation

http://code.google.com/p/guava-libraries/http://code.google.com/p/guava-osgi/

http://eclipse.org/modeling/emf/http://code.google.com/a/eclipselabs.org/p/emfpath/