读:Java并发编程实战 遇到的问题及解决(一)

在实例封闭的例子中,我们先来看看代码
如果对于Collections.unmodifiableMap() 不熟悉的话,最后会给出解析

class MutablePoint{
    public  int x,y;
    public MutablePoint(){
        x=0;
        y=0;
    }
    public MutablePoint(MutablePoint point){
        this.x = point.x;
        this.y = point.y;
    }

}

public class MonitorVehicleTracker{
    private final Map<String, MutablePoint> locations;
    //问题一:为什么在初始化的时候需要深拷贝呢
	//因为如果使用 this.locations = locations时,我们赋值的是locations的引用
	//当我们扩展外部的locations时会影响到我们类中的变量,这并不是我们想看到的
	//在深拷贝中,返回的是Collections.unmodifiableMap(locs),所以我们无法扩展变量locations,只能修改里面的值
    public MonitorVehicleTracker(Map<String, MutablePoint> locations){
        this.locations = locations;
    }
	//问题二:为什么返回实例的时候还需要进行一次深拷贝呢,直接返回Collections.unmodifiableMap(locs)不就可以了?
	//现在的理解是为了防止Point的逸出
    public synchronized Map<String, MutablePoint> getLocations(){
        return deepCopy(locations);
    }

    public synchronized MutablePoint getLocation(String id){
        MutablePoint loc = locations.get(id);
        return loc == null?null:new MutablePoint(loc);
    }

    public synchronized void setLocation(String id, int x, int y){
        MutablePoint loc = locations.get(id);
        if(loc == null)
            throw new IllegalStateException();
        loc.x = x;
        loc.y = y;
    }

    private static Map<String, MutablePoint> deepCopy(Map<String, MutablePoint> m){
        Map<String, MutablePoint> locs = new HashMap<>();
        for(String id:m.keySet()){
            MutablePoint loc = new MutablePoint(m.get(id));
            locs.put(id, loc);
        }
        return Collections.unmodifiableMap(locs);
    }
}

对于 Collections.unmodifiableMap 有一个很好的例子

package three;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class SeeminglyUnmodifiable {
	private Map<String, Point> startingLocations = new HashMap<String, Point>(3);

	public SeeminglyUnmodifiable() {
		startingLocations.put("张三的位置", new Point(1, 1));
		startingLocations.put("李四的位置", new Point(1, 2));
		startingLocations.put("王五的位置", new Point(1, 3));
		// ..more locations..
	}

	public Map<String, Point> getStartingLocations() {
//		Map<String,Point> newMap = new HashMap<>();
//		for(String key : startingLocations.keySet()) {
//			newMap.put(key, startingLocations.get(key));
//		}
		return Collections.unmodifiableMap(startingLocations);
	}

	public static void main(String[] args) {
		SeeminglyUnmodifiable pieceLocations = new SeeminglyUnmodifiable();
		Map<String, Point> locations = pieceLocations.getStartingLocations();

		Point camelLoc = locations.get("张三的位置");
		System.out.println("张三的位置是 : [ " + camelLoc.getX() + ", " 
							+ camelLoc.getY() + " ]");
		
		// Try 1. update elicits Exception
		try {
			locations.put("张三的位置", new Point(0, 0));
		} catch (java.lang.UnsupportedOperationException e) {
			System.out.println("无法重新赋值,只能修改");
		}

		// Try 2. Now let's try changing the contents of the object from the
		// unmodifiable map!
		camelLoc.setLocation(0, 0);

		// Now see whether we were able to update the actual map
		Point newCamelLoc = pieceLocations.getStartingLocations().get("张三的位置");
		System.out.println("我们可以修改张三位置的值 ,修改后张三的位置为 : [ " 
				+ newCamelLoc.getX() + ", "
				+ newCamelLoc.getY() + " ]");
	}
}

class Point {
	public float x;
	public float y;

	public Point(float x, float y) {
		setLocation(x, y);
	}

	public void setLocation(float x, float y) {
		this.x = x;
		this.y = y;
	}

	public float getX() {
		return x;
	}

	public float getY() {
		return y;
	}
}

输出的结果为

张三的位置是 : [ 1.0, 1.0 ]
无法重新赋值,只能修改
我们可以修改张三位置的值 ,修改后张三的位置为 : [ 0.0, 0.0 ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值