一行的方法

出自《java puzzle》


現在該輪到你寫一些代碼了。下面的謎題每一個都可以用一個方法來解決,這些方法的方法體都只包含一行代碼。各就各位,預備,編碼!

• A.編寫一個方法,它接受一個包含元素的List,並返回一個新的List,它以相同的順序包含相同的元素,只不過它把第二次以及後續出現的重複元素都剔除了。例如,如果你傳遞了一個包含”spam”,”sausage”,”spam”,”spam”,”bacon”,”spam”,”tomato”和”spam”的列表,那麼你將得到一個包含”spam”,”sausage”,”bacon”,”tomato”的新列表。

• B.編寫一個方法,它接受一個由0個或多個由逗號分隔的標誌所組成的字符串,並返回一個表示這些標誌的字符串數組,數組中的元素的順序與這些標誌在輸入字符串中出現的順序相同。每一個逗號後面都可能會跟隨0個或多個空格字符,這個方法忽略它們。例如,如果你傳遞的字符串是”fear, surprise, ruthless efficiency, an almost fanatical devotion to the Pope, nice red uniforms”,那麼你得到的將是一個包含5個元素的字符串數組,這些元素是”fear”,”surprise”,”ruthless efficiency”,”an almost fanatical devotion to the Pope” 和 “nice red uniform”。

• C.假設你有一個多維數組,出於調試的目的,你想打印它。你不知道這個數組有多少級,以及在數組的每一級中所存儲的對象的類型。編寫一個方法,它可以向你顯示出在每一級上的所有元素。

• D.編寫一個方法,它接受兩個int數值,並在第一個數值與第二個數值以二進制補碼形式進行比較,具有更多的位被置位時,返回true。

A.衆所周知,你可以通過把集合(collection)中的元素置於一個Set中將集合中的所有重複元素都消除掉。在本謎題中,你還被要求要保持最初的集合中的元素順序。幸運的是,有一種Set的實現可以維護其元素被插入的順序,它提供的導入性能接近HashMap。它就是LinkedHashSet,它是在1.4版本的JDK中被添加到Java平臺中的。在內部,它是用一個鏈接列表來處理的,從而被實現爲一個散列表。它還有一個映射表版本可供你使用,以定製緩存。一旦你瞭解了LinkedHashSet,本謎題就很容易解決了。剩下唯一的關鍵就是你被要求要返回一個List,因此你必須用LinkedHashSet的內容來初始化一個List。把它們放到一塊,就形成了下面的解決方案:

static <E> List<E> withoutDuplicates(List<E> original) {
return new ArrayList<E>(new LinkedHashSet<E>(original));
}

B.在將字符串解析成標誌時,許多程序員都立刻想到了使用StringTokenizer。這是最不幸的事情,自1.4版本開始,由於正則表達式被添加到了Java平臺中(java.util.regex),StringTokenizer開始變得過時了。如果你試圖通過StringTokenizer來解決本謎題,那麼你很快就會意識到它不是非常適合。通過使用正則表達式,它就是小菜一碟。爲了在一行代碼中解決本謎題,我們要使用很方便的方法String.split,它接受一個描述標誌分界符的正則表達式作爲參數。如果你以前從來沒有使用過正則表達式,那麼它們看起來會顯得有一點神祕,但是它們驚人地強大,值得我們好好學習一下:
static String[ ] parse(String string) {
return string.split(",\\S*");
}

C.這是一個講究技巧的問題。你甚至不必去編寫一個方法。這個方法在5.0或之後的版本中已經提供了,它就是Arrays.deepToString。如果你傳遞給它一個對象引用的數組,它將返回一個精密的字符串表示。它可以處理嵌套數組,甚至可以處理循環引用,即一個數組元素直接或間接地引用了其嵌套外層的數組。事實上,5.0版本中的Arrays類提供了一整套的toString、equals和hashCode方法,使你能夠打印、比較或散列任何原始類型數組或對象引用數組的內容。

D.爲了在一行代碼中解決該謎題,你需要了解在5.0版本中添加到Java平臺中的一整套位操作方法。整數類型的包裝器類(Integer、Long、Short、Byte和Char)現在支持通用的位處理操作,包括highestOneBit、lowestOneBit、numberOfLeadingZeros、numberOfTrailingZeros、bitCount、rotateLeft、rotateRight、reverse、signum和reverseBytes。在本例中,你需要的是Integer.bitCount,它返回的是一個int數值中被置位的位數:
static Boolean hasMoreBitsSet(int i, int j) {
return (Integer.bitCount(i) > Integer.bitCount(j));
}

總之,Java平臺的每一個主版本都在其類庫中隱藏了一些寶藏。本謎題的所有4個部分都依賴於這樣的寶藏。每當該平臺發佈一個新版本時,你都應該研究就一下新特性和提高(new features and enhancements)頁面,這樣你就不會遺漏掉新版本提供的任何驚喜[Features-1.4, Features-5.0]。瞭解類庫中有些什麼可以節省你大量的時間和精力,並且可以提高你的程序的速度和質量。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章