Friday, 8 April 2016

Effective Java Item 30: Strategy enum pattern

 enum PayrollDay {  
   MONDAY(PayType.WEEKDAY),  
   TUESDAY(PayType.WEEKDAY),  
   WEDNESDAY(PayType.WEEKDAY),  
   THURSDAY(PayType.WEEKDAY),  
   FRIDAY(PayType.WEEKDAY),  
   SATURDAY(PayType.WEEKEND),  
   SUNDAY(PayType.WEEKEND);  
   private final PayType payType;  
   PayrollDay(PayType payType){  
     this.payType = payType;  
   }  
   double pay (double hoursWorked, double payRate){  
     return payType.pay(hoursWorked, payRate);  
   }  
   private enum PayType {  
     WEEKDAY {  
       double overtimePay(double hours, double payRate){  
         return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT) * payRate / 2;  
       }  
     },  
     WEEKEND {  
       double overtimePay(double hours, double payRate){  
         return hours * payRate / 2;  
       }  
     };  
     private static final int HOURS_PER_SHIFT = 8;  
     abstract double overtimePay(double hours, double payRate);  
     double pay(double hoursWorked, double payRate){  
       double basePay = hoursWorked * payRate;  
       return basePay + overtimePay(hoursWorked, payRate);  
     }  
   }  
 }  
 public class StrategyEnumPattern{  
   public static void main(String[] args){  
     for (PayrollDay payrollDay : PayrollDay.values()){  
       System.out.println(payrollDay + " pays " + payrollDay.pay(9, 100));  
     }  
   }  
 }  

Effective Java Item 28: Generics Comparable

What's the benefit of using Comparable<? super T>?

   public static <T extends Comparable<T>> T max1 (List<T> list){  
     //implementation not import  
     return null;  
   }  
   public static <T extends Comparable<? super T>> T max2 (List<T> list){  
     //implementation not import  
     return null;  
   }  

The code below compiles fine.

 class Cat implements Comparable<Cat>{  
   @Override  
   public int compareTo(Cat o) {return 0;}  
   public static void main(String[] args){  
     List<Cat> cats = new ArrayList<>();  
     max1(cats);  
     max2(cats);  
   }  
 }  
However, if we make Cat extend Animal and allow it to compare with other animals....

 class Animal{}  
 class Cat extends Animal implements Comparable<Animal>{  
   @Override  
   public int compareTo(Animal o) {  
     return 0;  
   }  
 }  

max1() doesn't compile any more. Clearly, Comparable<? super T> is more flexible.

Wednesday, 6 April 2016

Groovy Map << [key: value] vs Map << [(key): value]

Note the difference between a key wrapped with () and without. If without parentheses, the key will be literal 'key'. With parentheses, the key is the value 100.

 def key = 100  
 def map = [:]  
 map << [key:2]  
 println map  
 map << [(key):2]  
 println map  

Tuesday, 5 April 2016

Fix IntelliJ compilation level

Keep getting

Warning:java: source value 1.5 is obsolete and will be removed in a future release
Warning:java: To suppress warnings about obsolete options, use -Xlint:-options.

If still no luck with changing the settings below...




















Try add the following to pom.xml

 <build>  
     <plugins>  
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-compiler-plugin</artifactId>  
         <version>3.1</version>  
         <configuration>  
           <source>1.8</source>  
           <target>1.8</target>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  

Monday, 4 April 2016

Groovy XML traverse

Now we have some XML and we need to print out the subfield's code and text under datafield with tag 852.  In this case, the output expected is [b PIC, h test2]

 class XmlTraverse {  
   def String xml = """  
     <response>  
       <marcRecord>  
         <leader>00167nx a22000854 4500</leader>  
         <controlfield tag="001">4000089</controlfield>  
         <controlfield tag="004">3569260</controlfield>  
         <controlfield tag="005">20160330130804.0</controlfield>  
         <controlfield tag="008">1603300u  0  4000uueng0000000</controlfield>  
         <datafield ind2=" " ind1="8" tag="852">  
           <subfield code="b">PIC</subfield>  
           <subfield code="h">test2</subfield>  
         </datafield>  
         <datafield tag="954" ind1="" ind2="">  
           <subfield code="a">NLA</subfield>  
         </datafield>  
       </marcRecord>  
     </response>  
   """ 
 }  

