Amazon Ads

2012年10月30日 星期二

Java String 的「==」和「equals」

今天同事問了一個Java String比較的問題,讓我想起剛學Java時,也有的相同疑惑!

在Java中,字串是使用String類別來建構,請參考Java Gossip: String 類別一個字串物件一旦被配置,它的內容就是固定不可變的(immutable),也就是說,當指定了兩個String變數後,他在記憶體中,是兩個由兩個不同的記憶位置,指向不同的記憶體區塊。
如:
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println("s3 == s4 ? " + (s3 == s4)); //印出false
System.out.println("s3 equals s4 ? " + (s3.equals(s4)));  //印出true
由上例,可以知道:若要比對字串內容是不是相等,要使用equals,來看看String類別中,equals方法的實作:
    /**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
       if (this == anObject) {
           return true;
       }
       if (anObject instanceof String) {
           String anotherString = (String)anObject;
           int n = count;
           if (n == anotherString.count) {
               char v1[] = value;
               char v2[] = anotherString.value;
               int i = offset;
               int j = anotherString.offset;
               while (n-- != 0) {
                   if (v1[i++] != v2[j++])
                       return false;
               }
               return true;
           }
       }
       return false;
    }
那你是否會問,用「==」去比較兩個String變數,是什麼意思?其實,就是去看這兩個變數所指向的記憶體位置是否相同。有興趣的可以參閱http://www3.ntu.edu.sg/home/ehchua/programming/java/J3d_String.html,這裡對String有更進一步的說明。

另外,值得一提的是,若你在同一程式區塊中,不用new的方式,而是直接用""的方式設定字串變數的話,用「==」是會回傳true的,如:
public static void main(String[] argv){
 String s1 = "Hello";
 String s2 = "Hello";
 String s0 = get();
 System.out.println("s1 == s2 ? " + (s1 == s2));//印出true
 System.out.println("s0 == s1 ? " + (s0 == s1));//印出true
        System.out.println("s0 == s2 ? " + (s0 == s2));//印出true
}

private static String get(){
 return "Hello";
}

這是Java為String設計的一個特別叫「string common pool」的機制,在上列的網頁中有說明,主要是對常用的字串保留記憶體空間,來節省使用的空間,在上列中,對於"Hello"字串,會在記憶體中產生一個String物件,讓s1、s2、s0都指向它,所以用「==」去比較時,都會回傳true。

2012年10月25日 星期四

好用的MongoDB Eclipse GUI外掛-MonjaDB


MonjaDB是一套MongoDB客戶端的GUI工具,可以直接裝在Eclipse中。


前往eclipse marketplace


點選綠色箭頭,複製紅框中的網址。


開啟Eclipse,點選「Help」、「Install New Software...」,將上列網址加入新增的Repository。之後勾選做安裝,再重開Eclipse。


Eclipse重新開啟後,點按選單列的「Windows」、「Open Perspective」,就可以看到MonjaDB的選項。


開啟的UI如下所示,在左上方的空白處按滑鼠右鍵,就可以新增MongoDB連線。



2012年10月24日 星期三

2012Java認證日來囉!

免費,而且參加三、四次的感想,我覺得內容都還不錯!有興趣的請參考:
http://www.uuu.com.tw/public/content/edm/eDM0927/eDM.html

【筆記】在Ubuntu中,Java執行Shell Script,並runtime傳入參數

程式碼如下:


其中:

使用ProcessBuilder建構子(1.5後才有的,請參考:http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html)設定要執行的script和要傳入的參數:
ProcessBuilder pb = new ProcessBuilder("./myscript.sh", "sampleParam1"); 
//這在shell script中,可以用$1去接此參數sampleParam1
可以使用ProcessBuilder中的environment方法,來設定或取得執行中的環境變數,使用ProcessBuilder中的directory方法來設定工作目錄,就是要執行script的目錄。

範例script如下:



執行java程式後,可以看到在執行工作目錄產生了a.txt,如下:



檢視a.txt內容,可以看到java中設定的參數傳入到sciprt中,並輸出到a.txt中:

2012年10月23日 星期二

【解決】Ubuntu解決Eclipse Subversion Incompatible JavaHL library loaded. 1.7.x or later required.的問題

有時裝在Eclipse上的Subversion版本比較高,會出現下列的錯誤:「Incompatible JavaHL library loaded. 1.7.x or later required」。
這是因為在你電腦上,Subclipse需要JavaHL版本太舊了,請參考:http://subclipse.tigris.org/wiki/JavaHL

解法:

  • 前往http://www.collab.net/downloads/subversion#tab-1下載Subversion 1.7.7 (Linux x86_64)到本機後,直接用解壓縮程式開啟,將其中的CollabNet_Subversion的資料夾解壓縮到/opt下。
  • 開啟Eclipse的eclipse.ini,在-vmargs這一行下面加上「-Djava.library.path=/opt/CollabNet_Subversion/lib」,重新開啟Eclipse就好。