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;
}
}
Wednesday, 20 April 2016
Effective Java Item 78: Serialization proxy
Tuesday, 19 April 2016
Effective Java Item 71: Lazy initialization, holder class, double checking
static field uses holder class
instance field uses double check
if you don't mind re-creating instance again, You can use single check
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
Throws ConcurrentModificationException
ConcurrentHashMap never throws ConcurrentModificationException
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
Found duplicates
Correct implementation using synchronized
Correct implementation using AtomicLong
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
Example 2
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
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...
The result is
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.
It runs fine. Now take out the cloneable interface
The result is
This says clone() method does not work without the Cloneable interface.
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 super T>
What's the benefit of using Comparable<? super T>?
The code below compiles fine.
max1() doesn't compile any more. Clearly, Comparable<? super T> is more flexible.
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
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]
First attempt, find the 852 tag datafield, under that datafield, find all subfields, use collect to transform to a List
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.
If we just to want to print the text, we can take advantage of the asterisk operator.
Reference: Processing XML
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")
A customer lock can prevent reentrant. Now the thread calling outer() will be blocked at lock.lock() inside the inner() method.
Reference: Locks in Java
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.
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.
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.
Reference: http://blog.csdn.net/yqj2065/article/details/39481255
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
Subscribe to:
Posts (Atom)