亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使Map的特化變得不可修改?

如何使Map的特化變得不可修改?

DIEA 2023-06-28 15:51:56
我目前正在通過一個中型編碼示例來刷新我的 Java 知識。我有一個數據結構Map<String, String>,通常用它來初始化它new LinkedHashMap<>()以保留插入順序。我在代碼中經常使用它,并且我想擺脫聲明重復。在 C++ 中,我會給地圖起別名,但據我所知,在 Java 中沒有別名。所以我想出了將泛型子類化的想法,如下所示:public class Attributes extends LinkedHashMap<String, String> {    public Attributes() {        super();    }    public Attributes(Map<? extends String, ? extends String> map) {        super(map);    }}到目前為止,這看起來不錯,但現在我想創建它的不可修改的副本,因為屬性應該是不可變/不可修改的數據結構的一部分。在我使用這個之前:Map<String, String> unmodifiableAttributes = Collections.unmodifiableMap(        new LinkedHashMap<>(attributes));這不適用于派生類,我嘗試過:Attributes unmodifiableAttributes = Collections.unmodifiableMap(        new Attributes(attributes));編譯器會拒絕它Incompatible types。有沒有一種簡單的方法來獲取此類子類的不可修改(或不可變)副本?還是我的想法完全錯誤?我不想寫一個功能齊全的裝飾器,只想寫幾行代碼。更新到目前為止,對于我想做的事情似乎還沒有好的解決方案。我查看了Java Collections類的源代碼,有不可修改的映射和類似集合的內部類。它們用于包裝輸入集合并由相應的靜態方法返回。人們可以重新實現這一點,但我認為開銷太大。我們對 LSP 違規進行了更多討論,而不是原來的問題,這確實也是一個有趣的問題。
查看完整描述

2 回答

?
一只名叫tom的貓

TA貢獻1906條經驗 獲得超3個贊

您不能使子類LinkedHashMap不可修改,因為它會違反里氏可替換性:LinkedHashMap被記錄為可變的,因此所有子類也必須是可變的。

您還有一個額外的問題,即要使地圖不可修改實際上需要做很多工作:您不僅有像putand之類的明顯方法remove,而且還有像clear,?putAll,?putIfAbsent,?computeIfAbsent, 之類的東西computeIfPresent。然后你必須擔心視圖返回方法:entrySet,keySet,values都必須返回不可修改的視圖。我確信我錯過了幾個也需要重寫的方法,但我的觀點仍然是,使可變映射不可修改并不是微不足道的。

但是,您可以擁有不可修改的 Map 實現。最簡單的方法是擴展AbstractMap并委托給實際的LinkedHashMap

public class Attributes extends AbstractMap<String, String> {

? ? private final LinkedHashMap<String, String> delegate;


? ? public Attributes() {

? ? ? ? this(Collections.emptyMap());

? ? }


? ? public Attributes(Map<? extends String, ? extends String> map) {

? ? ? ? this.delegate = new LinkedHashMap<>(map);

? ? }


? ? // Override the methods you need to, and that are required by AbstractMap.

? ? // Details of methods to override in AbstractMap are given in Javadoc.

}

但我也會質疑你的 Attributes 類是否真的需要實現像接口一樣通用的東西Map- 如果你需要這種通用性,你可以直接使用 a Map。


查看完整回答
反對 回復 2023-06-28
?
倚天杖

TA貢獻1828條經驗 獲得超3個贊

Collections.unmodifiableMap返回 aMap<K,V>所以你必須像這樣使用它:

Map<String,?String>?unmodifiableAttributes?=?Collections.unmodifiableMap(?
???????????new?Attributes(attributes)
);

并且您無法將返回的對象轉換為Attributes

Attributes?unmodifiableAttributes?=?(Attributes)?Collections.unmodifiableMap(
????????????new?Attributes(attributes)
);

因為Collections.unmodifiableMap返回實例,private static UnmodifiableMap所以你會得到一個ClassCastException.?并且Attributes不是 的子類型UnmodifiableMap。

LinkedHashMap另外,我認為在您的情況下,直接使用而不是從中創建派生類會更容易,因為據我所知,功能與原始類沒有什么不同。Collections.unmodifiableMap然后使用從as返回的對象Map。


查看完整回答
反對 回復 2023-06-28
  • 2 回答
  • 0 關注
  • 259 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號