counting sort
package test;
public class TestCountingSort {
/**
* @param target is the unsorted number array
*/
public static void countingSort(int[] target) {
// find max and min
int max = 0;
int min = 0;
for (int num : target) {
if ( num > max ) {
max = num;
}
if ( num < min ) {
min = num;
}
}
// add one into counter which index is the sorting number
int zeroOffset = 0 - min;
int counterSize = max + zeroOffset + 1;
int[] counter = new int[counterSize];
for (int num : target) {
counter[num + zeroOffset]++;
}
// put result from counter into target array
for ( int targetIdx = 0; targetIdx < target.length; targetIdx++ ) {
for ( int counterIdx = min + zeroOffset; counterIdx < counterSize; counterIdx++ ) {
if ( counter[counterIdx] > 0 ) {
target[targetIdx] = counterIdx - zeroOffset;
counter[counterIdx]--;
break;
}
}
}
// show result
for (int num : target) {
System.out.print(num + ", ");
}
}
public static void main(String[] args) {
countingSort(new int[]{-1,84,13,0,0,73,26,32,19,91,38});
}
}
Posted at 03:15上午 一月 29, 2010 by shooeugenesea in Java | 迴響[0]
打包不同環境設定檔的 build.xml
/ant/lib/jsp-api.jar /ant/lib/junit-4.4.jar /ant/lib/servlet-api.jar /src /test /web /config/yourconfigfolders1 /config/yourconfigfolders2 /config/yourconfigfolders3 ... /config/yourconfigfoldersN只要確定專案資料夾結構符合規定就可以使用這份 build.xml
clean : 清空 build 與 dist 資料夾 clean-dist-jarwar : clean 與 dist 後打包檔案到 dist 資料夾 clean-dist-test : clean 與 dist 後執行測試 clean-dist-test-jarwar : clean 與 dist 與 test 後打包檔案到 dist 資料夾注意這是在使用 target 的時候要帶參數, 目的就是要指定想使用哪一個設定檔.
ant clean-dist-jarwar -Dconfig=yourconfigfolders1想打包 /config/yourconfigfolders2, 就輸入
ant clean-dist-jarwar -Dconfig=yourconfigfolders2依此類推.
<?xml version="1.0" encoding="UTF-8"?>
<project name="myproject" default="default" basedir=".">
<description>Builds the project.</description>
<property name="project.name" value="myproject" />
<property name="dist" value="dist" />
<property name="build" value="build" />
<property name="build.version" value="1.0" />
<property name="lib" value="web/WEB-INF/lib" />
<property name="ant.lib" value="ant/lib" />
<property name="build.reports.tests" value="build/reports/tests" />
<property name="build.tests" value="build/tests" />
<property name="build.tests.classes" value="build/tests/classes" />
<property name="build.web" value="build/web" />
<property name="build.web.classes" value="${build.web}/WEB-INF/classes" />
<property name="build.web.lib" value="${build.web}/WEB-INF/lib" />
<property name="src.java" value="src" />
<property name="src.test" value="test" />
<property name="src.config" value="config/${config}" />
<property name="src.webapp" value="web" />
<property name="dist.manifest" value="dist/MANIFEST.MF" />
<property name="dist.mainclass" value="" />
<path id="build.classpath">
<fileset dir="${ant.lib}" includes="*.jar" />
<fileset dir="${lib}" includes="*.jar" />
</path>
<target name="clean">
<delete dir="${build}" />
<delete dir="${dist}" />
</target>
<target depends="clean" name="clean-dist">
<mkdir dir="${build.web.classes}" />
<mkdir dir="${build.tests.classes}"/>
<mkdir dir="${dist}" />
<javac destdir="${build.web.classes}"
srcdir="${src.java}"
classpathref="build.classpath"
source="1.5"
target="1.5"
encoding="UTF-8">
</javac>
<copy todir="${build.web.classes}">
<fileset dir="${src.java}">
<exclude name="**/*.java" />
<include name="**/*"/>
</fileset>
</copy>
<javac destdir="${build.tests.classes}"
srcdir="${src.test}"
classpathref="build.classpath"
source="1.5"
target="1.5"
encoding="UTF-8">
<classpath location="${build.web.classes}" />
</javac>
<copy todir="${build.tests.classes}">
<fileset dir="${src.test}">
<exclude name="**/*.java" />
<include name="**/*"/>
</fileset>
</copy>
<copy todir="${build.web.lib}">
<fileset dir="${lib}" />
</copy>
<copy todir="${build.web}">
<fileset dir="${src.webapp}" />
</copy>
</target>
<target name="clean-dist-test" depends="clean-dist">
<mkdir dir="${build.reports.tests}" />
<copy todir="${build.web.classes}">
<fileset dir="${src.config}" />
</copy>
<junit haltonfailure="false" showoutput="true">
<jvmarg value="-version:1.5.0" />
<classpath>
<pathelement path="${build.tests.classes}" />
<pathelement path="${build.web.classes}"/>
<path refid="build.classpath" />
</classpath>
<batchtest fork="yes" todir="${build.reports.tests}">
<fileset dir="${src.test}">
<include name="**/*"/>
</fileset>
<formatter type="xml" />
</batchtest>
</junit>
</target>
<target name="init-dist-manifest">
<copy todir="dist/lib">
<fileset dir="${lib}" includes="*.jar" />
</copy>
<path id="jar.classpath">
<fileset dir="dist/lib">
<include name="*.jar" />
</fileset>
</path>
<manifestclasspath property="jar.manifest.classpath" jarfile="dist/${project.name}.jar">
<classpath refid="jar.classpath" />
</manifestclasspath>
<manifest file="${dist.manifest}">
<attribute name="Class-Path" value="${jar.manifest.classpath}" />
<attribute name="Main-Class" value="${dist.mainclass}"/>
<attribute name="Implementation-Title" value="${project.name}"/>
<attribute name="Implementation-Version" value="${build.version}"/>
<attribute name="Implementation-Vendor" value="YourCompany Technology Corporation"/>
<attribute name="Implementation-Build" value="myproject-${build.version}-M201001240200"/>
</manifest>
</target>
<target depends="clean-dist-test,init-dist-manifest" name="clean-dist-test-jarwar">
<jar destfile="dist/${project.name}.jar" manifest="${dist.manifest}" >
<fileset dir="${build.web.classes}"/>
</jar>
<copy todir="${build.web.classes}">
<fileset dir="${src.config}" />
</copy>
<war destfile="${dist}/${project.name}.war">
<fileset dir="${build.web}" />
</war>
</target>
<target depends="clean-dist,init-dist-manifest" name="clean-dist-jarwar">
<jar destfile="dist/${project.name}.jar" manifest="${dist.manifest}" >
<fileset dir="${build.web.classes}"/>
</jar>
<copy todir="${build.web.classes}">
<fileset dir="${src.config}" />
</copy>
<war destfile="${dist}/${project.name}.war">
<fileset dir="${build.web}" />
</war>
</target>
</project>
Posted at 02:37上午 一月 24, 2010 by shooeugenesea in Others | 迴響[0]
C pointer to a function
#include <stdio.h>
void bubble( int numbers[], int length, int (*compare) (int, int) );
// 也可 void bubble( int numbers[], int length, int (*) (int, int) );
int ascending( int a, int b ) ;
int descending( int a, int b );
void swap( int *aPtr, int *bPtr );
void printAry( int ary[], int length );
void fillRandomNumbers( int numbers[], int length );
int main(void) {
int numbers[10];
fillRandomNumbers( numbers, 10 );
printAry( numbers, 10 );
printf("---1\n");
bubble( numbers, 10, ascending );
printAry( numbers, 10 );
printf("---2\n");
bubble( numbers, 10, descending );
printAry( numbers, 10 );
printf("---3\n");
getche();
return 0;
}
void printAry( int ary[], int length ) {
int i = 0;
for ( i = 0; i < length; i++ ) {
printf( " %d ", ary[i] );
}
}
void bubble( int numbers[], int length, int (*compare) (int, int) ) {
int pass = 0;
int count = 0;
for ( pass = 0; pass < length; pass++ ) {
for ( count = 0; count < length-1; count++ ) {
if ( (*compare)( numbers[count], numbers[count+1]) ) {
swap( &numbers[count], &numbers[count+1] );
}
}
}
}
void fillRandomNumbers( int numbers[], int length ) {
int i = 0;
for ( i = 0; i < length; i++ ) {
numbers[i] = rand() % 10;
}
}
void swap( int *aPtr, int *bPtr ) {
int tmp = *aPtr;
*aPtr = *bPtr;
*bPtr = tmp;
}
int ascending( int a, int b ) {
return a > b;
}
int descending( int a, int b ) {
return a < b;
}
Posted at 01:11上午 十一月 25, 2009 by shooeugenesea in C/C++ | 迴響[0]
codeline 的控制
專案通常會有三種環境: DEV / UAT / PROD.
為了讓每次的佈署與修改的 bug 都有好的版本管理方式, 我列一下一個需求進來該有怎樣的操作流程.
希望看官們能給點意見, 謝謝! :D
(這只是草稿, 希望以後可以適當的完整, 也不要太複雜好讓人容易記住).
- create branch for development
- create branch from trunk to /branches/DEV/
- develop in branch
- test in branch
- fix bugs in branch
- finish branch development
- merge to trunk
- create tag from trunk to /tags/DEV/
- merge branch to trunk
- test in trunk
- fix bugs in trunk
- finish trunk mergence
- deploy to UAT
- create tag from trunk to /tags/UAT/ before deploy to UAT
- deploy to UAT
- test in UAT
- fix bugs in UAT
- create branch from /tags/UAT/ to /branches/UAT
- fix bugs in /branches/UAT/
- test in /branches/UAT/
- finish fix bugs in /branches/UAT/
- create tag from trunk to /tags/UAT/
- merge from branch to trunk
- go to "deploy to UAT"
- finish UAT deployment
- deploy to PROD
- create tag from trunk to /tags/PROD/ before deploy to PROD
- deploy to PROD
- test in PROD
- fix bugs in PROD
- create branch from /tags/PROD/ to /branches/PROD/
- fix bugs in /branches/PROD/
- test in /branches/PROD/
- finish fix bugs in /branches/PROD
- create tag from trunk to /tags/PROD/
- merge from branch to trunk
- go to "deploy to PROD"
- finish PROD deployment
Posted at 10:44上午 十一月 18, 2009 by shooeugenesea in Others | 迴響[2]
C + bubbleSort + linearSearch + binarySearch
#include<stdio.h>
#define ARY_SIZE 20
#define RANDOM_RANGE 20
void bubbleSort(int ary[], int length);
void fillRandomNumber(int ary[], int length);
void printAry(int ary[], int length);
int linearSearch( int search, int ary[], int length );
int binarySearchRecursion( int searchNumber, int sortedAry[], int lowIdx, int highIdx );
int binarySearchLoop( int searchNumber, int sortedAry[], int lowIdx, int highIdx );
int main(void) {
int ary[ARY_SIZE];
fillRandomNumber( ary, ARY_SIZE );
printAry( ary, ARY_SIZE );
bubbleSort( ary, ARY_SIZE );
printAry( ary, ARY_SIZE );
int searchNumber = 5;
int searchIndex = linearSearch(searchNumber, ary, ARY_SIZE);
printf( " searched %d index = %d\n\n", searchNumber, searchIndex );
fillRandomNumber( ary, ARY_SIZE );
printAry( ary, ARY_SIZE );
bubbleSort( ary, ARY_SIZE );
printAry( ary, ARY_SIZE );
searchNumber = 1;
searchIndex = binarySearchRecursion(searchNumber, ary, 0, ARY_SIZE );
printf( " searched %d index = %d\n\n", searchNumber, searchIndex );
fillRandomNumber( ary, ARY_SIZE );
printAry( ary, ARY_SIZE );
bubbleSort( ary, ARY_SIZE );
printAry( ary, ARY_SIZE );
searchNumber = 7;
searchIndex = binarySearchLoop(searchNumber, ary, 0, ARY_SIZE );
printf( " searched %d index = %d\n\n", searchNumber, searchIndex );
getche();
return 0;
}
int binarySearchLoop( int searchNumber, int sortedAry[], int lowIdx, int highIdx ) {
while ( lowIdx <= highIdx ) {
printf( " ." );
int centerIdx = ( lowIdx + highIdx ) / 2;
if ( sortedAry[centerIdx] == searchNumber ) {
return centerIdx;
}
if ( (highIdx - lowIdx <= 1 )
&& searchNumber != sortedAry[highIdx]
&& searchNumber != sortedAry[lowIdx] ) {
return -1;
}
if ( searchNumber > sortedAry[centerIdx] ) {
lowIdx = centerIdx;
} else {
highIdx = centerIdx;
}
}
return -1;
}
int binarySearchRecursion( int searchNumber, int sortedAry[], int lowIdx, int highIdx ) {
printf(" .");
int centerIdx = ( lowIdx + highIdx ) / 2;
if ( sortedAry[centerIdx] == searchNumber ) {
return centerIdx;
}
if ( sortedAry[centerIdx] != searchNumber
&& (centerIdx == lowIdx || centerIdx == highIdx) ) {
return -1;
}
if ( sortedAry[centerIdx] > searchNumber ) {
return binarySearchRecursion( searchNumber, sortedAry, lowIdx, centerIdx );
} else if ( sortedAry[centerIdx] < searchNumber ) {
return binarySearchRecursion( searchNumber, sortedAry, centerIdx, highIdx );
}
return -1;
}
int linearSearch( int search, int ary[], int length ) {
int i = 0;
for ( i = 0; i < length; i++ ) {
printf( " ." );
if ( search == ary[i] ) {
return i;
}
}
return -1;
}
void printAry(int ary[], int length) {
int i = 0;
for ( i = 0; i < length; i++ ) {
printf( "%3d", i );
}
printf( "\n" );
for ( i = 0; i < length; i++ ) {
printf( "%3d", ary[i] );
}
printf( "\n" );
printf( "\n" );
}
void fillRandomNumber(int ary[], int length) {
int i = 0;
for ( i = 0; i < length; i++ ) {
ary[i] = rand() % RANDOM_RANGE;
}
}
void bubbleSort(int ary[], int length) {
int roundCnt = 0;
for ( roundCnt = 0; roundCnt < length; roundCnt++ ) {
int compareIdx = 0;
for ( compareIdx = 0; compareIdx < length; compareIdx++ ) {
if ( ary[compareIdx] > ary[compareIdx+1] ) {
int temp = ary[compareIdx];
ary[compareIdx] = ary[compareIdx+1];
ary[compareIdx+1] = temp;
}
}
}
}
Posted at 02:48上午 十一月 15, 2009 by shooeugenesea in C/C++ | 迴響[4]
adapter
public class UnknownSourcePrinter {
public void print(String text) {
System.out.println("print with printer without source code, print text = " + text);
}
}
MyPrintService.java
public class MyPrintService {
private UnknownSourcePrinter printer = new UnknownSourcePrinter();
public void print(String text) {
printer.print( text );
}
}
UserCode.java
public class UserCode {
public static void main(String[] args) {
MyPrintService service = new MyPrintService();
service.print( "my text" );
}
}
Posted at 02:43上午 十一月 15, 2009 by shooeugenesea in design pattern | 迴響[8]
[分享] 節錄版本控制與平行開發文章重點的投影片
今天在公司分享介紹一篇文章
Streamed Lines: Branching Patterns for Parallel Software Development
有做投影片節錄重點.
http://docs.google.com/present/view?id=dcsswcvv_5f65vrwfp
不過這篇文章好像蠻久的了, 而且也只是大概看一下, 如果有誤解或是該抓的重點沒抓到請提出來討論喔.
Posted at 11:26下午 十一月 06, 2009 by shooeugenesea in Others | 迴響[0]
簡單的推文到 twitter, plurk, facebook
因為客戶想要, 所以看一下客戶口中的"推文到 twitter, plurk, facebook"是怎麼回事.
根據客戶的描述文字, 目前猜測可能是以下的簡單功能.
facebook 的部份跟 twitter/plurk 不太一樣的地方是不知道怎麼顯示字串訊息
而且給的是網頁的位址, facebook 會自動去找那個網頁有什麼可以顯示的..
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<script type="text/javascript">
function sendToPlurk() {
var msg = document.getElementById('msg').value;
window.open('http://www.plurk.com/?qualifier=shares&status=' + msg );
}
function sendToTwitter() {
var msg = document.getElementById('msg').value;
window.open('http://twitter.com/home/?status=' + msg );
}
function sendToFacebook() {
var url = document.getElementById('url').value;
window.open('http://www.facebook.com/sharer.php?u=' + encodeURIComponent(url) );
}
</script>
</head>
<body>
<input type="text" size="100" id="msg" value="測試" /><br />
<a href="javascript:sendToPlurk()">
發訊息上 plurk
</a><br />
<a href="javascript:sendToTwitter()">
發訊息上 twitter
</a><br /><br /><br />
URL : <input type="text" size="100" id="url" value="http://www.youtube.com/watch?v=x6QA3m58DQw" /><br />
<a href="javascript:sendToFacebook()">
發訊息上 facebook
</a>
</body>
</html>
Posted at 01:03上午 十月 06, 2009 by shooeugenesea in Others | 迴響[0]
指定 package iterate 包含 jar 檔內所有 sub package 的 class
以前就好奇現在很多工具只要 annotation 就可以紀錄你有哪些 class 是註冊要做某事的行為怎麼實做.
也就是好奇要怎麼 iterate 所有的 class 進行操作呢?
今天看到 stripes 的 ResolverUtil.java 就有這種行為.
感覺像是這樣.
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
public class TestIterateClasses {
public static void main(String[] args) throws IOException, ClassNotFoundException {
TestIterateClasses test = new TestIterateClasses();
// 這裡指定的 package 不管是 source code 或 library 下的都可以把所有 class 顯示出來
test.test("org.apache.commons.pool.impl");
}
private void test(String javaPackageName) throws IOException {
String packageName = javaPackageName.replaceAll("\\.", "/");
// 這裡可以找到有指定 package 的 library 有哪些
Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(packageName);
while (urls.hasMoreElements()) {
String urlPath = urls.nextElement().getFile();
if ( urlPath.startsWith("file:") ) {
urlPath = urlPath.substring(5);
}
if ( urlPath.indexOf("!") > 0 ) {
urlPath = urlPath.substring(0, urlPath.indexOf("!"));
}
File file = new File(urlPath);
if ( file.isDirectory() ) {
iterateDirectory( packageName, file );
} else {
showClassInJarFile( file, packageName );
}
}
}
private void showClassInJarFile(File file, String packageName) throws IOException {
JarInputStream jarIs = new JarInputStream(new FileInputStream(file));
JarEntry entry = null;
while ( (entry = jarIs.getNextJarEntry()) != null ) {
// 還不確定這有沒有更快的方式, 不然其實是 iterate 所有的 package
if ( entry.getName().endsWith(".class")
&& entry.getName().indexOf(packageName) > -1 ) {
System.out.println(entry.getName());
}
}
}
private void iterateDirectory(String packageName, File directory) throws IOException {
File[] files = directory.listFiles();
for (File file : files) {
System.out.println("iterate directory:" + packageName + "/" + file.getName());
if ( file.isDirectory() ) {
iterateDirectory( packageName, file );
} else {
showClassInFileDirectory( file );
}
}
}
private void showClassInFileDirectory(File file) {
if ( file.getName().endsWith(".class") ) {
System.out.println(file);
}
}
}
Posted at 10:51上午 九月 19, 2009 by shooeugenesea in Java | 迴響[0]
做 immutable class 時讓 List 真的不能被改變
上次看到一篇文章寫得很不錯, 但是忘記網址了,
反正就是在說實做 immutable 要注意的地方.
今天剛好需要 immutable class, 有個 List 的變數, 我想讓它 immutable
這時候就是用 Collections#unmodifiableList,
要注意雖然 unmodifiableList 會產生一個不能 modify 的 List.
但傳進去的 List instance 卻還是可以被編輯,
所以仍然可以透過操作傳進去的物件改變內容, 這樣就不是 immutable 了.
所以要做 immutable 的 List 除了呼叫 unmodifiableList 以外還要用 ArrayList 包起來
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestCollections {
public static void main(String[] args) {
List<String> stringList = new ArrayList<String>();
stringList.add("A");
stringList.add("B");
stringList.add("C");
List<String> notReallyUnmodifiedList = Collections.unmodifiableList( stringList );
stringList.add("D");
try {
notReallyUnmodifiedList.add("Trigger exception");
} catch (Exception ex) {
System.out.println("Yes! You can't modify notReallyUnmodifiedList directly");
}
// will print ABCD
System.out.print("notReallyUnmodifiedList=");
for (String str : notReallyUnmodifiedList) {
System.out.print(str);
}
System.out.println();
List<String> reallyUnmodifiedList = Collections.unmodifiableList( new ArrayList<String>(stringList) );
stringList.add("E");
try {
reallyUnmodifiedList.add("Trigger exception");
} catch (Exception ex) {
System.out.println("Yes! You can't modify reallyUnmodifiedList directly");
}
// will print ABCD, not ABCDE
System.out.print("reallyUnmodifiedList=");
for (String str : reallyUnmodifiedList) {
System.out.print(str);
}
System.out.println();
}
}
Posted at 12:44上午 九月 13, 2009 by shooeugenesea in Java | 迴響[0]
decorator 適合自己設計的 class
如果用 adapter, 就比較適合用來處理 3rd party 的 library method.
只要我呼叫的是不會變動的 interface, 即使以後換 library 也不會有太大問題.
不過如果是 decorator, 因為要 override 所有的 method 然後用 delegate 到 class member 中.
那我就無法掌握我 decorate 的 method 以後不會變動.
比方說我要 decorate log4j 的 Logger 使能夠不用
private static final Logger logger = Logger.getLogger(ABC.class);
public void methodA() {
if ( logger.isInfoEnabled() ) {
logger.info("This is method a");
}
}
而只要
private static final Logger logger = new LoggerDecorator(Logger.getLogger(ABC.class));
public void methodA() {
logger.info("This is method a");
}
就可以有 isInfoEnabled 的效果.Posted at 08:34上午 七月 26, 2009 by shooeugenesea in design pattern | 迴響[0]
Study effective java 2nd note - 如果建構子的參數很多怎麼辦
如果有一個建構子的參數超過四個, 而且很多是 optional 的.
可用 Builder 建立參數物件.
參考作法是一個 immutable 的參數物件加上一個 mutable 的 inner builder class.
透過對 inner class 的呼叫設定想要的參數值後呼叫 build 建立一個 immutable 的參數物件.
package test;
import org.apache.commons.lang.builder.ToStringBuilder;
import test.PersonalInfo.PersonalInfoBuilder;
public class TestBuilder {
public static void main(String[] args) {
PersonalInfo info = new PersonalInfoBuilder()
.address("myaddress")
.age(5)
.cellphone("1234567890")
.firstName("my first name")
.lastName("my last name")
.phone("myphone")
.build();
System.out.println(info);
}
}
class PersonalInfo {
private final String firstName;
private final String lastName;
private final int age;
private final String address;
private final String phone;
private final String cellphone;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getAddress() {
return address;
}
public String getPhone() {
return phone;
}
public String getCellphone() {
return cellphone;
}
public static class PersonalInfoBuilder implements Builder<PersonalInfo> {
private String firstName = "";
private String lastName = "";
private int age = 0;
private String address = "";
private String phone = "";
private String cellphone = "";
public PersonalInfoBuilder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public PersonalInfoBuilder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public PersonalInfoBuilder age(int age) {
this.age = age;
return this;
}
public PersonalInfoBuilder address(String address) {
this.address = address;
return this;
}
public PersonalInfoBuilder phone(String phone) {
this.phone = phone;
return this;
}
public PersonalInfoBuilder cellphone(String cellphone) {
this.cellphone = cellphone;
return this;
}
@Override
public PersonalInfo build() {
return new PersonalInfo( this );
}
}
private PersonalInfo(PersonalInfoBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.address = builder.address;
this.phone = builder.phone;
this.cellphone = builder.cellphone;
}
}
interface Builder<T> {
T build();
}
Posted at 09:54下午 七月 24, 2009 by shooeugenesea in Java | 迴響[0]
double-checked locking 在JDK5後搭配 volatile 可實做 singleton
最近才知道原來 double-checked locking 其實是不能實作 singleton 的.
一開始看不太懂為什麼, 後來上網查之後才知道原因.
不過以前看書的時候有說到 double-checked locking 在 JDK5 之後能用.
那時候還不知道為什麼, 現在才知道...原來如此...
The "Double-Checked Locking is Broken" Declaration
Posted at 08:25下午 七月 12, 2009 by shooeugenesea in Java | 迴響[0]
factory
package test;
public class TestFactory {
public static void main(String[] args) {
new ProductUser(AProduct.FACTORY);
new ProductUser(BProduct.FACTORY);
}
}
class ProductUser {
private ProductFactory productFactory = null;
public ProductUser(ProductFactory productFactory) {
this.productFactory = productFactory;
}
public void doUse() {
productFactory.create().use();
}
}
class BProduct implements Product {
public static final ProductFactory FACTORY = new ProductFactory() {
public Product create() {
return new BProduct();
}
};
private BProduct() {
}
public void use() {
System.out.println("use BProduct");
}
}
class AProduct implements Product {
public static final ProductFactory FACTORY = new ProductFactory() {
public Product create() {
return new AProduct();
}
};
private AProduct() {
}
public void use() {
System.out.println("use AProduct");
}
}
interface ProductFactory {
public Product create();
}
interface Product {
public void use();
}
Posted at 12:31上午 七月 10, 2009 by shooeugenesea in design pattern | 迴響[0]
YUI 做 Yahoo suggest.
public class TestAutoCompleteServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("誰誰誰");
out.println("神神神");
out.println("一一一");
out.println("二二二");
out.println("aaa");
out.println("bbb");
out.println("ccc");
out.println("ddd");
out.println("eee");
out.println("fff");
out.println("ggg");
out.println("hhh");
} finally {
out.close();
}
}
// doGet, doPost call processRequest
}
TestAutoComplete.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/autocomplete/assets/skins/sam/autocomplete.css" />
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/connection/connection-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/animation/animation-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/datasource/datasource-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/autocomplete/autocomplete-min.js"></script>
<style type="text/css">
#myAutoComplete {
width:25em; /* set width here or else widget will expand to fit its container */
padding-bottom:2em;
}
</style>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body class="yui-skin-sam">
<div id="myAutoComplete">
<input id="myInput" type="text">
<div id="myContainer"></div>
</div>
<script type="text/javascript">
var test = function() {
// Use an XHRDataSource
var oDS = new YAHOO.util.XHRDataSource("${pageContext.request.contextPath}/TestAutoCompleteServlet");
// Set the responseType
oDS.responseType = YAHOO.util.XHRDataSource.TYPE_TEXT;
// Define the schema of the delimited results
oDS.responseSchema = {
recordDelim: "\n",
fieldDelim: "\t"
};
// Enable caching
oDS.maxCacheEntries = 5;
// Instantiate the AutoComplete
var oAC = new YAHOO.widget.AutoComplete("myInput", "myContainer", oDS);
oAC.formatResult = function(oResultData, sQuery, sResultMatch) {
var resultDataString = new String(oResultData);
var queryString = new String(sQuery);
var minusString = resultDataString.substr(queryString.length, resultDataString.length);
var hasMatch = resultDataString.indexOf(queryString) > -1;
if ( hasMatch ) {
return '<font color=orange>' + queryString + '</font>' + minusString;
} else {
return resultDataString;
}
};
return {
oDS: oDS,
oAC: oAC
};
}();
</script>
</body>
</html>
Posted at 12:14上午 七月 07, 2009 by shooeugenesea in JavaScript | 迴響[0]