程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java謎題選 - II

Java謎題選 - II

編輯:關於JAVA

題目2:關於Sets的更多Fun。

對了,這個題目表面上看也是關於Sets的...

程序

import java.net.*;
public class UrlSet {
  private static final String[] URL_NAMES = {
    "http://javapuzzlers.com",
    "http://apache2-snort.skybar.dreamhost.com",
    "http://www.google.com",
    "http://javapuzzlers.com",
    "http://findbugs.sourceforge.net",
    "http://www.bianceng.cn"
   };
  public static void main (string[] args)
            throws MalformedURLException {
      Set<URL> favorites = new HashSet<URL>();
      for (String urlName : URL_NAMES)
          favorites.add(new URL(urlName));
      System.out.println(favorites.size());
  }
}

答案

(a) 4

(b) 5

(c) 6

(d) None of the above

譯者序:

因為最近忙,這個第二集的答案出得太晚了點,希望大家見諒。

另:程序中的一行忘記了括號,Set<URL> favorites = new HashSet<URL>(); 我已經加上了,多謝讀者的細心。

謎題一之答案,分析過程,以及經驗教訓

答案

(d) None of the above

分析過程

如果運行此程序所在的機器與互聯網相接,那麼答案將是(a) 4。為什麼呢?因為URL接口的equals和hashCode方法徹底搞錯了。

"http://javapuzzlers.com"和"http://apache2-snort.skybar.dreamhost.com",這兩個完全不同的網址,解析成的IP地址竟是完全相同的!(譯者注:寄存這兩個不同網址的web服務器顯然只有一個,用的是以名稱為基礎的共享IP網絡寄存技術,這顯然是出題者有意為之,即所謂的Virtual Host)

根據URL類的技術文檔,兩個URL對象將被認為相等,如果以下條件得到滿足:

使用同樣的通信協議,引用相當的寄存服務器,使用同樣的端口,同樣的文件或同樣的一部分文件。

兩個寄存服務器被認為是相等的,如果兩個名稱被解析成同一個IP地址,或者兩個名稱都不可被解析,或者兩個名稱同為空(null)。

因此,如果運行此程序所在的機器不與互聯網相接,得到的結果將是1,應為所有名稱都不可被解析。這個題的答案因此是(d) None of the above。不同網絡環境下的運行,就有不同的結果,這實在是比較糟糕的。

URL類的equals方法是不支持Virtual Host(虛擬寄存)功能的。93年URL類被加進java平台時,基本是沒有虛擬寄存這個技術的。

經驗教訓

URL類有bug,不要使用URL,應該使用URI類。

URI類的equals方法只會進行字符的比較。程序改成Set<URI> favorites = new HashSet<URI>(); 打印出來的結果就是5了,因為有兩個"http://javapuzzlers.com"的緣故。

同時,favorites.add(new URL(urlName))這行程序也要改成favorites.add(URI.create(uriname));

注意這裡用的是更好的靜態工廠的模式,而不是一般的創建,這也是URI所不同於URL的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved