Java怎樣創建兩個KEY(key-pair)的MAP
就像在XY坐標系中,一個X刻度、一個Y刻度,會對應圖上的一個點,即pair(x, y) – > point,那么就有創建一個點,或者根據(x, y)來尋求一個點的需求,如果用Python的語法表達,是這個樣子:
dict((x, y) : point)
然而在JAVA中卻變得不容易,骨鉤了一下,有這么一些方法:
使用嵌套MAP
Map<Integer, Map<Integer, V>> map = //... // ... map.get(2).get(5);
這種方法將水平的KEY切換成了垂直KEY,我們要找尋XY坐標系中(x, y)對應的點,其實可以先找x點的那條垂直線,然后找出這條垂直線上y高度的那個點。
但是要取得這個雙KEY的VALUE,得有2次GET,實例代碼沒有做第一次GET的NULL判斷,有隱患!并且感覺不是很直觀。
寫一個pair key的包裝類
public class Key { private final int x; private final int y; public Key(int x, int y) { this.x = x; this.y = y; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Key)) return false; Key key = (Key) o; return x == key.x && y == key.y; } @Override public int hashCode() { int result = x; result = 31 * result + y; return result; } }
以這種方法提前包裝好一個類,類中有x和y兩個屬性,同時提供equals方法用于“點”的比較,提供hashCode用于使用在計算對象在散列表中的位置。
為什么要覆蓋hashCode方法?請參見鏈接
寫完這個pair類之后,就好用了:
Map<Key, V> map = //... map.get(new Key(2, 5));
這種方法以更多的代碼為代價來實現pair key的map,pair class的編寫中,不能忘記覆蓋equals和hashcode方法,增加了代碼量,感覺不是很好用。
GOOGLE的HashBasedTable類庫
這種方法感覺才是最直觀,最好用的
import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; // 創建 Table<Long, Long, Point> plane = HashBasedTable.create(); // 新增 plane.put(1L, 2L, pointA); plane.put(1L, 3L, pointB); plane.put(1L, 4L, pointC); // 獲取 Point pointA = plane.get(1L, 2L); Point pointB = plane.get(1L, 2L);
驚嘆,好用。在JAVA語言里,寫成這樣的代碼,可稱之為藝術。
無限維度的KEY
有兩種方法可以實現無線維度的KEY,第一種和本文的第二種方法一樣,先寫一個CLASS,里面有無限個屬性,然后作為MAP的KEY。
第二種,如果類型一樣,可以這樣子實現:
Map<List<Integer>, V> map = //...
但是這種方法易出錯、不易讀,并且性能很低。
總結
要實現map的key是兩個綁定的屬性,或者稱之為pair key,個人認為首先使用google的HashBasedTable類庫,其次的方法是編寫對應的class。
可是,這些總感覺不是那么的方便,python那種{tuple : value}的方法,咋就那么藝術呢!
本文翻譯自:鏈接 中的一個答案。