Wednesday 20 April 2016

Effective Java Item 78: Serialization proxy

 class Period implements Serializable{  
   private final Date start;  
   private final Date end;  
   
   public Period(Date start, Date end){  
     if (start.compareTo(end) > 0){  
       throw new IllegalArgumentException(start + " after "+end);  
     }  
     this.start = start;  
     this.end = end;  
   }  
   
   public Date start(){  
     return new Date(start.getTime());  
   }  
   
   public Date end(){  
     return new Date(end.getTime());  
   }  
   
   @Override  
   public String toString() {  
     return "start "+start+ " end "+end;  
   }  
   
   private static class PeriodProxy implements Serializable{  
     private final Date start;  
     private final Date end;  
   
     PeriodProxy(Period period){  
       this.start = period.start;  
       this.end = period.end;  
     }  
   
     private Object readResolve(){  
       return new Period(start, end);  
     }  
   }  
   
   private Object writeReplace(){  
     return new PeriodProxy(this);  
   }  
   
   private void readObject(ObjectInputStream in) throws InvalidObjectException{  
     throw new InvalidObjectException("Proxy required");  
   }  
   
 }  
   
 public class SerializationProxy {  
   public static void main(String[] args) throws Exception{  
     Calendar cal1 = Calendar.getInstance();  
     cal1.set(2015, Calendar.JANUARY, 1);  
     Calendar cal2 = Calendar.getInstance();  
     cal1.set(2016, Calendar.JANUARY, 1);  
     Period period = new Period(cal1.getTime(), cal2.getTime());  
     System.out.println(period);  
     Period deserializePeriod = serializeAndDeserialize(period);  
     System.out.println(deserializePeriod);  
   }  
   
   private static <T> T serializeAndDeserialize(T serialized) throws Exception {  
     File serializeFile = new File("_serialized");  
     // serialize  
     try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(serializeFile))) {  
       out.writeObject(serialized);  
     }  
     // deserialize  
     try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(serializeFile))) {  
       @SuppressWarnings("unchecked")  
       T deserialized = (T) in.readObject();  
       return deserialized;  
     }  
   }  

Tuesday 19 April 2016

Effective Java Item 71: Lazy initialization, holder class, double checking

static field uses holder class

 private static class ValueHolder{  
     static final String value = "Lazy initialized";  
   }  
   
   public static String getValue(){  
     return ValueHolder.value;  
   }  

instance field uses double check

 private volatile String value;  
   
   public String getValue(){  
     String result = value;  
     if (result == null){  
       synchronized (this){  
         result = value;  
         if (result == null){  
           value = result = "LazyInitialized";  
         }  
       }  
     }  
     return result;  
   }  

if you don't mind re-creating instance again, You can use single check

 public String getValue(){  
     String result = value;  
     if (result == null){  
       value = result = "LazyInitialized";  
     }  
     return result;  
   }  

Monday 18 April 2016

Effective Java Item 69: Synchronized map vs ConcurrentMap

Synchronized map

 public static void main(String[] args){  
     Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<String, String>());  
     syncMap.put("1","1");  
     syncMap.put("2","2");  
     syncMap.put("3","3");  
     for (String key : syncMap.keySet()){  
       addValue(syncMap);  
     }  
   }  
   
   private static void addValue(Map<String, String> map){  
     map.put("4", "4");  
   }  

Throws ConcurrentModificationException

 Exception in thread "main" java.util.ConcurrentModificationException  
      at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)  
      at java.util.HashMap$KeyIterator.next(HashMap.java:1453)  

ConcurrentHashMap never throws ConcurrentModificationException

 Map<String, String> syncMap = new ConcurrentHashMap<>();  

Sunday 17 April 2016

Effective Java Item 66: Volatile, synchronization, and AtomicLong

volatile

 class SerialNumber{  
   private static volatile long nextSerialNumber = 0;  
   
   public static long nextSerialNumber(){  
     return nextSerialNumber++;  
   }  
 }  
   
 public class MyConcurrency extends Thread{  
   
   private static List<Long> numbers = new ArrayList<>();  
   
   private static synchronized void add(long number){  
     numbers.add(number);  
   }  
   
   public static void main(String[] args) throws Exception{  
     new MyConcurrency().start();  
     new MyConcurrency().start();  
     new MyConcurrency().start();  
     Thread.sleep(10*1000); //Make sure threads all end  
     Set<Long> hashSet = new HashSet<>();  
     for(long i : numbers) {  
       if(!hashSet.add(i)){  
         System.out.println("Has duplicate "+i);  
       }  
     }  
     System.out.println("Finish");  
   }  
   
   @Override  
   public void run() {  
     long nextSerialNumber;  
     do{  
       nextSerialNumber = SerialNumber.nextSerialNumber();  
       add(nextSerialNumber);  
     }while(nextSerialNumber < 10000);  
   }  
 }  

