walterwing
日歷
<
2008年11月
>
日
一
二
三
四
五
六
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
統(tǒng)計
隨筆 - 12
文章 - 1
評論 - 7
引用 - 0
導(dǎo)航
BlogJava
首頁
發(fā)新隨筆
發(fā)新文章
聯(lián)系
聚合
管理
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
(1)
給我留言
查看公開留言
查看私人留言
隨筆分類
Java基礎(chǔ)(9)
(rss)
大千世界(2)
(rss)
隨筆檔案
2009年2月 (2)
2008年11月 (2)
2008年10月 (2)
2008年7月 (7)
搜索
最新評論
1.?re: java線程基本知識小結(jié)
very good
--very good
2.?re: (轉(zhuǎn)載)高科技公司的搖籃 — 斯坦福大學(xué)[未登錄]
@與你同飛
面包會有的:) 雖然有生之年可能看不到國內(nèi)大學(xué)也能躋身世界前列,但我們也要對自己有信心,哪怕路途再遙遠,也要努力向前
--Wing
3.?re: (轉(zhuǎn)載)高科技公司的搖籃 — 斯坦福大學(xué)
差距啊,差距,什么是差距?這就是差距!
--與你同飛
4.?re: 一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……
評論內(nèi)容較長,點擊標題查看
--This is Wing
5.?re: 一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……
請講講
removeEntryForKey
這段代碼吧,
我是新手,看不懂。
--sclsch
閱讀排行榜
1.?對象的序列化和反序列化(轉(zhuǎn)載+原創(chuàng))(4893)
2.?java線程基本知識小結(jié)(3357)
3.?(轉(zhuǎn)載)高科技公司的搖籃 — 斯坦福大學(xué)(652)
4.?一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……(644)
5.?The Collections Framework (摘要)- Part 4(563)
評論排行榜
1.?一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……(3)
2.?(轉(zhuǎn)載)高科技公司的搖籃 — 斯坦福大學(xué)(2)
3.?java線程基本知識小結(jié)(1)
4.?靜態(tài)Proxy與動態(tài)Proxy用法淺析(0)
5.?The Collections Framework (摘要)- Part 4(0)
一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……
題目:
public
class
SetSize
{
public
static
void
main(string[] args)
{
Set
<
Short
>
set
=
new
HashSet
<
Short
>
();
for
(
short
i
=
0
; i
<
10
; i
++
)
{
set.add(i);
set.remove(i
-
1
);
}
System.out.println(set.size());
}
}
上面代碼輸出結(jié)果為10,為什么?
題目乍一看很簡單,不就是一個HashSet么,但看完了題目又覺得困惑:對啊,怎么會是10?真難為自己還特意花了一些時間學(xué)習(xí)Java的Collection Framework,居然連這么小的一個題目都吃不透,汗顏啊……
看了半天,沒有思路,跳過去做其他題,待到收卷前10分鐘,不甘心,再回過頭來看這道題。發(fā)現(xiàn)一個值得懷疑的地方:Set<Short> set = ……
為什么要特意設(shè)定是Short?再看到下面的i - 1,馬上感覺到似乎和類型轉(zhuǎn)換有關(guān)。
目前可以肯定的是:
1. set存儲的元素是Short類型
2. 調(diào)用remove方法時,i - 1會自動轉(zhuǎn)型為int,也就是說,傳給remove方法的參數(shù)是一個int值
接下來呢?int值會被自動包裝成Integer還是Short?對Java的泛型和Auto-Boxing不是很了解,于是在這犯迷糊了,只好將目前的思路草草寫了幾筆,交卷……
作為一名后知后覺的Java愛好者,自然不能放過這么有意思的題目。如是回來之后,上機親自試驗,輸入試題程序,出來的結(jié)果果然是10(嗯,沒騙我……)。然后驗證自己的猜測:將Set<Short>改為Set<Integer>,輸出結(jié)果……1!
看來我還是有一定的嗅覺的……
接下來就是探索原因了
首先驗證一下i - 1得到的結(jié)果會不會有錯:-1,0,1,……8。嗯,是對的
然后驗證一下每次remove之后有沒有真的remove掉指定的值……發(fā)現(xiàn)沒有。
苦思……
經(jīng)一位精研C++的同學(xué)提醒:是不是因為存的是short,但刪的是int,所以不能刪?
試驗一下:
short
temp
=
1
;
Short s
=
new
Short(temp);
//
不能是new Short(1),否則編譯出錯
Integer i
=
new
Integer(
1
);
System.out.println(s.equals(i));
輸出結(jié)果……false!看來終于找到真正的原因了。
查看一下Short.equals()方法的源代碼:
public
boolean
equals(Object obj)
{
if
(obj
instanceof
Short)
{
return
value
==
((Short)obj).shortValue();
}
return
false
;
}
ft……居然不是同一類型的就無視……這跟胸懷廣闊的集合框架背道而馳啊……當(dāng)然,這是我的錯
目前可以大致推斷:因為set中存入的是值為0~9的Short型對象,而每次刪除是是要求刪除值為-1~8的Integer型對象,但值相同的Short與Integer看來并不“相等”,所以無法刪除。
那就看一下HashSet的remove方法究竟干了些什么
public
boolean
remove(Object o)
{
return
map.remove(o)
==
PRESENT;
}
public
V remove(Object key)
{
Entry
<
K,V
>
e
=
removeEntryForKey(key);
return
(e
==
null
?
null
: e.value);
}
終于到主菜了……
/** */
/**
* Removes and returns the entry associated with the specified key
* in the HashMap. Returns null if the HashMap contains no mapping
* for this key.
*/
final
Entry
<
K,V
>
removeEntryForKey(Object key)
{
int
hash
=
(key
==
null
)
?
0
: hash(key.hashCode());
int
i
=
indexFor(hash, table.length);
Entry
<
K,V
>
prev
=
table[i];
Entry
<
K,V
>
e
=
prev;
while
(e
!=
null
)
{
Entry
<
K,V
>
next
=
e.next;
Object k;
if
(e.hash
==
hash
&&
((k
=
e.key)
==
key
||
(key
!=
null
&&
key.equals(k))))
{
modCount
++
;
size
--
;
if
(prev
==
e)
table[i]
=
next;
else
prev.next
=
next;
e.recordRemoval(
this
);
return
e;
}
prev
=
e;
e
=
next;
}
return
e;
}
代碼就不用解釋了,大家都看得懂。
HashSet里面刪除一個元素時,首先要根據(jù)傳進來對象的hash值從hash table中找到對應(yīng)的“Entry”,當(dāng)然,難免會有碰撞的情況,這時需要遍歷一下來找到真正需要刪除的對象。一直到這一步,Short和Integer的差異還沒有體現(xiàn)出來,因為它們返回的hash值是相同的,但當(dāng)執(zhí)行key.equals(k)的時候,就“不相等”了,因此找不到要刪除的元素,刪除失敗
小小的一道題,囊括了Java方方面面的細節(jié),果然語言這個東西博大精深啊,有時候你以為自己很明白了,但隨便揪出一個細節(jié)來就足以打到你……
大家還是好好學(xué)習(xí),天天向上吧
posted on 2008-11-02 19:52
This is Wing
閱讀(644)
評論(3)
編輯
收藏
所屬分類:
Java基礎(chǔ)
評論:
#
re: 一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……
sclsch
Posted @ 2008-11-04 09:23
講得不錯啊。學(xué)習(xí)了。
回復(fù)
更多評論
#
re: 一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……
sclsch
Posted @ 2008-11-04 09:47
請講講
removeEntryForKey
這段代碼吧,
我是新手,看不懂。
回復(fù)
更多評論
#
re: 一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……
This is Wing
Posted @ 2008-11-04 16:02
@sclsch
其實我建議你先去回顧一下數(shù)據(jù)結(jié)構(gòu)中的哈希表,比如怎么存儲,怎么解決碰撞,怎么查找……這些都是很基礎(chǔ)的東西,很多地方都要用到。相信當(dāng)你搞懂哈希表之后,自然也就知道上面的代碼是在做什么了
回復(fù)
更多評論
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發(fā)表評論。
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關(guān)文章:
垃圾回收(轉(zhuǎn)載)
一道小而精巧的筆試題——Set、equals、類型轉(zhuǎn)換……
對象的序列化和反序列化(轉(zhuǎn)載+原創(chuàng))
java線程基本知識小結(jié)
靜態(tài)Proxy與動態(tài)Proxy用法淺析
The Collections Framework (摘要)- Part 4
The Collections Framework (摘要)- Part 3
The Collections Framework (摘要)- Part 2
The Collections Framework (摘要)- Part 1
Copyright © This is Wing
Powered by:
博客園
模板提供:
滬江博客
主站蜘蛛池模板:
a级毛片毛片免费观看永久
|
在线综合亚洲欧洲综合网站
|
乱淫片免费影院观看
|
在线观看AV片永久免费
|
亚洲免费视频网址
|
免费观看激色视频网站(性色)
|
精品亚洲成a人片在线观看
|
久久午夜无码免费
|
亚洲国产女人aaa毛片在线
|
99re在线视频免费观看
|
亚洲国产精品不卡在线电影
|
免费人成在线观看网站品爱网
|
亚洲AV区无码字幕中文色
|
99爱在线精品视频免费观看9
|
亚洲综合成人网在线观看
|
91精品导航在线网址免费
|
777亚洲精品乱码久久久久久
|
亚洲高清视频免费
|
亚洲日韩乱码久久久久久
|
日韩精品成人无码专区免费
|
亚洲第一街区偷拍街拍
|
www亚洲精品少妇裸乳一区二区
|
国产免费福利体检区久久
|
亚洲AV无码久久精品成人
|
ww在线观视频免费观看
|
亚洲欧美一区二区三区日产
|
亚洲国产精品尤物yw在线
|
中国一级特黄的片子免费
|
噜噜噜亚洲色成人网站∨
|
成人性生交大片免费看无遮挡
|
国产91成人精品亚洲精品
|
亚洲区小说区图片区
|
日本xxxx色视频在线观看免费
|
亚洲AV无码无限在线观看不卡
|
va亚洲va日韩不卡在线观看
|
久久精品国产大片免费观看
|
亚洲熟妇无码AV
|
国产亚洲AV手机在线观看
|
又黄又爽又成人免费视频
|
尤物视频在线免费观看
|
久久亚洲私人国产精品
|