[英]How to swap arrayMap values and keys in Java
我在反轉給定的映射並將其反轉的鍵和值存儲到另一個映射時遇到了一些麻煩。 我有一個方法原型如下:
public static Map<String, Set<String>> reverse (Map <String, Set<String>> graph);
因此,如果我有向圖的樣例鍵如下:
{c -> arraySet{f, e}}
{b -> d}
{a -> arraySet{c, b}}
{d -> g}
{e -> d}
{f -> arraySet{g, d}}
我需要有效地反轉該圖,以便使d-> b代替b-> d。
我認為這對我來說就是要交換原始圖中的值和鍵,並將它們添加到reverseMap中。 我想我可以遍歷圖中給定鍵的每組值,然后將它們存儲在列表中。
不幸的是,我在實施和思考時遇到了麻煩。 我真的很感激朝着正確方向前進。
這是使用Guava Multimaps的實際,最新工作代碼:
SetMultimap<Integer, Integer> graph = HashMultimap.create();
graph.put(1, 2); // add an edge from 1 to 2
SetMultimap<Integer, Integer> inverse = Multimaps.invertFrom(
graph, HashMultimap.<Integer, Integer> create());
(披露:我向番石榴捐款。)
但是,如果您不能使用第三方庫,請執行以下操作...
Map<Integer, Set<Integer>> g;
Map<Integer, Set<Integer>> gInverse = new HashMap<Integer, Set<Integer>>();
for (Map.Entry<Integer, Set<Integer>> gAdj : g.entrySet()) {
Integer v = gAdj.getKey();
for (Integer w : gAdj.getValue()) {
Set<Integer> wInverseAdj = gInverse.get(w);
if (wInverseAdj == null) {
gInverse.put(w, wInverseAdj = new HashSet<Integer>());
}
wInverseAdj.add(v);
}
}
或者,如果您可以使用Java 8,請使用此...
map.entrySet().stream()
.flatMap(entryKToVs -> entryKToVs.getValue().stream()
.map(v -> new AbstractMap.SimpleEntry<>(entryKToVs.getKey(), str)))
.collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList())))
偽代碼,但接近真實。 只需使用Multimap即可 。
Multimap<String, String> ret = Multimaps.newSetMultimap();
for (Entry<String, Set<String>> entry : graph) {
for(String neighbor : entry.getValue()) {
ret.addTo(neighbor, entry.getKey());
}
}
您將需要遍歷映射中的條目,然后,由於值存儲在集合中,因此需要遍歷該集合。 您將需要檢查每個鍵的結果圖,並在鍵不存在時創建一個新的鍵集。
public static Map<String, Set<String>> reverse (Map <String, Set<String>> graph) {
Map<String, Set<String>> result = new HashMap<String, Set<String>>();
for (Map.Entry<String, Set<String>> graphEntry: graph.entrySet()) {
for (String graphValue: graphEntry.getValue()) {
Set<String> set = result.get(graphValue);
if (set == null) {
set = new HashSet<String>();
result.put(graphValue, set);
}
set.add(graphEntry.getKey());
}
}
return result;
}
我首先建議編寫一個Graph
類,該類抽象出底層的Map
數據結構。 當然,這只是將實現推送到Graph
接口,而不是直接處理Map
接口。
因此,現在,堅持使用您的地圖:
Map<String, Set<String>> graph;
Map<String, Set<String>> reverse;
我建議使用Map.entrySet()從graph
獲取一組條目。 然后,對於每個Map.Entry ,檢索每個鍵和鍵的值。 接下來,對於值Set
中的每個“頂點”,將鍵插入與頂點關聯的Set
中。
如果我將其格式化為類似於Java代碼而不是英語句子,則可能會更清楚。 我希望你能得到基本的想法。 當然,如果適合您的項目約束,則最好使用預制和預先測試的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.