在实例封闭的例子中,我们先来看看代码
如果对于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 ]