【问题标题】:How do I add values to a Set inside a Map? [closed]如何将值添加到地图内的集合? [关闭]
【发布时间】:2013-03-25 17:09:42
【问题描述】:

我有这张地图Map<String, Set<Integer>> myMap;,现在我需要与之交互,我该怎么做?


例如:

键是:“apple”、“orange”、“grape”等。
每组将包含随机数:1-9

我需要创建一个映射(HashMap 或 TreeMap),其中包含用于键的字符串和用于值的集合。我需要返回给定密钥的集合。我还需要能够根据一个键为每个集合填充多个数字。不知道如何解决这个问题。有什么想法吗?

【问题讨论】:

  • 阅读有关Set 接口及其实现的文档。 Map 也是如此。 To get you started
  • 你能举一个用户输入和预期输出的例子吗?
  • 您的地图应该是Map<String,Set<Integer>>,至于地图或集合本身,请参阅文档。特别是地图的putget 方法和集合的add 方法。
  • 您可能想查看 Guava 开源库中的 SetMultimap 接口及其实现。您可能可以直接使用这个库,或者至少看看他们的代码,以了解如何使用这种类型的数据结构。
  • 在 Java 8 中实现这一点的好方法:map.computeIfAbsent(key, k -> new HashSet()).add(value);

标签: java dictionary hashmap set key


【解决方案1】:

要记住的是,该值最初将为 null,因此第一次使用键时,您必须对其进行初始化:

Map<String,Set<Integer>> map;  

要将数字添加到密钥中,您必须这样做:

String key = "apple"; // for example 

Set<Integer> set = map.get(key); 
if (set == null) {
    set = new HashSet<Integer>();
    map.put(key, set);
}
set.add(5);

不幸的是,无论您在哪里与集合交互,都必须进行空检查。例如,如果您想检查某个键是否映射了某个数字,则无法安全地执行此操作:

if (map.get(key).contains(number))  // not safe

因为对get() 的调用可能会返回null(如果没有密钥条目)并且您会得到NullPointerException

有一种方法可以让你的地图使用起来非常方便,方法是在地图内部进行空检查,这样对get() 的调用将始终返回一个非空集;创建一个匿名类,相应地覆盖get()

Map<String,Set<Integer>> map = new HashMap<String,Set<Integer>> () {
    @Override
    public Set<Integer> get(Object key) {
        Set<Integer> set = super.get(key); 
        if (set == null) {
            set = new HashSet<Integer>();
            put(key, set);
        }
        return set;
    }
}

有了这个,您的主要代码变得更加简单和清晰。添加:

map.get(key).add(number);

检查:

if (map.get(key).contains(number)) // now safe

不再需要空检查代码。

——

Java 8 更新:

添加到集合时的空条目问题处理:

map.computeIfAbsent( key, k -> new HashSet<>() ).add(number);

对于空值安全检查:

if ( map.getOrDefault(key, Collections.emptySet() ).contains(number))

【讨论】:

    【解决方案2】:

    如果我理解正确的话并不难。

    Map<String, Set<Integer>> reqdMap = new HashMap<String, Set<Integer>>();
    
    //Form the set corresponding to apple.
    Set<Integer> appleSet = new HashSet<Integer>();
    appleSet.add(1);
    ...
    
    
    reqdMap.put("apple", appleSet);
    
    //To Retrieve
    appleSet = reqdMap.get("apple");
    

    【讨论】:

      【解决方案3】:

      为什么不看看这个:

      https://github.com/google/guava/wiki/NewCollectionTypesExplained#multimap

      MultiMap 允许您以非常有效的方式为给定键存储多个值。

      在您的情况下,最大的优势是您无需从给定键中检索值 (Set) 以向其添加一些值。

      确实,您只需将值添加到键中,就像处理“单值”一样,它将自动添加到后台的set

      【讨论】:

        【解决方案4】:
        Map<String,Set<Integer>> map;  
        Set<Integer> set = map.get("apple");  
        

        我省略了map的实际人口,因为OP是如何get集合,即值

        【讨论】:

          【解决方案5】:
          Map<String, Set<Integer>> mapOfSets = new HashMap<String, Set<Integer>>();
          Set<Integer> numberSet = new HashSet<Integer>();
          
          //put a set into the map
          mapOfSets.put("key", numberSet);
          //get a set out of the map
          Set<Integer> set = mapOfSets.get("key");
          

          【讨论】:

            【解决方案6】:

            如果您想使用一种方法将多个数字添加到集合中,请尝试以下操作:

            Map<String, Set<Integer>> map; // Definition
            
            
            public void addValues(String key, Integer... values) {
                map.get(key).addAll(values);
            }
            

            这样,当你需要为一个键添加一堆数字时,你可以这样调用:

            addValues("apple", 1, 2, 4, 6, 8);
            

            1 行而不是 5 行。

            【讨论】:

              【解决方案7】:

              这只是一个完整的示例。只需运行它并对其进行处理以了解有关此问题的更多信息

              public class Tester5 {
              
                  /**
                   * @param args
                   */
                  public static void main(String[] args) {
                      //"apple", "orange", "grape", etc. Each set will contain random numbers: 1, 2, 3, 4, 5, 6, 7, 8, 9
              
                      Random ran = new Random();
              
                      Map<String, Set<Integer>> map= new HashMap<String, Set<Integer>>();
                      String keys[]= {"apple", "orange", "grape"};
                      for(String key : keys) {
                          Set<Integer> integers= new HashSet<Integer>();
                          for(int i = 0; i < 10; i++) {
                               integers.add(ran.nextInt(9)+1);
                          }
                          map.put(key, integers);
                      }
                      System.out.println(map.toString());
              
                  }
              
              }
              

              【讨论】:

                猜你喜欢
                • 2021-12-03
                • 1970-01-01
                • 2018-07-30
                • 2016-11-02
                • 2012-05-01
                • 1970-01-01
                • 1970-01-01
                • 2013-07-26
                • 1970-01-01
                相关资源
                最近更新 更多