Found duplicates

 Has duplicate 4528  
 Has duplicate 5280  
 Has duplicate 7274  
 Has duplicate 9376  
 Finish  

Correct implementation using synchronized

 class SerialNumber{  
   private static long nextSerialNumber = 0;  
   
   public static synchronized long nextSerialNumber(){  
     return nextSerialNumber++;  
   }  
 }  

Correct implementation using AtomicLong

 class SerialNumber{  
   private static final AtomicLong nextSerialNumber = new AtomicLong();  
   
   public static long nextSerialNumber(){  
     return nextSerialNumber.getAndIncrement();  
   }  
 }  

Saturday 16 April 2016

Threadlocal example

Business layer can access userId without passing the parameter from web layer.

 
 package threadlocal;  
   
 class SecurityContext {  
   
   private String userId = null;  
   
   public String getUserId() {  
     return userId;  
   }  
   
   public void setUserId(String userId) {  
     this.userId = userId;  
   }  
 }  
   
 class MyThreadLocal {  
   private static final ThreadLocal userThreadLocal = new ThreadLocal();  
   
   public static void set(SecurityContext user) {  
     userThreadLocal.set(user);  
   }  
   
   public static void unset() {  
     userThreadLocal.remove();  
   }  
   
   public static SecurityContext get() {  
     return (SecurityContext)userThreadLocal.get();  
   }  
 }  
   
 class BusinessService {  
   
   public void businessMethod() {  
     SecurityContext securityContext = MyThreadLocal.get();  
     System.out.println(securityContext.getUserId());  
   }  
 }  
   
 public class Main extends Thread{  
   public static void main(String[] args){  
     new Main().start();  
     new Main().start();  
   }  
   
   @Override  
   public void run() {  
     SecurityContext securityContext = new SecurityContext();  
     securityContext.setUserId(getName());  
     MyThreadLocal.set(securityContext);  
     new BusinessService().businessMethod();  
     MyThreadLocal.unset();  
   }  
 }  
   
Reference: http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/

Effective Java Item 49: Auto boxed type NullPointerException

Seems quite innocuous, but throws NPE

Example 1

   public static void main(String[] args){  
     Boolean b = null;  
     call(b);  
   }  
   
   public static void call(boolean b){  
     System.out.println(b);  
   }  

Example 2

   public static void main(String[] args){  
     Integer i = null;  
     if (i == 42){  
       System.out.println(i);  
     }  
   }  

Thursday 14 April 2016

jQuery return false; vs e.preventDefault()

return false;

is equal to

e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();

So the lesson is never use 'return false' unless you completely understand it.

Reference: http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/comment-page-2/#comment-73556

Monday 11 April 2016

Bash script to replace part of file name

Suppose a folder has following files

abcde-l1.mp3 abcde-l2.mp3 abcde-l3.mp3 abcde.meta.xml abcde.wav

We want to rename them to

