現(xiàn)在該輪到你寫一些代碼了。下面的謎題每一個(gè)都可以用一個(gè)方法來(lái)解決,這些方法的方法體都只包含一行代碼。各就各位,預(yù)備,編碼!
A.編寫一個(gè)方法,它接受一個(gè)包含元素的List,并返回一個(gè)新的List,它以相同的順序包含相同的元素,只不過(guò)它把第二次以及后續(xù)出現(xiàn)的重復(fù)元素都剔除了。例如,如果你傳遞了一個(gè)包含”spam”,”sausage”,”spam”,”spam”,”bacon”,”spam”,”tomato”和”spam”的列表,那么你將得到一個(gè)包含”spam”,”sausage”,”bacon”,”tomato”的新列表。
B.編寫一個(gè)方法,它接受一個(gè)由0個(gè)或多個(gè)由逗號(hào)分隔的標(biāo)志所組成的字符串,并返回一個(gè)表示這些標(biāo)志的字符串?dāng)?shù)組,數(shù)組中的元素的順序與這些標(biāo)志在輸入字符串中出現(xiàn)的順序相同。每一個(gè)逗號(hào)后面都可能會(huì)跟隨0個(gè)或多個(gè)空格字符,這個(gè)方法忽略它們。例如,如果你傳遞的字符串是”fear, surprise, ruthless efficiency, an almost fanatical devotion to the Pope, nice red uniforms”,那么你得到的將是一個(gè)包含5個(gè)元素的字符串?dāng)?shù)組,這些元素是”fear”,”surprise”,”ruthless efficiency”,”an almost fanatical devotion to the Pope” 和 “nice red uniform”。
C.假設(shè)你有一個(gè)多維數(shù)組,出于調(diào)試的目的,你想打印它。你不知道這個(gè)數(shù)組有多少級(jí),以及在數(shù)組的每一級(jí)中所存儲(chǔ)的對(duì)象的類型。編寫一個(gè)方法,它可以向你顯示出在每一級(jí)上的所有元素。
D.編寫一個(gè)方法,它接受兩個(gè)int數(shù)值,并在第一個(gè)數(shù)值與第二個(gè)數(shù)值以二進(jìn)制補(bǔ)碼形式進(jìn)行比較,具有更多的位被置位時(shí),返回true。
A.眾所周知,你可以通過(guò)把集合(collection)中的元素置于一個(gè)Set中將集合中的所有重復(fù)元素都消除掉。在本謎題中,你還被要求要保持最初的集合中的元素順序。幸運(yùn)的是,有一種Set的實(shí)現(xiàn)可以維護(hù)其元素被插入的順序,它提供的導(dǎo)入性能接近HashMap。它就是LinkedHashSet,它是在1.4版本的JDK中被添加到Java平臺(tái)中的。在內(nèi)部,它是用一個(gè)鏈接列表來(lái)處理的,從而被實(shí)現(xiàn)為一個(gè)散列表。它還有一個(gè)映射表版本可供你使用,以定制緩存。一旦你了解了LinkedHashSet,本謎題就很容易解決了。剩下的關(guān)鍵就是你被要求要返回一個(gè)List,因此你必須用LinkedHashSet的內(nèi)容來(lái)初始化一個(gè)List。把它們放到一塊,就形成了下面的解決方案:
static List withoutDuplicates(List original) {
return new ArrayList(new LinkedHashSet(original));
}
B.在將字符串解析成標(biāo)志時(shí),許多程序員都立刻想到了使用StringTokenizer。這是最不幸的事情,自1.4版本開(kāi)始,由于正則表達(dá)式被添加到了Java平臺(tái)中(java.util.regex),StringTokenizer開(kāi)始變得過(guò)時(shí)了。如果你試圖通過(guò)StringTokenizer來(lái)解決本謎題,那么你很快就會(huì)意識(shí)到它不是非常適合。通過(guò)使用正則表達(dá)式,它就是小菜一碟。為了在一行代碼中解決本謎題,我們要使用很方便的方法String.split,它接受一個(gè)描述標(biāo)志分界符的正則表達(dá)式作為參數(shù)。如果你以前從來(lái)沒(méi)有使用過(guò)正則表達(dá)式,那么它們看起來(lái)會(huì)顯得有一點(diǎn)神秘,但是它們驚人地強(qiáng)大,值得我們好好學(xué)習(xí)一下:
static String[ ] parse(String string) {
return string.split(",\\S*");
}
C.這是一個(gè)講究技巧的問(wèn)題。你甚至不必去編寫一個(gè)方法。這個(gè)方法在5.0或之后的版本中已經(jīng)提供了,它就是Arrays.deepToString。如果你傳遞給它一個(gè)對(duì)象引用的數(shù)組,它將返回一個(gè)精密的字符串表示。它可以處理嵌套數(shù)組,甚至可以處理循環(huán)引用,即一個(gè)數(shù)組元素直接或間接地引用了其嵌套外層的數(shù)組。事實(shí)上,5.0版本中的Arrays類提供了一整套的toString、equals和hashCode方法,使你能夠打印、比較或散列任何原始類型數(shù)組或?qū)ο笠脭?shù)組的內(nèi)容。
D.為了在一行代碼中解決該謎題,你需要了解在5.0版本中添加到Java平臺(tái)中的一整套位操作方法。整數(shù)類型的包裝器類(Integer、Long、Short、Byte和Char)現(xiàn)在支持通用的位處理操作,包括highestOneBit、lowestOneBit、numberOfLeadingZeros、numberOfTrailingZeros、bitCount、rotateLeft、rotateRight、reverse、signum和reverseBytes。在本例中,你需要的是Integer.bitCount,它返回的是一個(gè)int數(shù)值中被置位的位數(shù):
static Boolean hasMoreBitsSet(int i, int j) {
return (Integer.bitCount(i) > Integer.bitCount(j));
}
總之,Java平臺(tái)的每一個(gè)主版本都在其類庫(kù)中隱藏了一些寶藏。本謎題的所有4個(gè)部分都依賴于這樣的寶藏。每當(dāng)該平臺(tái)發(fā)布一個(gè)新版本時(shí),你都應(yīng)該研究就一下新特性和提高(new features and enhancements)頁(yè)面,這樣你就不會(huì)遺漏掉新版本提供的任何驚喜[Features-1.4, Features-5.0]。了解類庫(kù)中有些什么可以節(jié)省你大量的時(shí)間和精力,并且可以提高你的程序的速度和質(zhì)量。
A.編寫一個(gè)方法,它接受一個(gè)包含元素的List,并返回一個(gè)新的List,它以相同的順序包含相同的元素,只不過(guò)它把第二次以及后續(xù)出現(xiàn)的重復(fù)元素都剔除了。例如,如果你傳遞了一個(gè)包含”spam”,”sausage”,”spam”,”spam”,”bacon”,”spam”,”tomato”和”spam”的列表,那么你將得到一個(gè)包含”spam”,”sausage”,”bacon”,”tomato”的新列表。
B.編寫一個(gè)方法,它接受一個(gè)由0個(gè)或多個(gè)由逗號(hào)分隔的標(biāo)志所組成的字符串,并返回一個(gè)表示這些標(biāo)志的字符串?dāng)?shù)組,數(shù)組中的元素的順序與這些標(biāo)志在輸入字符串中出現(xiàn)的順序相同。每一個(gè)逗號(hào)后面都可能會(huì)跟隨0個(gè)或多個(gè)空格字符,這個(gè)方法忽略它們。例如,如果你傳遞的字符串是”fear, surprise, ruthless efficiency, an almost fanatical devotion to the Pope, nice red uniforms”,那么你得到的將是一個(gè)包含5個(gè)元素的字符串?dāng)?shù)組,這些元素是”fear”,”surprise”,”ruthless efficiency”,”an almost fanatical devotion to the Pope” 和 “nice red uniform”。
C.假設(shè)你有一個(gè)多維數(shù)組,出于調(diào)試的目的,你想打印它。你不知道這個(gè)數(shù)組有多少級(jí),以及在數(shù)組的每一級(jí)中所存儲(chǔ)的對(duì)象的類型。編寫一個(gè)方法,它可以向你顯示出在每一級(jí)上的所有元素。
D.編寫一個(gè)方法,它接受兩個(gè)int數(shù)值,并在第一個(gè)數(shù)值與第二個(gè)數(shù)值以二進(jìn)制補(bǔ)碼形式進(jìn)行比較,具有更多的位被置位時(shí),返回true。
A.眾所周知,你可以通過(guò)把集合(collection)中的元素置于一個(gè)Set中將集合中的所有重復(fù)元素都消除掉。在本謎題中,你還被要求要保持最初的集合中的元素順序。幸運(yùn)的是,有一種Set的實(shí)現(xiàn)可以維護(hù)其元素被插入的順序,它提供的導(dǎo)入性能接近HashMap。它就是LinkedHashSet,它是在1.4版本的JDK中被添加到Java平臺(tái)中的。在內(nèi)部,它是用一個(gè)鏈接列表來(lái)處理的,從而被實(shí)現(xiàn)為一個(gè)散列表。它還有一個(gè)映射表版本可供你使用,以定制緩存。一旦你了解了LinkedHashSet,本謎題就很容易解決了。剩下的關(guān)鍵就是你被要求要返回一個(gè)List,因此你必須用LinkedHashSet的內(nèi)容來(lái)初始化一個(gè)List。把它們放到一塊,就形成了下面的解決方案:
static List withoutDuplicates(List original) {
return new ArrayList(new LinkedHashSet(original));
}
B.在將字符串解析成標(biāo)志時(shí),許多程序員都立刻想到了使用StringTokenizer。這是最不幸的事情,自1.4版本開(kāi)始,由于正則表達(dá)式被添加到了Java平臺(tái)中(java.util.regex),StringTokenizer開(kāi)始變得過(guò)時(shí)了。如果你試圖通過(guò)StringTokenizer來(lái)解決本謎題,那么你很快就會(huì)意識(shí)到它不是非常適合。通過(guò)使用正則表達(dá)式,它就是小菜一碟。為了在一行代碼中解決本謎題,我們要使用很方便的方法String.split,它接受一個(gè)描述標(biāo)志分界符的正則表達(dá)式作為參數(shù)。如果你以前從來(lái)沒(méi)有使用過(guò)正則表達(dá)式,那么它們看起來(lái)會(huì)顯得有一點(diǎn)神秘,但是它們驚人地強(qiáng)大,值得我們好好學(xué)習(xí)一下:
static String[ ] parse(String string) {
return string.split(",\\S*");
}
C.這是一個(gè)講究技巧的問(wèn)題。你甚至不必去編寫一個(gè)方法。這個(gè)方法在5.0或之后的版本中已經(jīng)提供了,它就是Arrays.deepToString。如果你傳遞給它一個(gè)對(duì)象引用的數(shù)組,它將返回一個(gè)精密的字符串表示。它可以處理嵌套數(shù)組,甚至可以處理循環(huán)引用,即一個(gè)數(shù)組元素直接或間接地引用了其嵌套外層的數(shù)組。事實(shí)上,5.0版本中的Arrays類提供了一整套的toString、equals和hashCode方法,使你能夠打印、比較或散列任何原始類型數(shù)組或?qū)ο笠脭?shù)組的內(nèi)容。
D.為了在一行代碼中解決該謎題,你需要了解在5.0版本中添加到Java平臺(tái)中的一整套位操作方法。整數(shù)類型的包裝器類(Integer、Long、Short、Byte和Char)現(xiàn)在支持通用的位處理操作,包括highestOneBit、lowestOneBit、numberOfLeadingZeros、numberOfTrailingZeros、bitCount、rotateLeft、rotateRight、reverse、signum和reverseBytes。在本例中,你需要的是Integer.bitCount,它返回的是一個(gè)int數(shù)值中被置位的位數(shù):
static Boolean hasMoreBitsSet(int i, int j) {
return (Integer.bitCount(i) > Integer.bitCount(j));
}
總之,Java平臺(tái)的每一個(gè)主版本都在其類庫(kù)中隱藏了一些寶藏。本謎題的所有4個(gè)部分都依賴于這樣的寶藏。每當(dāng)該平臺(tái)發(fā)布一個(gè)新版本時(shí),你都應(yīng)該研究就一下新特性和提高(new features and enhancements)頁(yè)面,這樣你就不會(huì)遺漏掉新版本提供的任何驚喜[Features-1.4, Features-5.0]。了解類庫(kù)中有些什么可以節(jié)省你大量的時(shí)間和精力,并且可以提高你的程序的速度和質(zhì)量。