SlideShare a Scribd company logo
1 of 108
Hamlet D'Arcy – Canoo Engineering AG @HamletDRC http://hamletdarcy.blogspot.com Java Boilerplate Busters
Agenda ,[object Object]
Builders / Fluent APIs
Function Objects /  Proxies / Interceptors
Java 7
Lombok / Groovy
About Me
Boilerplate – noun Code you shouldn't be writing yourself
Agenda ,[object Object]
Builders / Fluent APIs
Function Objects /  Proxies / Interceptors
Java 7
Lombok / Groovy
import static  org.apache.commons.lang.StringUtils.*;
import static  org.apache.commons.lang.StringUtils.*; assert   isAlpha ( "abcde" ); assert   isNumeric ( "12345" ); assert   isAlphanumeric ( "12345abc" );
import static  org.apache.commons.lang.StringUtils.*; assert   isBlank ( "" ); assert   isBlank ( null );
import static  org.apache.commons.lang.StringUtils.*; assert   isAllLowerCase ( "abcdef" ); assert   isAllUpperCase ( "ABCDEF" );
import static  org.apache.commons.lang.StringUtils.*; assert   "abc"  ==  defaultString ( "abc" ); assert   ""  ==  defaultString ( "" ); assert   ""  ==  defaultString ( null );
import static  org.apache.commons.lang.StringUtils.*; assert   "abc" .equals( left ( "abcdef" ,  3 )); assert   "def" .equals( right ( "abcdef" ,  3 )); assert   null  ==  right ( null ,  3 );
import static  org.apache.commons.lang.StringUtils.*; Object[] array =  new  Object[]{ 1 ,  2 ,  3 }; assert   "1, 2, 3" .equals( join (array,  ", " )); List list = Arrays. asList ( 1 ,  2 ,  3 ); assert   "1, 2, 3" .equals( join (list,  ", " ));
import  org.apache.commons.lang.StringEscapeUtils;
import  org.apache.commons.lang.StringEscapeUtils; String xmlText =  " amp;quot; Hello amp;quot;   &  amp;quot; GoodBye amp;quot; " ; String escapedXml =  ""Hello" & " +  ""GoodBye"" ; assert  escapedXml.equals( StringEscapeUtils. escapeXml (xmlText) ); assert  xmlText.equals( StringEscapeUtils. unescapeXml (escapedXml) );
import  org.apache.commons.lang.StringEscapeUtils; String htmlText =  &quot;<body>text</body>&quot; ; String escapedHtml =  &quot;&lt;body&gt;&quot;  + &quot;text&lt;/body&gt;&quot; ; assert  escapedHtml.equals( StringEscapeUtils. escapeHtml (htmlText) ); assert  htmlText.equals( StringEscapeUtils. unescapeHtml (escapedHtml) );
import  org.apache.commons.lang.StringEscapeUtils; String csvText =  &quot;red, beans, and rice&quot; ; String escapedCsv =  &quot; amp;quot; red, beans, and rice amp;quot; &quot; ; assert  escapedCsv.equals( StringEscapeUtils. escapeCsv (csvText) ); assert  csvText.equals( StringEscapeUtils. unescapeCsv (escapedCsv) );
import static  org.apache.commons.lang.ArrayUtils.*;
import static  org.apache.commons.lang.ArrayUtils.*; int [] evens =  new   int []{ 2 ,  4 ,  6 }; int [] odds =  new   int []{ 1 ,  3 ,  5 }; assert   contains (evens,  2 ); assert   contains (odds,  3 );
import static  org.apache.commons.lang.ArrayUtils.*; int [] evens =  new   int []{ 2 ,  4 ,  6 }; int [] odds =  new   int []{ 1 ,  3 ,  5 }; assert  Arrays. equals (   new   int []{ 2 ,  4 ,  6 ,  8 },    add (evens,  8 ) ); assert  Arrays. equals ( new   int []{ 2 ,  4 ,  6 ,  1 ,  3 ,  5 },  addAll (evens, odds) );
import static  org.apache.commons.lang.ArrayUtils.*; int [] evens =  new   int []{ 2 ,  4 ,  6 }; int [] odds =  new   int []{ 1 ,  3 ,  5 }; assert  Arrays. equals (   new   int []{ 2 ,  6 },    remove (evens,  1 ) ); assert  Arrays. equals (   new   int []{ 1 ,  3 },    remove (odds,  2 ) );
import static  org.apache.commons.lang.BooleanUtils.*;
import static  org.apache.commons.lang.BooleanUtils.*; assert   toBoolean ( &quot;true&quot; ); assert   toBoolean ( &quot;TRUE&quot; ); assert   toBoolean ( &quot;tRUe&quot; ); assert   toBoolean ( &quot;on&quot; ); assert   toBoolean ( &quot;ON&quot; ); assert   toBoolean ( &quot;yes&quot; ); assert   toBoolean ( &quot;YES&quot; );
import  org.apache.commons.lang.builder.ToStringBuilder;
import  org.apache.commons.lang.builder.ToStringBuilder; public   class  Person { String  name ; Date  timestamp  =  new  Date(); @Override public  String toString() { return   new  ToStringBuilder( this ) .append( &quot;name&quot; ,  name ) .append( &quot;timestamp&quot; ,  timestamp ) .toString(); } }
import  org.apache.commons.lang.builder.EqualsBuilder;
import  org.apache.commons.lang.builder.EqualsBuilder; public   class  Person { String  name ; Date  timestamp  =  new  Date(); @Override public   boolean  equals(Object obj) { if  (obj ==  null ) {  return   false ; } if  (obj ==  this ) {  return   true ; } if  (obj.getClass() != getClass()) {  return   false ; } Person rhs = (Person) obj; return   new  EqualsBuilder() .append( name , rhs. name ) .append( timestamp , rhs. timestamp ) .isEquals(); } }
import  org.apache.commons.lang.builder.HashCodeBuilder;
import  org.apache.commons.lang.builder.HashCodeBuilder; public   class  Person { String  name ; Date  timestamp  =  new  Date(); @Override public   int  hashCode() { return   new  HashCodeBuilder() .append( name ) .append( timestamp ) .toHashCode(); } }
import  org.apache.commons.lang.builder. CompareToBuilder ;
import  org.apache.commons.lang.builder. CompareToBuilder ; public   class  Person  implements  Comparable<Person> { String  name ; Date  timestamp  =  new  Date(); public   int  compareTo(Person other) { return   new  CompareToBuilder() .append( this . name , other. name ) .toComparison(); } }
Apache Commons Lang ,[object Object]
No Generics
Many functions obsoleted by JDK 5 ,[object Object],[object Object]
Not backwards compatible with 2.6
new  HashMap<T, Set<U>>
import  com.google.common.collect.Multimap;
import  com.google.common.collect.Multimap; Multimap<String, String> multiMap =  HashMultimap. create (); multiMap.put( &quot;Canoo&quot; ,  &quot;Hamlet&quot; ); multiMap.put( &quot;Canoo&quot; ,  &quot;Dierk&quot; ); multiMap.put( &quot;Canoo&quot; ,  &quot;Andres&quot; ); multiMap.put( &quot;EngineYard&quot; ,  &quot;Charles&quot; ); multiMap.put( &quot;EngineYard&quot; ,  &quot;Thomas&quot; ); multiMap.put( &quot;EngineYard&quot; ,  &quot;Nick&quot; );
import  com.google.common.collect.Multimap; assert  multiMap.containsKey( &quot;Canoo&quot; ); assert  multiMap.containsKey( &quot;EngineYard&quot; ); assert  multiMap.containsValue( &quot;Hamlet&quot; ); assert  multiMap.containsValue( &quot;Charles&quot; );
import  com.google.common.collect.Multimap; Collection<String> canooies = multiMap.get( &quot;Canoo&quot; ); Collection<String> c = Lists. newArrayList ( &quot;Dierk&quot; , &quot;Andres&quot; ,  &quot;Hamlet&quot; ); assert  canooies.containsAll(c);
import  com.google.common.collect.BiMap;
import  com.google.common.collect.BiMap; BiMap<String, String> biMap = HashBiMap. create (); biMap.put( &quot;Switzerland&quot; ,  &quot;die Schweiz&quot; ); biMap.put( &quot;Poland&quot; ,  &quot;Polska&quot; ); biMap.put( &quot;Austria&quot; ,  &quot;Österreich&quot; ); assert   &quot;Polska&quot;  == biMap.get( &quot;Poland&quot; ); assert   &quot;Switzerland&quot;  == biMap.inverse() .get( &quot;die Schweiz&quot; );
new  HashMap<T, Map<U, V>>
import  com.google.common.collect.Table;
import  com.google.common.collect.Table; Table<Integer, Integer, String> table =  HashBasedTable. create (); table.put( 1 ,  1 ,  &quot;Hamlet&quot; ); table.put( 1 ,  2 ,  &quot;Dierk&quot; ); table.put( 2 ,  1 ,  &quot;Andres&quot; ); table.put( 2 ,  2 ,  &quot;Matthius&quot; );
import  com.google.common.collect.Table; assert  table.contains( 1 ,  1 ); assert  table.containsRow( 1 ); assert  table.containsColumn( 2 ); assert  !table.contains( 3 ,  1 ); assert  !table.containsRow( 3 ); assert  !table.containsColumn( 3 ); assert   &quot;Hamlet&quot;  == table.get( 1 ,  1 ); assert  table.containsValue( &quot;Hamlet&quot; );
import  com.google.common.base.Joiner;
import  com.google.common.base.Joiner; Set<Integer> set = Sets. newHashSet ( 1 ,  2 ,  3 ); assert   &quot;1, 2, 3&quot; .equals(Joiner. on ( &quot;, &quot; ).join(set));
import  com.google.common.base.Splitter;
import  com.google.common.base.Splitter; String string =  &quot;1, 2, , 3&quot; ; Iterable<String> i = Splitter. on ( &quot;,&quot; ) .omitEmptyStrings() .trimResults() .split(string);
import static  com.google.common.collect.Iterables.*; import static  com.google.common.collect.Lists.*; Iterable<Integer> setAsInts =  transform (i, new  Function<String, Integer>() { @Override public  Integer apply(String input) { return  Integer. valueOf (input); } }); assert   newArrayList ( 1 ,  2 ,  3 ) .containsAll( newArrayList (setAsInts));
import static  com.google.common.base.Strings.*;
import static  com.google.common.base.Strings.*; assert   emptyToNull ( &quot;&quot; ) ==  null ; assert   &quot;&quot; .equals( nullToEmpty ( null )); assert   isNullOrEmpty ( &quot;&quot; ); assert   &quot;abcabcabc&quot; .equals( repeat ( &quot;abc&quot; ,  3 ));
import static  com.google.common.base.Preconditions.*;
import static  com.google.common.base.Preconditions.*; int  userID =  1 ; String userName =  &quot;some name&quot; ; checkArgument (userID >  0 ,  &quot;userid is negative: %s&quot; , userID); checkNotNull (userName,  &quot;user %s missing name&quot; , userID); checkState (userName.length() >  0 ,  &quot;user %s missing name&quot; , userID);
import static  com.google.common.base.Objects.*;
import static  com.google.common.base.Objects.*; class  Person { String  name ; Date  timestamp  =  new  Date(); @Override public  String toString() { return   toStringHelper ( this ) .add( &quot;name&quot; ,  name ) .add( &quot;timestamp&quot; ,  timestamp ).toString(); } }
import static  com.google.common.base.Equivalences.*;
import static  com.google.common.base.Equivalences.*; class  Person  implements  Comparable<Person> { String  name ; Date  timestamp  =  new  Date(); @Override public   boolean  equals(Object obj) { if  (obj ==  null ) {  return   false ; } if  (obj ==  this ) {  return   true ; } if  (obj.getClass() != getClass()) { return   false ; } Person rhs = (Person) obj; return   equals ().equivalent( name , rhs. name ) && equals ().equivalent( timestamp , rhs. timestamp ); } @Override public   int  hashCode() { return   hashCode ( name ,  timestamp ); } }
import static  com.google.common.collect.ComparisonChain.*;
import static  com.google.common.collect.ComparisonChain.*; class  Person  implements  Comparable<Person> { String  name ; Date  timestamp  =  new  Date(); public   int  compareTo(Person other) { return   start () .compare( name , other. name ) .compare( timestamp , other. timestamp ) .result(); } }
import  com.google.common.base.Throwables;
import  com.google.common.base.Throwables; Exception ex =  new  Exception(); Throwables. propagateIfPossible (ex); Throwables. propagate (ex); // throws Exception Throwables. throwCause (ex,  false );
import  com.google.common.base.Function;
import  com.google.common.base.Function; Person alice =  new  Person( &quot;Alice&quot; ); Person bob =  new  Person( &quot;Bob&quot; ); Person carol =  new  Person( &quot;Carol&quot; ); List<Person> people =  newArrayList (alice, bob, carol);
import  com.google.common.base.Function; Function<Person, String> getName =  new  Function<Person, String>() { public  String apply(Person p) { return  p.getName(); } }; assert   &quot;Alice&quot;  == getName.apply(alice); Collection<String> names = Collections2 . transform (people, getName); assert  names.containsAll( newArrayList ( &quot;Alice&quot; ,  &quot;Bob&quot; ,  &quot;Carol&quot; ) );
import  com.google.common.base.Predicate;
import  com.google.common.base.Predicate; Predicate<Person> predicate =  new  Predicate<Person>() { public   boolean  apply(Person input) { return  input.getName().contains( &quot;o&quot; ); } }; Iterable<Person> filteredList = Iterables . filter ( people, predicate); assert  Iterables. contains (filteredList, bob); assert  Iterables. contains (filteredList, carol); assert  !Iterables. contains (filteredList, alice);
Google Guava ,[object Object]
Well-Designed
Consistent?
Active
Agenda ,[object Object]
Builders / Fluent APIs
Function Objects /  Proxies / Interceptors
Java 7
Lombok / Groovy
“Traditional API” Order order =  new  Order(); order.setItemName( &quot;lattes&quot; ); order.setQuantity( 2 ); order.pay(Currency. getInstance ( &quot;USD&quot; ));
“Modern API” new  FluentOrder() .withItem( &quot;lattes&quot; ) .withQuantity( 2 ) .pay(Currency. getInstance ( &quot;USD&quot; ));
“Modern API” class  FluentOrder { private  String  item ; private   int   quantity ; public  FluentOrder withItem(String item) { this . item  = item; return   this ; }   public  FluentOrder withQuantity( int  quantity) { this . quantity  = quantity; return   this ; }   boolean  pay(Currency currency) {   // pay order return   true ; } }
class  OrderBuilder { QuantityHolder withItem(String item) { return   new  QuantityHolder(item); } } class  QuantityHolder { private   final  String  item ; private  QuantityHolder(String item) { this . item  = item; } OrderFiller withQuantity( int  quantity) { return   new  OrderFiller( item , quantity);  } } class  OrderFiller { private   final  String  item ; private   final   int   quantity ; private  OrderFiller(String item,  int  quantity) { this . item  = item;  this . quantity  = quantity; } boolean  pay(Currency currency) { /* pay order... */   return   true ; } }
... another type-safe version new  Order( OrderBuilder. newInstance () .initItemName( &quot;latte&quot; ) .initQuantity( 10 ) .withCurrency(Currency. getInstance ( &quot;CHF&quot; )) ).pay(); // forgetting required args is a compile error new  Order( OrderBuilder.newInstance() .initItemName( &quot;latte&quot; ) .withCurrency(Currency.getInstance( &quot;CHF&quot; ) ));
public   class  OrderBuilder<NAME, QUANTITY> { // required fields private  String  itemName ; private   int   quantity ; private  Currency  currency ;  // optional field public   static  OrderBuilder<NOK, NOK> newInstance() { return   new  OrderBuilder<>(); } public  OrderBuilder(String itemName,  int  quantity, Currency currency) { this . itemName  = itemName; this . quantity  = quantity; this . currency  = currency; } public  OrderBuilder<OK, QUANTITY> initItemName(String itemName) { this . itemName  = itemName; return   new  OrderBuilder<>(name,  quantity ,  currency ); } public  OrderBuilder<NAME, OK> initQuantity( int  quantity) { this . quantity  = quantity; return   new  OrderBuilder<>( itemName , quantity,  currency ); } public  OrderBuilder<NAME, QUANTITY> withCurrency(Currency currency) { this . currency  = currency; return   this ; } ...  // getters & default ctor omitted }
... and it's just plain old Groovy new  Order( itemName:  'lattes' , quantity: 2 ).pay(Currency.getInstance( 'USD' )) new  Order().with { itemName =  'lattes' quantity = 2 pay(Currency. getInstance ( 'USD' )) }
Builders & Fluent API + More expressive + Type-safer + Easier to use - Harder to write - Harder to learn? - Some reformatting tools choke
Agenda ,[object Object]
Builders / Fluent APIs
Function Objects /  Proxies / Interceptors
Java 7
Lombok / Groovy
public   class  ResourceProvider {   private   final  ReadWriteLock  lock  =  new  ReentrantReadWriteLock(); private   final  Map<String, String>  data  =  new  ConcurrentHashMap();   public  String getResource(String key)  throws  Exception { lock .readLock().lock(); try  { return   data .get(key); }  finally  { lock .readLock().unlock(); } } public   void  refresh()  throws  Exception { lock .writeLock().lock(); try  { // reload settings... }  finally  { lock .writeLock().unlock(); } } } “Traditional API”
public   class  ResourceController { private   final  ReadWriteLock  lock  =  new  ReentrantReadWriteLock(); public  <T> T withReadLock(Callable<T> block)  throws  Exception { lock .readLock().lock(); try  { return  block.call(); }  finally  { lock .readLock().unlock(); } } public  <T> T withWriteLock(Callable<T> block)  throws  Exception { lock .writeLock().lock(); try  { return  block.call(); }  finally  { lock .writeLock().unlock(); } } } “Modern API” con't
public   class  ResourceProvider { private   final  ResourceController  controller  =  new  ResourceController(); private   final  Map<String, String>  data  =  new  ConcurrentHashMap(); public  String getResource( final  String key)  throws  Exception { return   controller .withReadLock( new  Callable<String>() { public  String call()  throws  Exception { return   data .get( key ); } }); } public   void  refresh()  throws  Exception { controller .withWriteLock( new  Callable<Void>() { public  Void call()  throws  Exception { // reload settings return   null ; } }); } } “Modern API” -- Function Objects
class  ResourceProvider { private   final   controller  =  new  ResourceController() private   final   data  = [:]  as  ConcurrentHashMap String getResource(String key) { controller .withReadLock({  data .get( key )  }  as  Callable) } void  refresh() { controller .withWriteLock( {  /* reload settings */ }  as  Callable)  } } “Modern API” -- Groovy Function Objects
public   class  DefaultResourceProvider  implements  ResourceProvider { private   final  Map<String, String>  data  =  new  ConcurrentHashMap(); @WithReadLock public  String getResource(String key) { return   data .get(key); } @WithWriteLock public   void  refresh() { System. out .println( &quot;Reloading the settings...&quot; ); } } “Modern API” -- Proxy Class
public   class  ResourceController  implements  InvocationHandler { private   final  Object  target ; private   final  ReadWriteLock  lock  =  new  ReentrantReadWriteLock(); ResourceController(Object target) {  this . target  = target; } public  Object invoke (Object proxy, Method method, Object[] args) { try  { Method targetMethod =  target .getClass().getMethod( method.getName(), method.getParameterTypes()); if  (targetMethod.isAnnotationPresent( WithReadLock . class )) { lock .readLock().lock(); try  { return  targetMethod.invoke( target , args); }  finally  { lock .readLock().unlock(); } }  else   if  (targetMethod.isAnnotationPresent( WithWriteLock . class )){ lock .writeLock().lock(); try  { return  targetMethod.invoke( target , args); }  finally  { lock .writeLock().unlock(); } }  else  { return  targetMethod.invoke( target , args); } }  catch  (Exception ex) { throw   new  RuntimeException(ex); } } }
“Modern API” -- Proxy Class con't InvocationHandler handler =  new  ResourceController( new  DefaultResourceProvider() ); ResourceProvider p = (ResourceProvider) Proxy. newProxyInstance ( DefaultResourceProvider. class .getClassLoader(), new  Class[]{ResourceProvider. class }, hand ler); p.refresh(); p.getResource( &quot;property&quot; );
“Modern API” -- Proxy Class con't class  ResourceProvider { private   final  Map  data  =  new  ConcurrentHashMap(); @WithReadLock String getResource(String key) { return  (String) data .get(key); } @WithWriteLock void  refresh() { // Reload settings... } }
public   class  WithLockInterceptor  {   // This is shared!!! private   final  ReadWriteLock  lock  =  new  ReentrantReadWriteLock(); @AroundInvoke public  Object enforceLock(InvocationContext context)  throws  Exception{ try  { Method targetMethod = context.getMethod(); if  (targetMethod.isAnnotationPresent( WithReadLock . class )) { lock .readLock().lock(); try  { return  context.proceed(); }  finally  { lock .readLock().unlock(); } }  else   if  (targetMethod.isAnnotationPresent( WithWriteLock . class )){ lock .writeLock().lock(); try  { //reload the resources into memory return  context.proceed(); }  finally  { lock .writeLock().unlock(); } }    return  context.proceed(); }  catch  (Exception ex) { throw   new  RuntimeException(ex); } } }
Function Objects  + Safe + Boilerplate is compiler enforced + Easily replaces finally & catch blocks  + Easier in Java 8 and Groovy - Verbose - Different
Proxies & Interceptors + Declarative  + Expressive + Easily replaces finally & catch blocks  + Many implementation options - Proxy requires interface - Proxy hard to instantiate - Unproxied class may not be “valid”

More Related Content

What's hot

What's in Kotlin for us - Alexandre Greschon, MyHeritage
What's in Kotlin for us - Alexandre Greschon, MyHeritageWhat's in Kotlin for us - Alexandre Greschon, MyHeritage
What's in Kotlin for us - Alexandre Greschon, MyHeritageDroidConTLV
 
using python module: doctest
using python module: doctestusing python module: doctest
using python module: doctestmitnk
 
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09Ilya Grigorik
 
50 new things we can do with Java 8
50 new things we can do with Java 850 new things we can do with Java 8
50 new things we can do with Java 8José Paumard
 
JFokus 50 new things with java 8
JFokus 50 new things with java 8JFokus 50 new things with java 8
JFokus 50 new things with java 8José Paumard
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developersJosé Paumard
 
Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Ignacio Martín
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsBaruch Sadogursky
 
Functional aspects of java 8
Functional aspects of java 8Functional aspects of java 8
Functional aspects of java 8Jobaer Chowdhury
 
The redux saga begins
The redux saga beginsThe redux saga begins
The redux saga beginsDaniel Franz
 
Return Oriented Programming (ROP chaining)
Return Oriented Programming (ROP chaining)Return Oriented Programming (ROP chaining)
Return Oriented Programming (ROP chaining)Abhinav Chourasia, GMOB
 
Using Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side EffectsUsing Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side EffectsGlobalLogic Ukraine
 
Specs Presentation
Specs PresentationSpecs Presentation
Specs PresentationSynesso
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmineRubyc Slides
 
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, Gett
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, GettLean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, Gett
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, GettDroidConTLV
 
Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...
Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...
Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...Codemotion
 

What's hot (20)

What's in Kotlin for us - Alexandre Greschon, MyHeritage
What's in Kotlin for us - Alexandre Greschon, MyHeritageWhat's in Kotlin for us - Alexandre Greschon, MyHeritage
What's in Kotlin for us - Alexandre Greschon, MyHeritage
 
using python module: doctest
using python module: doctestusing python module: doctest
using python module: doctest
 
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
Lean & Mean Tokyo Cabinet Recipes (with Lua) - FutureRuby '09
 
50 new things we can do with Java 8
50 new things we can do with Java 850 new things we can do with Java 8
50 new things we can do with Java 8
 
JFokus 50 new things with java 8
JFokus 50 new things with java 8JFokus 50 new things with java 8
JFokus 50 new things with java 8
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developers
 
Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
 
Functional aspects of java 8
Functional aspects of java 8Functional aspects of java 8
Functional aspects of java 8
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Next Level Testing Revisited
Next Level Testing RevisitedNext Level Testing Revisited
Next Level Testing Revisited
 
The redux saga begins
The redux saga beginsThe redux saga begins
The redux saga begins
 
Return Oriented Programming (ROP chaining)
Return Oriented Programming (ROP chaining)Return Oriented Programming (ROP chaining)
Return Oriented Programming (ROP chaining)
 
Using Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side EffectsUsing Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side Effects
 
Specs Presentation
Specs PresentationSpecs Presentation
Specs Presentation
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmine
 
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, Gett
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, GettLean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, Gett
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, Gett
 
Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...
Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...
Knowledge is Power: Getting out of trouble by understanding Git - Steve Smith...
 

Similar to Java Boilerplate Busters

Google collections api an introduction
Google collections api   an introductionGoogle collections api   an introduction
Google collections api an introductiongosain20
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with JasmineTim Tyrrell
 
Javascript Unit Testing
Javascript Unit TestingJavascript Unit Testing
Javascript Unit TestingPaul Klipp
 
Unit8
Unit8Unit8
Unit8md751
 
Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web ModuleMorgan Cheng
 
Effective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsEffective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsMarakana Inc.
 
Python - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave ParkPython - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave Parkpointstechgeeks
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With PhpJeremy Coates
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript PrimerAdam Hepton
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaJevgeni Kabanov
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Guillaume Laforge
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery PresentationSony Jain
 

Similar to Java Boilerplate Busters (20)

Google guava
Google guavaGoogle guava
Google guava
 
Google collections api an introduction
Google collections api   an introductionGoogle collections api   an introduction
Google collections api an introduction
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Spring Capitulo 05
Spring Capitulo 05Spring Capitulo 05
Spring Capitulo 05
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
 
Javascript Unit Testing
Javascript Unit TestingJavascript Unit Testing
Javascript Unit Testing
 
My java file
My java fileMy java file
My java file
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Unit8
Unit8Unit8
Unit8
 
Groovy
GroovyGroovy
Groovy
 
Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web Module
 
Effective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsEffective Java - Still Effective After All These Years
Effective Java - Still Effective After All These Years
 
Prototype js
Prototype jsPrototype js
Prototype js
 
Python - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave ParkPython - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave Park
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With Php
 
Linq intro
Linq introLinq intro
Linq intro
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript Primer
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery Presentation
 

More from HamletDRC

Static Analysis and AST Transformations
Static Analysis and AST TransformationsStatic Analysis and AST Transformations
Static Analysis and AST TransformationsHamletDRC
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEAHamletDRC
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokusHamletDRC
 
10 Years of Groovy
10 Years of Groovy10 Years of Groovy
10 Years of GroovyHamletDRC
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - GreachHamletDRC
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)HamletDRC
 
AST Transformations
AST TransformationsAST Transformations
AST TransformationsHamletDRC
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 

More from HamletDRC (8)

Static Analysis and AST Transformations
Static Analysis and AST TransformationsStatic Analysis and AST Transformations
Static Analysis and AST Transformations
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEA
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
10 Years of Groovy
10 Years of Groovy10 Years of Groovy
10 Years of Groovy
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 

Recently uploaded

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 

Recently uploaded (20)

DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 

Java Boilerplate Busters

  • 1. Hamlet D'Arcy – Canoo Engineering AG @HamletDRC http://hamletdarcy.blogspot.com Java Boilerplate Busters
  • 2.
  • 4. Function Objects / Proxies / Interceptors
  • 8. Boilerplate – noun Code you shouldn't be writing yourself
  • 9.
  • 11. Function Objects / Proxies / Interceptors
  • 14. import static org.apache.commons.lang.StringUtils.*;
  • 15. import static org.apache.commons.lang.StringUtils.*; assert isAlpha ( &quot;abcde&quot; ); assert isNumeric ( &quot;12345&quot; ); assert isAlphanumeric ( &quot;12345abc&quot; );
  • 16. import static org.apache.commons.lang.StringUtils.*; assert isBlank ( &quot;&quot; ); assert isBlank ( null );
  • 17. import static org.apache.commons.lang.StringUtils.*; assert isAllLowerCase ( &quot;abcdef&quot; ); assert isAllUpperCase ( &quot;ABCDEF&quot; );
  • 18. import static org.apache.commons.lang.StringUtils.*; assert &quot;abc&quot; == defaultString ( &quot;abc&quot; ); assert &quot;&quot; == defaultString ( &quot;&quot; ); assert &quot;&quot; == defaultString ( null );
  • 19. import static org.apache.commons.lang.StringUtils.*; assert &quot;abc&quot; .equals( left ( &quot;abcdef&quot; , 3 )); assert &quot;def&quot; .equals( right ( &quot;abcdef&quot; , 3 )); assert null == right ( null , 3 );
  • 20. import static org.apache.commons.lang.StringUtils.*; Object[] array = new Object[]{ 1 , 2 , 3 }; assert &quot;1, 2, 3&quot; .equals( join (array, &quot;, &quot; )); List list = Arrays. asList ( 1 , 2 , 3 ); assert &quot;1, 2, 3&quot; .equals( join (list, &quot;, &quot; ));
  • 22. import org.apache.commons.lang.StringEscapeUtils; String xmlText = &quot; amp;quot; Hello amp;quot; & amp;quot; GoodBye amp;quot; &quot; ; String escapedXml = &quot;&quot;Hello&quot; &amp; &quot; + &quot;&quot;GoodBye&quot;&quot; ; assert escapedXml.equals( StringEscapeUtils. escapeXml (xmlText) ); assert xmlText.equals( StringEscapeUtils. unescapeXml (escapedXml) );
  • 23. import org.apache.commons.lang.StringEscapeUtils; String htmlText = &quot;<body>text</body>&quot; ; String escapedHtml = &quot;&lt;body&gt;&quot; + &quot;text&lt;/body&gt;&quot; ; assert escapedHtml.equals( StringEscapeUtils. escapeHtml (htmlText) ); assert htmlText.equals( StringEscapeUtils. unescapeHtml (escapedHtml) );
  • 24. import org.apache.commons.lang.StringEscapeUtils; String csvText = &quot;red, beans, and rice&quot; ; String escapedCsv = &quot; amp;quot; red, beans, and rice amp;quot; &quot; ; assert escapedCsv.equals( StringEscapeUtils. escapeCsv (csvText) ); assert csvText.equals( StringEscapeUtils. unescapeCsv (escapedCsv) );
  • 25. import static org.apache.commons.lang.ArrayUtils.*;
  • 26. import static org.apache.commons.lang.ArrayUtils.*; int [] evens = new int []{ 2 , 4 , 6 }; int [] odds = new int []{ 1 , 3 , 5 }; assert contains (evens, 2 ); assert contains (odds, 3 );
  • 27. import static org.apache.commons.lang.ArrayUtils.*; int [] evens = new int []{ 2 , 4 , 6 }; int [] odds = new int []{ 1 , 3 , 5 }; assert Arrays. equals ( new int []{ 2 , 4 , 6 , 8 }, add (evens, 8 ) ); assert Arrays. equals ( new int []{ 2 , 4 , 6 , 1 , 3 , 5 }, addAll (evens, odds) );
  • 28. import static org.apache.commons.lang.ArrayUtils.*; int [] evens = new int []{ 2 , 4 , 6 }; int [] odds = new int []{ 1 , 3 , 5 }; assert Arrays. equals ( new int []{ 2 , 6 }, remove (evens, 1 ) ); assert Arrays. equals ( new int []{ 1 , 3 }, remove (odds, 2 ) );
  • 29. import static org.apache.commons.lang.BooleanUtils.*;
  • 30. import static org.apache.commons.lang.BooleanUtils.*; assert toBoolean ( &quot;true&quot; ); assert toBoolean ( &quot;TRUE&quot; ); assert toBoolean ( &quot;tRUe&quot; ); assert toBoolean ( &quot;on&quot; ); assert toBoolean ( &quot;ON&quot; ); assert toBoolean ( &quot;yes&quot; ); assert toBoolean ( &quot;YES&quot; );
  • 32. import org.apache.commons.lang.builder.ToStringBuilder; public class Person { String name ; Date timestamp = new Date(); @Override public String toString() { return new ToStringBuilder( this ) .append( &quot;name&quot; , name ) .append( &quot;timestamp&quot; , timestamp ) .toString(); } }
  • 34. import org.apache.commons.lang.builder.EqualsBuilder; public class Person { String name ; Date timestamp = new Date(); @Override public boolean equals(Object obj) { if (obj == null ) { return false ; } if (obj == this ) { return true ; } if (obj.getClass() != getClass()) { return false ; } Person rhs = (Person) obj; return new EqualsBuilder() .append( name , rhs. name ) .append( timestamp , rhs. timestamp ) .isEquals(); } }
  • 36. import org.apache.commons.lang.builder.HashCodeBuilder; public class Person { String name ; Date timestamp = new Date(); @Override public int hashCode() { return new HashCodeBuilder() .append( name ) .append( timestamp ) .toHashCode(); } }
  • 38. import org.apache.commons.lang.builder. CompareToBuilder ; public class Person implements Comparable<Person> { String name ; Date timestamp = new Date(); public int compareTo(Person other) { return new CompareToBuilder() .append( this . name , other. name ) .toComparison(); } }
  • 39.
  • 41.
  • 43. new HashMap<T, Set<U>>
  • 45. import com.google.common.collect.Multimap; Multimap<String, String> multiMap = HashMultimap. create (); multiMap.put( &quot;Canoo&quot; , &quot;Hamlet&quot; ); multiMap.put( &quot;Canoo&quot; , &quot;Dierk&quot; ); multiMap.put( &quot;Canoo&quot; , &quot;Andres&quot; ); multiMap.put( &quot;EngineYard&quot; , &quot;Charles&quot; ); multiMap.put( &quot;EngineYard&quot; , &quot;Thomas&quot; ); multiMap.put( &quot;EngineYard&quot; , &quot;Nick&quot; );
  • 46. import com.google.common.collect.Multimap; assert multiMap.containsKey( &quot;Canoo&quot; ); assert multiMap.containsKey( &quot;EngineYard&quot; ); assert multiMap.containsValue( &quot;Hamlet&quot; ); assert multiMap.containsValue( &quot;Charles&quot; );
  • 47. import com.google.common.collect.Multimap; Collection<String> canooies = multiMap.get( &quot;Canoo&quot; ); Collection<String> c = Lists. newArrayList ( &quot;Dierk&quot; , &quot;Andres&quot; , &quot;Hamlet&quot; ); assert canooies.containsAll(c);
  • 49. import com.google.common.collect.BiMap; BiMap<String, String> biMap = HashBiMap. create (); biMap.put( &quot;Switzerland&quot; , &quot;die Schweiz&quot; ); biMap.put( &quot;Poland&quot; , &quot;Polska&quot; ); biMap.put( &quot;Austria&quot; , &quot;Österreich&quot; ); assert &quot;Polska&quot; == biMap.get( &quot;Poland&quot; ); assert &quot;Switzerland&quot; == biMap.inverse() .get( &quot;die Schweiz&quot; );
  • 50. new HashMap<T, Map<U, V>>
  • 52. import com.google.common.collect.Table; Table<Integer, Integer, String> table = HashBasedTable. create (); table.put( 1 , 1 , &quot;Hamlet&quot; ); table.put( 1 , 2 , &quot;Dierk&quot; ); table.put( 2 , 1 , &quot;Andres&quot; ); table.put( 2 , 2 , &quot;Matthius&quot; );
  • 53. import com.google.common.collect.Table; assert table.contains( 1 , 1 ); assert table.containsRow( 1 ); assert table.containsColumn( 2 ); assert !table.contains( 3 , 1 ); assert !table.containsRow( 3 ); assert !table.containsColumn( 3 ); assert &quot;Hamlet&quot; == table.get( 1 , 1 ); assert table.containsValue( &quot;Hamlet&quot; );
  • 55. import com.google.common.base.Joiner; Set<Integer> set = Sets. newHashSet ( 1 , 2 , 3 ); assert &quot;1, 2, 3&quot; .equals(Joiner. on ( &quot;, &quot; ).join(set));
  • 57. import com.google.common.base.Splitter; String string = &quot;1, 2, , 3&quot; ; Iterable<String> i = Splitter. on ( &quot;,&quot; ) .omitEmptyStrings() .trimResults() .split(string);
  • 58. import static com.google.common.collect.Iterables.*; import static com.google.common.collect.Lists.*; Iterable<Integer> setAsInts = transform (i, new Function<String, Integer>() { @Override public Integer apply(String input) { return Integer. valueOf (input); } }); assert newArrayList ( 1 , 2 , 3 ) .containsAll( newArrayList (setAsInts));
  • 59. import static com.google.common.base.Strings.*;
  • 60. import static com.google.common.base.Strings.*; assert emptyToNull ( &quot;&quot; ) == null ; assert &quot;&quot; .equals( nullToEmpty ( null )); assert isNullOrEmpty ( &quot;&quot; ); assert &quot;abcabcabc&quot; .equals( repeat ( &quot;abc&quot; , 3 ));
  • 61. import static com.google.common.base.Preconditions.*;
  • 62. import static com.google.common.base.Preconditions.*; int userID = 1 ; String userName = &quot;some name&quot; ; checkArgument (userID > 0 , &quot;userid is negative: %s&quot; , userID); checkNotNull (userName, &quot;user %s missing name&quot; , userID); checkState (userName.length() > 0 , &quot;user %s missing name&quot; , userID);
  • 63. import static com.google.common.base.Objects.*;
  • 64. import static com.google.common.base.Objects.*; class Person { String name ; Date timestamp = new Date(); @Override public String toString() { return toStringHelper ( this ) .add( &quot;name&quot; , name ) .add( &quot;timestamp&quot; , timestamp ).toString(); } }
  • 65. import static com.google.common.base.Equivalences.*;
  • 66. import static com.google.common.base.Equivalences.*; class Person implements Comparable<Person> { String name ; Date timestamp = new Date(); @Override public boolean equals(Object obj) { if (obj == null ) { return false ; } if (obj == this ) { return true ; } if (obj.getClass() != getClass()) { return false ; } Person rhs = (Person) obj; return equals ().equivalent( name , rhs. name ) && equals ().equivalent( timestamp , rhs. timestamp ); } @Override public int hashCode() { return hashCode ( name , timestamp ); } }
  • 67. import static com.google.common.collect.ComparisonChain.*;
  • 68. import static com.google.common.collect.ComparisonChain.*; class Person implements Comparable<Person> { String name ; Date timestamp = new Date(); public int compareTo(Person other) { return start () .compare( name , other. name ) .compare( timestamp , other. timestamp ) .result(); } }
  • 70. import com.google.common.base.Throwables; Exception ex = new Exception(); Throwables. propagateIfPossible (ex); Throwables. propagate (ex); // throws Exception Throwables. throwCause (ex, false );
  • 72. import com.google.common.base.Function; Person alice = new Person( &quot;Alice&quot; ); Person bob = new Person( &quot;Bob&quot; ); Person carol = new Person( &quot;Carol&quot; ); List<Person> people = newArrayList (alice, bob, carol);
  • 73. import com.google.common.base.Function; Function<Person, String> getName = new Function<Person, String>() { public String apply(Person p) { return p.getName(); } }; assert &quot;Alice&quot; == getName.apply(alice); Collection<String> names = Collections2 . transform (people, getName); assert names.containsAll( newArrayList ( &quot;Alice&quot; , &quot;Bob&quot; , &quot;Carol&quot; ) );
  • 75. import com.google.common.base.Predicate; Predicate<Person> predicate = new Predicate<Person>() { public boolean apply(Person input) { return input.getName().contains( &quot;o&quot; ); } }; Iterable<Person> filteredList = Iterables . filter ( people, predicate); assert Iterables. contains (filteredList, bob); assert Iterables. contains (filteredList, carol); assert !Iterables. contains (filteredList, alice);
  • 76.
  • 80.
  • 82. Function Objects / Proxies / Interceptors
  • 85. “Traditional API” Order order = new Order(); order.setItemName( &quot;lattes&quot; ); order.setQuantity( 2 ); order.pay(Currency. getInstance ( &quot;USD&quot; ));
  • 86. “Modern API” new FluentOrder() .withItem( &quot;lattes&quot; ) .withQuantity( 2 ) .pay(Currency. getInstance ( &quot;USD&quot; ));
  • 87. “Modern API” class FluentOrder { private String item ; private int quantity ; public FluentOrder withItem(String item) { this . item = item; return this ; } public FluentOrder withQuantity( int quantity) { this . quantity = quantity; return this ; } boolean pay(Currency currency) { // pay order return true ; } }
  • 88. class OrderBuilder { QuantityHolder withItem(String item) { return new QuantityHolder(item); } } class QuantityHolder { private final String item ; private QuantityHolder(String item) { this . item = item; } OrderFiller withQuantity( int quantity) { return new OrderFiller( item , quantity); } } class OrderFiller { private final String item ; private final int quantity ; private OrderFiller(String item, int quantity) { this . item = item; this . quantity = quantity; } boolean pay(Currency currency) { /* pay order... */ return true ; } }
  • 89. ... another type-safe version new Order( OrderBuilder. newInstance () .initItemName( &quot;latte&quot; ) .initQuantity( 10 ) .withCurrency(Currency. getInstance ( &quot;CHF&quot; )) ).pay(); // forgetting required args is a compile error new Order( OrderBuilder.newInstance() .initItemName( &quot;latte&quot; ) .withCurrency(Currency.getInstance( &quot;CHF&quot; ) ));
  • 90. public class OrderBuilder<NAME, QUANTITY> { // required fields private String itemName ; private int quantity ; private Currency currency ; // optional field public static OrderBuilder<NOK, NOK> newInstance() { return new OrderBuilder<>(); } public OrderBuilder(String itemName, int quantity, Currency currency) { this . itemName = itemName; this . quantity = quantity; this . currency = currency; } public OrderBuilder<OK, QUANTITY> initItemName(String itemName) { this . itemName = itemName; return new OrderBuilder<>(name, quantity , currency ); } public OrderBuilder<NAME, OK> initQuantity( int quantity) { this . quantity = quantity; return new OrderBuilder<>( itemName , quantity, currency ); } public OrderBuilder<NAME, QUANTITY> withCurrency(Currency currency) { this . currency = currency; return this ; } ... // getters & default ctor omitted }
  • 91. ... and it's just plain old Groovy new Order( itemName: 'lattes' , quantity: 2 ).pay(Currency.getInstance( 'USD' )) new Order().with { itemName = 'lattes' quantity = 2 pay(Currency. getInstance ( 'USD' )) }
  • 92. Builders & Fluent API + More expressive + Type-safer + Easier to use - Harder to write - Harder to learn? - Some reformatting tools choke
  • 93.
  • 95. Function Objects / Proxies / Interceptors
  • 98. public class ResourceProvider { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map<String, String> data = new ConcurrentHashMap(); public String getResource(String key) throws Exception { lock .readLock().lock(); try { return data .get(key); } finally { lock .readLock().unlock(); } } public void refresh() throws Exception { lock .writeLock().lock(); try { // reload settings... } finally { lock .writeLock().unlock(); } } } “Traditional API”
  • 99. public class ResourceController { private final ReadWriteLock lock = new ReentrantReadWriteLock(); public <T> T withReadLock(Callable<T> block) throws Exception { lock .readLock().lock(); try { return block.call(); } finally { lock .readLock().unlock(); } } public <T> T withWriteLock(Callable<T> block) throws Exception { lock .writeLock().lock(); try { return block.call(); } finally { lock .writeLock().unlock(); } } } “Modern API” con't
  • 100. public class ResourceProvider { private final ResourceController controller = new ResourceController(); private final Map<String, String> data = new ConcurrentHashMap(); public String getResource( final String key) throws Exception { return controller .withReadLock( new Callable<String>() { public String call() throws Exception { return data .get( key ); } }); } public void refresh() throws Exception { controller .withWriteLock( new Callable<Void>() { public Void call() throws Exception { // reload settings return null ; } }); } } “Modern API” -- Function Objects
  • 101. class ResourceProvider { private final controller = new ResourceController() private final data = [:] as ConcurrentHashMap String getResource(String key) { controller .withReadLock({ data .get( key ) } as Callable) } void refresh() { controller .withWriteLock( { /* reload settings */ } as Callable) } } “Modern API” -- Groovy Function Objects
  • 102. public class DefaultResourceProvider implements ResourceProvider { private final Map<String, String> data = new ConcurrentHashMap(); @WithReadLock public String getResource(String key) { return data .get(key); } @WithWriteLock public void refresh() { System. out .println( &quot;Reloading the settings...&quot; ); } } “Modern API” -- Proxy Class
  • 103. public class ResourceController implements InvocationHandler { private final Object target ; private final ReadWriteLock lock = new ReentrantReadWriteLock(); ResourceController(Object target) { this . target = target; } public Object invoke (Object proxy, Method method, Object[] args) { try { Method targetMethod = target .getClass().getMethod( method.getName(), method.getParameterTypes()); if (targetMethod.isAnnotationPresent( WithReadLock . class )) { lock .readLock().lock(); try { return targetMethod.invoke( target , args); } finally { lock .readLock().unlock(); } } else if (targetMethod.isAnnotationPresent( WithWriteLock . class )){ lock .writeLock().lock(); try { return targetMethod.invoke( target , args); } finally { lock .writeLock().unlock(); } } else { return targetMethod.invoke( target , args); } } catch (Exception ex) { throw new RuntimeException(ex); } } }
  • 104. “Modern API” -- Proxy Class con't InvocationHandler handler = new ResourceController( new DefaultResourceProvider() ); ResourceProvider p = (ResourceProvider) Proxy. newProxyInstance ( DefaultResourceProvider. class .getClassLoader(), new Class[]{ResourceProvider. class }, hand ler); p.refresh(); p.getResource( &quot;property&quot; );
  • 105. “Modern API” -- Proxy Class con't class ResourceProvider { private final Map data = new ConcurrentHashMap(); @WithReadLock String getResource(String key) { return (String) data .get(key); } @WithWriteLock void refresh() { // Reload settings... } }
  • 106. public class WithLockInterceptor { // This is shared!!! private final ReadWriteLock lock = new ReentrantReadWriteLock(); @AroundInvoke public Object enforceLock(InvocationContext context) throws Exception{ try { Method targetMethod = context.getMethod(); if (targetMethod.isAnnotationPresent( WithReadLock . class )) { lock .readLock().lock(); try { return context.proceed(); } finally { lock .readLock().unlock(); } } else if (targetMethod.isAnnotationPresent( WithWriteLock . class )){ lock .writeLock().lock(); try { //reload the resources into memory return context.proceed(); } finally { lock .writeLock().unlock(); } } return context.proceed(); } catch (Exception ex) { throw new RuntimeException(ex); } } }
  • 107. Function Objects + Safe + Boilerplate is compiler enforced + Easily replaces finally & catch blocks + Easier in Java 8 and Groovy - Verbose - Different
  • 108. Proxies & Interceptors + Declarative + Expressive + Easily replaces finally & catch blocks + Many implementation options - Proxy requires interface - Proxy hard to instantiate - Unproxied class may not be “valid”
  • 109.
  • 111. Function Objects / Proxies / Interceptors
  • 112. Java 7
  • 114. “Traditional Error Handling” try { doSomething(); } catch (UnsupportedOperationException e) { handleError(e); } catch (IllegalStateException e) { handleError(e); } catch (IllegalArgumentException e) { handleError(e); }
  • 115. “Modern Error Handling” try { doSomething(); } catch (UnsupportedOperationException | IllegalStateException | IllegalArgumentException e) { handleError(e); }
  • 116. “Traditional Resource Management” FileReader reader = new FileReader(path); try { return reader.read(); } finally { reader.close(); }
  • 117. “Modern Resource Management” try (FileReader reader = new FileReader(path)) { return reader.read(); }
  • 118. “Modern Resource Management” class MyResource implements AutoCloseable { String getResource() { return &quot;some resource&quot; ; } @Override public void close() throws Exception { // closing } } try (MyResource resource = new MyResource()) { return resource.getResource(); }
  • 119. Strings in Switch class Calculator { Number apply( int left, String operator, int right) { switch (operator) { case &quot;plus&quot; : return left + right; case &quot;minus&quot; : return left - right; case &quot;times&quot; : return left * right; case &quot;divided by&quot; : return left / right; default : throw new Exception(operator); } } } Calculator calculator = new Calculator(); assert calculator.apply( 1 , &quot;plus&quot; , 2 ).equals( 3 ); assert calculator.apply( 5 , &quot;times&quot; , 2 ).equals( 10 ); assert calculator.apply( 5 , &quot;minus&quot; , 2 ).equals( 3 );
  • 120. Regex in Groovy Switch Number apply( int left, String operator, int right) { switch (operator) { c ase ~/ (i)plus/ : return left + right case ~/ (i)minus/ : return left - right case ~/ (i)times/ : return left * right case ~/ (i)divided by/ : return left / right default : throw new Exception(operator) } } assert apply( 1 , &quot;plus&quot; , 2 ) == 3 assert apply( 5 , &quot;TIMES&quot; , 2 ) == 10 assert apply( 5 , &quot;MiNuS&quot; , 2 ) == 3
  • 121. Less Generic Cruft Map<Integer, String> map = new HashMap<>();
  • 122. Java 7 Features + Soon to be widely used + Terser code - No Lambdas - Not widely used
  • 123.
  • 125. Function Objects / Proxies / Interceptors
  • 126. Java 7
  • 128. “Traditional Java Bean” public class Person { private String fName ; private String lName ; public String getFirstName() { return fName ; } public void setFirstName(String f) { this . fName = f; } public String getLastName() { return lName ; } public void setLastName(String l) { this . lName = l; } @Override public boolean equals(Object o) { ... } @Override public int hashCode() { ... } }
  • 129. “Modern Java Bean” -- Lombok @EqualsAndHashCode public class Person { @Setter @Getter private String firstName ; @Setter @Getter private String lastName ; }
  • 130. “Modern Java Bean” -- Lombok @Data public class Person { private String firstName ; private String lastName ; }
  • 131.
  • 132. Lombok + Generates boilerplate into Class file + Java-only, IDE support + delombok option - IDEA Plugin is poor - Hinders some Eclipse features - Not all features are loved by all
  • 133. “Modern Java Bean” -- Groovy @EqualsAndHashCode public class Person { String firstName String lastName }
  • 134.
  • 135.
  • 136. Groovy + Generates boilerplate into Class file + Great Java interop & IDE support + Gateway to many other features - Requires a new language ? Performs worse than Java ? Hinders some IDE features
  • 137.
  • 139. Function Objects / Proxies / Interceptors
  • 140. Java 7
  • 142.

Editor's Notes

  1. // Propagates throwable as-is if it is an instance of RuntimeException or Error, or else as a last resort, wraps it in a RuntimeException then propagates. Throwables.propagate(ex); // Propagates throwable exactly as-is, if and only if it is an instance of RuntimeException or Error. Throwables.propagateIfPossible(ex); // Rethrows the cause exception of a given throwable, discarding the original throwable. if the cause is null, then throws the ex Throwables.throwCause(ex, false);