迭代Map <typea,设置<typeb>&gt;并将其转换为Map <typeb,set <typea>&gt;在爪哇

时间:2016-10-21 11:08:10

标签: java dictionary hashmap iteration

我有一个Map<String>,Set<String>> followingMap,其中键是用户名,值是关键用户名所遵循的用户名集。 我必须创建一个followersMap,在这种情况下,值集中的后续用户现在是键,值是根据前一个k的一组追随者。

不确定这是否足够清楚,例如,下一个地图中的元素将是:key="john", value=Set["robert","andrew,"amanda"].

在关注者地图中,它将是:

key="robert", value=Set["john"]
key="andrew", value=Set["john"]
key="amanda", value=Set["john"]

如果followMap中的第二个元素是key="alex",Set["amanda"],则会添加&#34; alex&#34;到&#34; amanda&#34;的价值集键。

我的代码应该可以解决问题,但是在测试时,我会获得所有值集被填充的键。

看看:

Map<String,Set<String>> followerGraph = new HashMap<String,Set<String>>();
for (Map.Entry<String, Set<String>> me : followsGraph.entrySet()) {
              String key = me.getKey();
              Set<String> tmp = new LinkedHashSet<>();    
              Set<String> valueSet = me.getValue();
              for (String s : valueSet) {
                  if (followerGraph.containsKey(s)){
                      followerGraph.get(s).add(key);
                  } else {
                      tmp.add(key);
                      followerGraph.put(s, tmp);
                  }  
              }   
        }

所以这是以下图表的印刷品:

{aliana=[@jake, @john, @erick], alyssa=[@john, @erick], 
bbitdiddle=[@rock-smith, @john, @erick], casus=[@daniel, @jake, @john, @erick], 
david=[@dude, @john]}

这是关注者的图片:

{@daniel=[casus], @rock-smith=[bbitdiddle], @jake=[aliana, alyssa, bbitdiddle, casus, david], @dude=[david], @john=[aliana, alyssa, bbitdiddle, casus, david], @erick=[aliana, alyssa, bbitdiddle, casus, david]}

正如你所看到的,@ erick承认没有大卫作为追随者。我错过了什么吗? 对不起,如果我的代码看起来像一团糟。我只有6个月的Java,4个小时学习如何迭代地图(尝试了Java 8流,但不知道如何在那里添加if-else),而且它早上6点,我的妻子可能会杀了我熬夜:S

3 个答案:

答案 0 :(得分:2)

你可以这样做:

    Map<String, Set<String>> followerMap = new HashMap<>();
    followingMap.forEach((name,followingSet)-> followingSet.forEach(
            follower-> followerMap.computeIfAbsent(follower, f->new HashSet<>())
                                  .add(name)));

followingMap.forEach处理以下Map中的所有条目。然后使用followingSet.forEach处理每个条目的集合。这一组的元素是追随者,新地图的关键。正在使用computeIfAbsent在地图中放置一个新条目(如果它不存在),在这种情况下添加一个空集。然后,将值添加到Set中,在这种情况下是followerMap的条目。

这是使用for循环代替forEach的相同代码,可能更具可读性。

    Map<String, Set<String>> followerMap = new HashMap<>();
    for (Entry<String, Set<String>> followingEntry : followingMap.entrySet()) {
        for (String follower : followingEntry.getValue()) {
            followerMap.computeIfAbsent(follower, s->new HashSet<>()).add(followingEntry.getKey());
        }
    }

答案 1 :(得分:1)

试试这个。

for (Map.Entry<String, Set<String>> me : followsGraph.entrySet()) {
    String key = me.getKey();
    // Set<String> tmp = new LinkedHashSet<>();     // MOVE THIS TO ...
    Set<String> valueSet = me.getValue();
    for (String s : valueSet) {
        if (followerGraph.containsKey(s)) {
            followerGraph.get(s).add(key);
        } else {
            Set<String> tmp = new LinkedHashSet<>();  // HERE
            tmp.add(key);
            followerGraph.put(s, tmp);
        }
    }
}

答案 2 :(得分:1)

尝试这样的事情:

Map<String, Set<String>> newFollowsGraph = new HashMap<>();
for (Map.Entry<String, Set<String>> me : followsGraph.entrySet()) {
          String key = me.getKey();  
          Set<String> valueSet = me.getValue();
          for (String s : valueSet) {
              if (newFollowerGraph.containsKey(s)){
                  newFollowerGraph.get(s).add(key);
              } else {
                  Set<String> tmp = new LinkedHashSet<>();
                  tmp.add(key)
                  newFollowerGraph.put(s, tmp);
              }  
          }   
    }

问题是,您正在迭代的对象中插入新数据。