編寫一個初始化之後,不可修改的集合(比如:Map、List、Set等不可變對象)

Java中提供final關鍵字,對基本類型進行修飾,當第一次初始化後,該變量就不可被修改,比如:
private final int a = 123;
然而,對於Map等類型,我們只能對於其引用不能被再次初始化,而其中的值則可以變化,比如:
private static final Map<Integer, String> map = Maps.newHashMap();

static {
    map.put(1, "one");
    map.put(2, "two");
}

public static void main(String[] args) {
    map.put(1,"three");
    log.info("{}", map.get(1));
}
輸出:
22:45:01.582 [main] INFO com.tim.concurrency.example.immutable.ImmutableExample - three
分析上述代碼可知map的值由原來key爲1,value爲one,被改爲value爲three。因此,此map是域不安全的。
改進方法(通過Collectionsf方法):
static {
    map.put(1, "one");
    map.put(2, "two");
    map  = Collections.unmodifiableMap(map);
}

public static void main(String[] args) {
    log.info("{}", map.get(1));
}
分析:
上述map如果再被put,則會報異常,map.put(1, "three");則會報異常。
static {
    map.put(1, "one");
    map.put(2, "two");
    map  = Collections.unmodifiableMap(map);
}

public static void main(String[] args) {
    map.put(1, "three");
    log.info("{}", map.get(1));
}
上述代碼會導致下面異常:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
at com.tim.concurrency.example.immutable.ImmutableExample.main(ImmutableExample.java:27)
分析:上述map是域安全,被初始化之後,不能被修改了。
補充(利用Collections和Guava提供的類可實現的不可變對象):

Collections.unmodifiableXXX:Collection、List、Set、Map...

Guava:ImmutableXXX:Collection、List、Set、Map...

   private final static ImmutableList<Integer> list = ImmutableList.of(1, 2, 3);  // 這樣被初始化之後 list是不能被改變

    private final static ImmutableSet set = ImmutableSet.copyOf(list); // 這樣被初始化之後set是不能被改變的

    public static void main(String[] args) {
        list.add(123);
        set.add(222);
    }
}

上述代碼中的list和set不能再被改變。

注意:guava中的map的寫法有點不一樣如下:

private final static ImmutableMap<Integer, Integer> map = ImmutableMap.of(1,2,3,4,5, 6);

private final static ImmutableMap<Integer, Integer> map2 = ImmutableMap.<Integer, Integer>builder().put(1,2).put(3,4).put(5,6).build();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章