【问题标题】:C# to Java - Dictionaries?C# 到 Java - 字典?
【发布时间】:2011-10-16 17:37:19
【问题描述】:

在 Java 中是否可以使用已在其中声明的项目制作字典?就像下面的 C# 代码:

   Dictionary<string, int> d = new Dictionary<string, int>()
    {
        {"cat", 2},
        {"dog", 1},
        {"llama", 0},
        {"iguana", -1}
    };

我该怎么做?我使用什么类型?我读过字典已经过时了。

【问题讨论】:

    标签: c# java dictionary map new-operator


    【解决方案1】:

    这会做你想做的事:

    Map<String,Integer> map = new HashMap<String, Integer>(){{
        put("cat", 2);
        put("dog", 1);
        put("llama", 0);
        put("iguana", -1);
    }};
    

    该语句创建了一个HashMap的匿名子类,与父类的唯一区别是在实例创建过程中添加了4个条目。这是 Java 世界中相当普遍的习惯用法(尽管有些人认为它有争议,因为它创建了一个新的类定义)。

    由于这个争议,从 Java 9 开始,出现了一种方便构建地图的新习惯用法:static Map.of methods 家族。

    使用 Java 9 或更高版本,您可以按如下方式创建所需的地图:

    Map<String, Integer> map = Map.of(
        "cat", 2,
        "dog", 1,
        "llama", 0,
        "iguana", -1
    );
    

    对于较大的地图,这个alternative syntax 可能不太容易出错:

    Map<String, Integer> map = Map.ofEntries(
        Map.entry("cat", 2),
        Map.entry("dog", 1),
        Map.entry("llama", 0),
        Map.entry("iguana", -1)
    );
    

    (如果 Map.entry 是静态导入而不是显式引用,这尤其好)。

    除了仅适用于 Java 9+ 之外,这些新方法与之前的方法并不完全相同:

    • 它们不允许您指定使用的 Map 实现
    • 他们只创建不可变的地图
    • 他们不会创建 Map 的匿名子类

    但是,对于许多用例来说,这些差异应该无关紧要,因此对于较新版本的 Java 来说,这是一个很好的默认方法。

    【讨论】:

    • 这里解释了这是做什么的。 techpolesen.blogspot.com/2007/08/…
    • 嗯...双括号语法通常不被认为是好的样式
    • 额外的大括号不是风格的东西。它们既是功能性的,也是将代码表示为初始化块的必要条件。
    • 我在和 fireshadow 交谈,他认为你的意思是“使用一个大括号,而不是两个”而不是“不要匿名子类化 JavaSE 库类只是为了节省一些打字时间。”
    • @Josh Smeaton:不错的文章,虽然其中有一个小错误:内括号是实例初始化器,而不是静态初始化器。
    【解决方案2】:
    Map<String,Integer> map = new HashMap<String, Integer>(){{
    put("cat", 2);
    put("dog", 1);
    put("llama", 0);
    put("iguana", -1);
    }};
    

    【讨论】:

    • 这不能编译,你的答案在你编辑之前是正确的。
    【解决方案3】:

    咬紧牙关,输入地图名称!

        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("cat", 2);
        map.put("dog", 1);
        map.put("llama", 0);
        map.put("iguana", -1);
    

    你也可以做这样的事情,这可能会节省一些输入很长的列表:

        Object[][] values = {
            {"cat", 2},
            {"dog", 1},
            {"llama", 0},
            {"iguana", -1}
        };
    
        for (Object[] o : values) {
            map.put((String) o[0], (Integer) o[1]);
        }
    

    【讨论】:

      【解决方案4】:

      如果您使用Guava library,您可以单独使用它的ImmutableMap 类(示例 1 和 2),或作为 HashMap 的初始化器(示例 3 和 4):

      Map<String, Integer> map1 = ImmutableMap.<String, Integer> builder()
          .put("cat", 2)
          .put("dog", 1)
          .put("llama", 0)
          .put("iguana", -1)
          .build();
      Map<String, Integer> map2 = ImmutableMap.of(
          "cat", 2,
          "dog", 1,
          "llama", 0,
          "iguana", -1
      );
      Map<String, Integer> map3 = Maps.newHashMap(
          ImmutableMap.<String, Integer> builder()
          .put("cat", 2)
          .put("dog", 1)
          .put("llama", 0)
          .put("iguana", -1)
          .build()
      );
      Map<String, Integer> map4 = Maps.newHashMap( ImmutableMap.of(
          "cat", 2,
          "dog", 1,
          "llama", 0,
          "iguana", -1)
      );
      

      【讨论】:

        【解决方案5】:

        Java7 几乎引入了允许这样的语法的“集合文字”。他们可能会尝试在 Java8 中推动它。我不知道这些人有什么问题。

        这可以通过某种封装 API 轻松实现

        Map<String,Integer> map = Maps.<String,Integer>empty()
            .put("cat", 2).put("dog",1)....; 
        

        还不错。我更喜欢类似的东西

        map("cat", "dog", ... )
        .to(  1,     2,   ... );
        

        这种东西肯定是不同人实现的,可惜标准API没有包含这种东西。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-19
          • 2011-10-21
          相关资源
          最近更新 更多