在 Java 中迭代 Map<TypeA,Set> <TypeB>并将其转换为 Map<TypeB,Set<TypeA>>



我有一个Map<String>,Set<String>> followingMap,其中键是用户名,值是键用户名跟随的用户名集合。我必须创建一个followersMap,在这种情况下,值集中被关注的用户现在是键,值是根据前面的k的追随者集。

不确定这是否足够清楚,所以作为一个例子,以下map中的元素将是:key="john", value=Set["robert","andrew,"amanda"].

在followersMap中应该是:

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

如果followingMap中的第二个元素是key="alex",Set["amanda"],则会将"alex"添加到"amanda"键的值集合中。

我的代码应该做到这一点,但是在测试时,我得到的键,所有的值集都被填充。

看一看:

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不应该有david作为追随者。我错过什么了吗?抱歉,如果我的代码看起来很乱。我只学了6个月的Java,花了4个小时学习如何迭代映射(尝试了Java 8流,但不知道如何在其中添加if-else),现在是早上6点,我妻子可能会因为我熬夜而杀了我:S

你可以这样做:

    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处理每个条目的Set。这个集合的元素是追随者,即新地图的键。computeIfAbsent被用来在地图中添加一个不存在的新条目,在这种情况下添加一个空的Set。在此之后,将值添加到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());
        }
    }

试试这个

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);
        }
    }
}

试试这样:

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);
              }  
          }   
    }

问题是,你在迭代对象中插入了新的数据

最新更新