12345-l1.mp3 12345-l2.mp3 12345-l3.mp3 12345.meta.xml 12345.wav

 #!/bin/bash  
   
 if [[ ! $1 ]]; then  
   echo "No argument supplied"  
   exit 1  
 fi  
   
 newname=$1  
   
 for entry in /Users/msun/msun/sound/*.wav; do  
  #Get file name without path e.g. abc.wav  
  filename=$(basename $entry)  
  #Get file name without extension e.g. abc  
  filename="${filename%.*}"  
  break   
 done  
   
 #replace $filename with $newname  
 for entry in /Users/msun/msun/sound/*; do  
  mv $entry ${entry/$filename/$newname}  
 done  

Sunday 10 April 2016

Expect script to ssh server and do stuff, scp files to server

 #!/usr/bin/expect  
   
 set server [lindex $argv 0];  
 set folder [lindex $argv 1];  
 spawn ssh $server  
 expect "msun@$server's password:"  
 send "$env(MY_PASSWORD)\r"  
 send "mkdir -p /home/$folder\r"  
 send "exit\r"  
 interact  
 spawn bash -c "sudo scp ~/sound/*.* msun@$server:/home/$folder"  
   
 expect {  
  "Password:" {  
   send "$env(MY_PASSWORD)\r"  
   exp_continue  
  }  
  "msun@$server's password:" {  
   send "$env(MY_PASSWORD)\r"  
   exp_continue  
  }  
 }  
 sleep 1  
 exit  

In .bash_profile

 export MY_PASSWORD = "12345"  

File name is sshscp.exp
Usage: ./sshscp.exp serverName folderName

Effective Java Item 41: Overload String.valueOf(char[]) and String.valueOf(Object)

Overloading methods can hurt a lot...

 public class MyOverload {  
   public static void main(String[] args){  
     char[] a = new char[]{'a','b','c'};  
     System.out.println(String.valueOf(a));  
     Object o = new char[]{'a','b','c'};  
     System.out.println(String.valueOf(o));  
   }  
 }  

The result is

 abc  
 [C@194fa3e  

Saturday 9 April 2016

Effective Java Item 11: Cloneable interface

Cloneable determines the behavior of Object's protected clone implementation: if a class implements Cloneable, Object's clone method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException.

What does this sentence mean? Let's look at an example.

 class Dog implements Cloneable{  
   private String name;  
   private int age;  
   
   public Dog(String name, int age) {  
     this.name = name;  
     this.age = age;  
   }  
   
   @Override  
   public String toString() {  
     return "Dog{" +  
         "name='" + name + '\'' +  
         ", age=" + age +  
         '}';  
   }  
   
   @Override  
   public Dog clone() {  
     try {  
       return (Dog) super.clone();  
     } catch (CloneNotSupportedException e) {  
       e.printStackTrace();  
     }  
     return null;  
   }  
 }  
   
 public class MyClone {  
   public static void main(String[] args){  
     Dog dog = new Dog("dog",1);  
     System.out.println(dog.clone());  
   }  
 }  

It runs fine. Now take out the cloneable interface

The result is

 java.lang.CloneNotSupportedException: clone.Dog  
      at java.lang.Object.clone(Native Method)  
      at clone.Dog.clone(MyClone.java:22)  
      at clone.MyClone.main(MyClone.java:33)  
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
      at java.lang.reflect.Method.invoke(Method.java:498)  
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)  
 null  

This says clone() method does not work without the Cloneable interface.

Effective Java Item 34 Generic T multiple extend

   interface IOperation{}  
   enum Operation implements IOperation{...}    
   private static <T extends Enum<T> & IOperation> void test(Class<T> opSet){  
     for (IOperation op : opSet.getEnumConstants()){  
       System.out.println(op);  
     }  
   }  

Friday 8 April 2016

Effective Java Item 30,32,33 fromString(), EnumSet and EnumMap

Correct way to implement enum's fromString. We should always use EnumSet and EnumMap because they are faster than HashMap.


 import java.util.*;  
 enum Operation {  
   PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/");  
   private static final Map<String, Operation> stringToEnum = new HashMap<>();  
   static {  
     for (Operation op : values()){  
       stringToEnum.put(op.toString(), op);  
     }  
   }  
   private String symbol;  
   Operation(String symbol){  
     this.symbol = symbol;  
   }  
   public String toString(){  
     return symbol;  
   }  
   public static Operation fromString(String symbol){  
     return stringToEnum.get(symbol);  
   }  
 }  
 public class EnumSetMap {  
   public static void main(String[] args){  
     Set<Operation> enumSet = EnumSet.of(Operation.PLUS, Operation.MINUS);  
     Map<Operation, String> enumMap = new EnumMap<>(Operation.class);  
     System.out.println(Operation.fromString("+"));  
   }  
 }  

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

Friday 1 April 2016

Callback

Suppose you want to check the progress of some work. You can choose to query the status from the server regularly. But this solution sucks right? It's like asking taxi driver every 5 minutes how far away the destination is.

 class Server{  
   private int progress;  
   public int getProgress(){ return progress;  }  
   public void copy() {  
     while(progress <100){  
       try{  
         Thread.sleep(10);  
         progress++;  
       }catch(InterruptedException e){}  
     }  
   }  
 }  
 public class NoCallbackClient {  
   private Server server = new Server();  
   public void call() {  
     server.copy();  
   }  
   public static void main(String[] args) throws InterruptedException{  
     final NoCallbackClient client = new NoCallbackClient();  
     Runnable r = ()->client.call();  
     new Thread(r).start();  
     System.out.print("Progress: ");  
     while(true){  
       int progress = client.server.getProgress();  
       Thread.sleep(200);  
       if(progress >= 100){  
         break;  
       }else{  
         System.out.print(progress+"% ");  
       }  
     }  
   }  
 }  

So instead of keeping asking the taxi driver, you should say to the driver, "Hey, let me know when we are 25%, 50%, 75% into our journey".

Here is what callback does.

 package callback;  
 interface IClient{  
   void callback(int i);  
 }  
 class Server{  
   private IClient client;  
   public Server(IClient client) {  
     this.client = client;  
   }  
   public void copy() {  
     for(int i=0;i<=100;i++){  
       if (i%10 == 0) {  
         client.callback(i);  
       }  
     }  
   }  
 }  
 public class CallbackClient implements IClient{  
   public void call() {  
     new Server(this).copy();  
   }  
   @Override public void callback(int i) {  
     System.out.print(i+"% ");  
   }  
   public static void main(String[] args){  
     new CallbackClient().call();  
   }  
 }  

Reference: http://blog.csdn.net/yqj2065/article/details/39481255