Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将Collections.unmodifiableMap与ConcurrentHashMap/HashMap一起用作参数_Java_Hashmap_Concurrenthashmap - Fatal编程技术网

Java 将Collections.unmodifiableMap与ConcurrentHashMap/HashMap一起用作参数

Java 将Collections.unmodifiableMap与ConcurrentHashMap/HashMap一起用作参数,java,hashmap,concurrenthashmap,Java,Hashmap,Concurrenthashmap,我从Goetz的书(实践中的Java并发)中获得了以下代码 书中说,将ConcurrentMap作为参数传递到Collections.unmodifiableMap将提供位置的“实时”视图(即下面调用getLocations()),这意味着对setLocation的调用将反映给调用者 但是,将HashMap作为Collections.unmodifiableMap中的参数传递将提供位置的原始视图(静态视图)(即,调用下面的getLocationsAsStatic()) 有人能解释一下背后的原因吗

我从Goetz的书(实践中的Java并发)中获得了以下代码

书中说,将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;
    }
}
@ThreadSafe
公共类授权车辆跟踪程序{
私有最终ConcurrentMap位置;
私有最终地图不可修改地图;
公共授权车辆追踪程序(地图点){
位置=新的ConcurrentHashMap(点);
unmodifiableMap=集合。unmodifiableMap(位置);
}
公共地图getLocations(){
返回不可修改的映射;
}
公共点getLocation(字符串id){
返回位置。获取(id);
}
公共void集合位置(字符串id,int x,int y){
if(locations.replace(id,新点(x,y))==null)
抛出新的IllegalArgumentException(“无效车辆名称:+id”);
}
//getLocations的替代版本(清单4.8)
公共地图getLocationsAsStatic(){
return Collections.unmodifiableMap(
新的HashMap(位置);
}
}
@不变的
公共课点{
公共最终int x,y;
公共点(整数x,整数y){
这个.x=x;
这个。y=y;
}
}

行为上的差异不是因为地图类型不同,而是因为它们是如何创建的<代码>集合。不可修改地图仅包装给定地图

您的
ConcurrentMap locations
是您正在修改的映射,因此当您包装它时,在使用不可修改的映射时,您仍然会看到最新的值

但是,您的
HashMap
是使用
newhashmap(locations)
创建的。文件说明:

使用与指定映射相同的映射构造新的HashMap

参数:
m-其映射将放置在此映射中的映射

因此,它实际上将给定映射的所有条目复制到新创建的映射中。因此,这个新的映射不再与
位置相关了。

另请参见Java并发实践中的类似示例