特殊的Map實現IndentityHashMap

2021-10-01 03:03:55 字數 3679 閱讀 1463

indentityhashmap

的特殊性在於它的鍵值比較使用

」key1==key2」

,而map

實現的常規約束的鍵值比較使用

」key1.equals(key2)」

。這樣設計的主要目的是適用引用物件比較級別的應用場景。

其中乙個應用場景就是使用

indentityhashmap

維護**物件,可以為每個物件建立乙個關聯物件,例如為每個物件建立乙個日誌例項。

maploggers = new identityhashmap<>();

teacher t1 = new teacher("小李");//重名的小***

teacher t2 = new teacher("小李");

loggers.put(t1, new logger("info"));

loggers.put(t2, new logger("debug"));

//******

loggers.get(t1).log("吃飯");//不同物件使用不同logger物件

loggers.get(t2).log("睡覺");

public class logger

public void log(string msg)

}public class teacher

******

}

維護**對這種場景的實際應用可以在

netty

原始碼中找到,

netty

中定義了乙個引數型別匹配器(

typeparametermatcher

),用來驗證某個物件是否建立自某個類。

我們驗證物件型別的普通方法可能是

instanceof

關鍵字或獲取物件的

class

物件,呼叫

class

物件的isassignablefrom

方法,再或者直接呼叫目標

class

的isinstance

方法:

teacher o1 = new teacher();

system.out.println(o1 instanceof teacher);

system.out.println(o1.getclass().isassignablefrom(teacher.class));

system.out.println(teacher.class.isinstance(o1));

//輸出 true,true,true

但是如果考慮到類載入器,不同的類載入器載入的

class

會建立不同的

class

物件,類似下面的樣例:

filesystemclassloader cl = new filesystemclassloader("d:\\bin\\test");

classtclass = (class)cl.findclass("map.teacher");

teacher o1 = new teacher();

system.out.println(o1 instanceof teacher);

system.out.println(o1.getclass().isassignablefrom(tclass));

system.out.println(tclass.isinstance(o1));

//輸出true, false, false

filesystemclassloader

是自定義的乙個類載入器,上面的輸出結果並不難理解,因為

o1這個

teacher

物件並不是建立自

tclass

這個類物件。

netty

的internalthreadlocalmap

類中定義了乙個

indentityhashmap

型別的變數儲存類與型別比較器的對映關係。

map, typeparametermatcher> cache;

cache = new identityhashmap, typeparametermatcher>();

netty

中使用indentityhashmap

也並非那麼有必要,因為

class

類的equal

方法繼承自

object

物件,預設使用的

this==object

等值比較,使用

hashmap

和使用indentityhashmap

效果一樣。但是

indentityhashmap

還有乙個特定,就是對於基本操作,它的效率是恆定的(

constant-time performance),

因為其內部使用

system.identityhashcode(object)

計算雜湊值。

indentityhashmap

物件被建立時可以指定

maximum

屬性,空間不夠的情況下會自動擴充套件,但擴充套件空間很影響效率,而最初指定的

maximum

過大可能會造成空間浪費,需要在實際應用中找到的合理的初始大小。

indentityhashmap

可以支援

null

值的key

和value

。它也是非執行緒安全的,如果想在多執行緒中使用它,可以借助

collections

幫助類:

map m = collections.synchronizedmap(new identityhashmap(...));

自定義類載入器

public class filesystemclassloader extends classloader 

protected class<?> findclass(string name) throws classnotfoundexception else

} private byte getclassdata(string classname)

return baos.tobytearray();

} catch (filenotfoundexception e) catch (ioexception e)

return null;

} private string classnametopath(string classname)

}

2.

如何區分使用介面和泛型?

泛型的最大好處是讓類例項可以處理未知型別的物件。乙個物件被建立必定有它的職責,它的職責就是處理某些業務邏輯。物件履行自己的職責過程中可能需要其他物件的輔助,如果這些關聯物件屬於同一型別,可以抽象成介面類。

比如老師物件平時需要教導學生學習知識,同時也要向教導主任匯報工作,學生和主任都是他的關聯物件,可以抽象

person

介面,老師的關聯人使用

list

定義。

如果老師類上定義了乙個「審閱」方法,可以審閱試卷,也可以審閱日常作業,試卷和日常作業不能抽象同一類,可以借助泛型來定義。

public class teacher 

}

Map實現類的比較

map實現類的比較 hashmap的存入順序和輸出順序無關。key值物件 hashcode和equals方法 linkedhashmap則保留了鍵值對的存入順序,一般不會使用訪問順序。key值物件 hashcode和equals方法 linkedhashmap雖然增加了時間和空間上的開銷,但是通過維...

使用特殊字型實現特殊報表效果

通過設定字型實現特殊字元顯示,適用於textbox,字段,引數字段,公式等。需要注意的是,如果使用的是特殊字型,沒有該字型的機器是不能正常顯示的。像 winddings字型,一般的windows系統都自帶。但是如果web應用,使用非windows機器瀏覽的時候可能就不能正確顯示。僅做乙個字型示例,報...

Javascript實現Map結構

說明 1.put key 新增乙個kv 2.get key 得到乙個kv 3.remove key 刪除乙個kv 4.size map的大小 return int 5.isempty 是否為空 6.keys 得到所有的key return array 7.values 得到所有的value retu...