與例如編輯
這將拷貝輸入地圖,安全地提供地圖時請求的不可變拷貝,並安全地在需要時返回的地圖的一個元素:
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CopyMap {
//just an example Long and String are both immutable
//replace Long for Book (Book has to implement hashcode and equals.
// replace String for Booklog
private final Map<Long, String> map;
public CopyMap(Map<Long,String> map) {
this.map = new ConcurrentHashMap<>(map);
}
// get a non editable copy of the whole map
// threadsafe because this.map is concurrentHashMap
// no synchronization needed
public Map<Long,String> getMap() {
return Collections.unmodifiableMap(this.map);
}
//get only one of the elements
//thread safe because implementation is ConcurrentHashMap
//no synchronization needed
public String get(Long key) {
return map.get(key);
}
//just to try it, with -ea enabled
public static void main(String... args) {
final Map<Long,String> map1 = new ConcurrentHashMap<>();
map1.put(1l,"1");
map1.put(2l,"2");
map1.put(3l,"3");
final CopyMap copyMap = new CopyMap(map1);
assert(copyMap.getMap().equals(map1));
assert(copyMap.getMap()!=map1);
assert(copyMap.get(1l).equals("1"));
assert(copyMap.get(2l).equals("2"));
assert(copyMap.get(3l).equals("3"));
}
}
原來歷史的目的: 有幾件事情,
首先,它是更好,如果你定義了你的變量/場/ constan全部作爲接口而不是具體的具體類。所以,你應該定義你映射爲:
//conventions usually prefer private final, as opposed to final private
private final Map<Book,BookLog> booklogMap;
然後,其次,你的確可以使用Collections.unmodifiableMap()
因此,一個例子是:
//package and imports here
public class MyClass {
private final Map<Book,BookLog> booklogMap;
public MyClass(Map<Book, BookLog> booklogMap) {
this.booklogMap = Collections.unmodifiableMap(booklogMap);
}
}
第三,你有真正的不變性,你需要使整個對象的層次不變。所以你的類Book
和BookLog
也需要是不可變的。
否則,您需要在構造函數中一一列出所有Book和s BookLog。
'new ConcurrentHashMap(booklogMap)'?你是否需要製作內容的副本? –
resueman
爲什麼要使用'Collections.unmodifiableMap()'遇到一個投射問題? – Tunaki
@Tunaki - 當我厭倦它時,它說要向Collections.unmodifiableMap()添加一個ConcurrentHashMap的強制轉換。 – AnnabelleRosemond