簡體   English   中英

將Collections.unmodifiableMap與ConcurrentHashMap / HashMap用作參數

[英]Use Collections.unmodifiableMap with ConcurrentHashMap / HashMap as a parameter

我從Goetz的書(Java Concurrency in Practice)中獲得了以下代碼。

該書說,將ConcurrentMap作為Collections.unmodifiableMap中的參數傳遞,將給出位置的“實時”視圖(即,調用下面的getLocations()),這意味着對setLocation的調用將反映給調用者。

但是,將HashMap作為Collections.unmodifiableMap中的參數傳遞將給出位置的原始視圖(靜態視圖)(即,調用下面的getLocationsAsStatic())

誰能解釋其背后的原因? 謝謝

@ThreadSafe
public class DelegatingVehicleTracker {
    private final ConcurrentMap<String, Point> locations;
    private final Map<String, Point> unmodifiableMap;

    public DelegatingVehicleTracker(Map<String, Point> points) {
        locations = new ConcurrentHashMap<String, Point>(points);
        unmodifiableMap = Collections.unmodifiableMap(locations);
    }

    public Map<String, Point> getLocations() {
        return unmodifiableMap;
    }

    public Point getLocation(String id) {
        return locations.get(id);
    }

    public void setLocation(String id, int x, int y) {
        if (locations.replace(id, new Point(x, y)) == null)
            throw new IllegalArgumentException("invalid vehicle name: " + id);
    }

    // Alternate version of getLocations (Listing 4.8)
    public Map<String, Point> getLocationsAsStatic() {
        return Collections.unmodifiableMap(
                new HashMap<String, Point>(locations));
    }
}

@Immutable
public class Point {
    public final int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

行為上的差異不是由於地圖的類型不同,而是由於它們是如何創建的。 Collections.unmodifiableMap只是包裝給定的地圖。

您的ConcurrentMap<String, Point> locations是您要修改的地圖,因此,在包裝它時,使用不可修改的地圖時,您仍然會看到最新的值。

但是,您的HashMap是使用new HashMap<String, Point>(locations) 構造函數的文檔說:

使用與指定Map相同的映射構造一個新的HashMap。

參數:
m-要在其地圖中放置其映射的地圖

因此,它實際上將給定映射的所有條目復制到新創建的條目中。 因此,此新地圖不再與locations地圖相關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM