SlideShare a Scribd company logo
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, MyHeritage
DroidConTLV
 
using python module: doctest
using python module: doctestusing python module: doctest
using python module: doctest
mitnk
 
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
Ilya 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 8
José 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 8
José 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 developers
José 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 es6
Ignacio 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 Seasons
Baruch Sadogursky
 
Functional aspects of java 8
Functional aspects of java 8Functional aspects of java 8
Functional aspects of java 8
Jobaer Chowdhury
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
Christoffer Noring
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
José Paumard
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
Christoffer Noring
 
Next Level Testing Revisited
Next Level Testing RevisitedNext Level Testing Revisited
Next Level Testing Revisited
James Saryerwinnie
 
The redux saga begins
The redux saga beginsThe redux saga begins
The redux saga begins
Daniel 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 Effects
GlobalLogic Ukraine
 
Specs Presentation
Specs PresentationSpecs Presentation
Specs Presentation
Synesso
 
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, Gett
DroidConTLV
 
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 guava
Google guavaGoogle guava
Google collections api an introduction
Google collections api   an introductionGoogle collections api   an introduction
Google collections api an introduction
gosain20
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
Tim Tyrrell
 
Javascript Unit Testing
Javascript Unit TestingJavascript Unit Testing
Javascript Unit TestingPaul Klipp
 
Unit8
Unit8Unit8
Unit8md751
 
Groovy
GroovyGroovy
Groovy
Zen Urban
 
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 Years
Marakana Inc.
 
Prototype js
Prototype jsPrototype js
Prototype js
mussawir20
 
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
pointstechgeeks
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With Php
Jeremy Coates
 
Linq intro
Linq introLinq intro
Linq intro
Bình Trọng Án
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript Primer
Adam 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 - 2008
Guillaume Laforge
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery Presentation
Sony 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 Transformations
HamletDRC
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEA
HamletDRC
 
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 Groovy
HamletDRC
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
HamletDRC
 
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 transformations
HamletDRC
 

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

Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 

Recently uploaded (20)

Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 

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