First attempt, find the 852 tag datafield, under that datafield, find all subfields, use collect to transform to a List

 import groovy.util.XmlSlurper  
 import groovy.util.slurpersupport.GPathResult  
 import groovy.util.slurpersupport.NodeChild  
 import groovy.util.slurpersupport.NodeChildren;  
 class XmlTraverse   
   def test(){  
     def response = new XmlSlurper().parseText(xml)  
     def datafield852 = response.marcRecord.'*'.find { node->  
       node.name() == 'datafield' && node.@tag == '852'  
     }  
     def subfields = datafield852.'*'.findAll { node ->  
       node.name() == 'subfield'  
     }  
     def subfieldsCodeAndValue = subfields.collect { node ->  
       "" + node.@code + " " + node.text()  
     }  
     println subfieldsCodeAndValue  
   }  
 }  

It's bad because A. It's too long,  B. if the tag doesn't exist, it throws a ClassCastException.

Here come the 2nd attempt. Find all the subfields with a parent's tag value equal to 852. Now even if tag 852 didn't exist, it would not break, printing out an empty list.

   def test2(){  
     def response = new XmlSlurper().parseText(xml)  
     def List subfieldsValue = response.marcRecord.datafield.subfield.findAll { node->  
       node.parent().@tag == '852'  
     }.collect{"" + it.@code + " " + it.text()}  
     println subfieldsValue  
   }  

If we just to want to print the text, we can take advantage of the asterisk operator.

   def test3(){  
     def response = new XmlSlurper().parseText(xml)  
     def List subfieldsValue = response.marcRecord.datafield.subfield.findAll { node->  
       node.parent().@tag == '852'  
     }*.text()  
     println subfieldsValue  
   }  

Reference: Processing XML

Sunday, 3 April 2016

Synchronized block is Reentrant

A thread that has already acquired the lock of a synchronized block can freely enter another synchronized block, provided both synchronized blocks are locked on same object.

If a thread calls outer(), it can also call inner() from inside outer(), because both methods are synchronized on the same monitor object ("this")

 public class Reentrant{  
  public synchronized outer(){  
   inner();  
  }  
  public synchronized inner(){  
   //do something  
  }  
 }  


A customer lock can prevent reentrant. Now the thread calling outer() will be blocked at lock.lock() inside the inner() method.

 public class Lock{  
  private boolean isLocked = false;  
  public synchronized void lock()  
  throws InterruptedException{  
   while(isLocked){  
    wait();  
   }  
   isLocked = true;  
  }  
  public synchronized void unlock(){  
   isLocked = false;  
   notify();  
  }  
 }  

 public class NotReentrant{  
  Lock lock = new Lock();  
  public outer(){  
   lock.lock();  
   inner();  
   lock.unlock();  
  }  
  public synchronized inner(){  
   lock.lock();  
   //do something  
   lock.unlock();  
  }  
 }  


Reference: Locks in Java

Saturday, 2 April 2016

Static member class vs. nonstatic

Wherever you use a static member class, you can always remove the static keyword, and it still works. But it will have an unnecessary reference to the enclosing instance (the Outer class's instance)

If we add static on Inner class, it won't compile. Because static member class doesn't know about Outer class's instance.

 public class Outer {  
   public void doit(){  
     Inner inner = new Inner();  
     inner.doit();  
   }  
   private void doitAgain(){  
     System.out.println("do it again");  
   }  
   private class Inner {  
     public void doit() {  
       Outer.this.doitAgain();  
     }  
   }  
   public static void main(String[] args){  
     new Outer().doit();  
   }  
 }