我看到設置比較器的唯一方法是通過TreeMap構造函數。例如:在運行時更改樹形圖比較器
TreeMap myMap = new TreeMap(myComparator);
但是,我想確定在運行時使用什麼類型的比較器。我可以創建多個TreeMaps或一個新的實例,但是我發現它留下了更大的內存空間。
有沒有辦法做到這一點?或者我的設計存在缺陷?
我看到設置比較器的唯一方法是通過TreeMap構造函數。例如:在運行時更改樹形圖比較器
TreeMap myMap = new TreeMap(myComparator);
但是,我想確定在運行時使用什麼類型的比較器。我可以創建多個TreeMaps或一個新的實例,但是我發現它留下了更大的內存空間。
有沒有辦法做到這一點?或者我的設計存在缺陷?
我建議你推遲創建TreeMap
,直到你知道哪個Comparator
將是合適的。如果這是不可能的(例如,因爲您需要使用對TreeMap
的引用來初始化其他對象),請考慮將TreeMap
隱藏在將懶惰地初始化它的方法或類後面,或者使用Factory模式。如果這也不可行,請使用您自己的Comparator
實施初始化TreeMap
,然後在那裏作出決定(在您開始向TreeMap
添加項目之前,不會調用compareTo()
)。
至於爲什麼TreeMap
(或採取Comparator
其他大多數集合)將不允許你改變Comparator
,看到@Evgeniy Dorofeev的答案。
TreeMap不允許更改比較器,因爲內部樹結構依賴於比較器,並且更改它會使內部樹無效。
你可以在這樣的方式實現你的比較:
//first impl
final Comparator<String> first = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return 0;
}
};
//second impl
final Comparator<String> second = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return 0;
}
};
Comparator<String> inst=first;
//Treemap initialization
TreeMap<String, String> t = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//call of the impl
return inst.compare(o1, o2);
}
});
.....
//switch during runtime
inst = second;
....
你可以做這樣的事情:
class MyCompartor<T> implements Comparator<T> {
Comparator<T> changeableComparator;
public void setComparator(Comparator<T> comparator) {
this.changeableComparator = comparator;
}
@Override
public int compare(T o1, T o2) {
return changeableComparator.compare(o1, o2);
}
}
但是這將是瘋狂的。在運行期間,您不能也不能更改TreeMap
的Comparator
。根據新的Comparator
,樹不會重新組織。
取而代之,爲每個新的Comparator
創建一個新的TreeMap
(也就是說,如果您知道比較類型是別人建議的,則無法初始化映射)。
或者,子類TreeMap,並添加一個重新組合方法與上面更改Comparator
,但真的這是幾乎相同(性能明智)創建一個新的TreeMap
。你唯一要消除的是內存分配。
或者,使用更改後的比較器創建一個新的TreeMap,並從現有的TreeMap中創建一個新的TreeMap。 – user949300 2015-02-24 06:35:49
@ user949300:這也可以,但是如果'TreeMap'是從很多地方引用的(這將全部需要更新),它可能會變得混亂。 – 2015-02-24 06:39:56