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));
}
}
}
Friday, 8 April 2016
Effective Java Item 30: Strategy enum pattern
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();
}
}
Subscribe to:
Posts (Atom)
