使用 HashMap 和 List 进行嵌套双括号初始化

Nested Double Brace Initialization with HashMap and List

我正在尝试控制我的应用程序的某些权限。 昨天我学习了如何创建 Double Brace Initialization,它帮助很大。但现在我试图嵌套使用它,但我得到了

')' expected

来自 IDE(Android 工作室)

这是我的代码:

public static final Map<String, List> ALL_PERMISSIONS = new HashMap<String, List>() {{
    put("Change-maps", new ArrayList<Integer>(){{add(R.id.button_change_view);}};);
    put("Stores-info-view", new ArrayList<Integer>(){{add(R.id.details_fragment);}};);
    put("Competitors-layer", new ArrayList<Integer>(){{add(R.id.switch_concorrentes);}};);
}};

我是不是遗漏了什么? 这是一个糟糕的方法吗?

PS:我正在尝试这种方法,因为将来我会使用一些具有多个视图(整数)的键,以及一些具有字符串列表的键。

如果您查看这段代码:

Map<String, String> map = new HashMap<String, String>();
map.put( "string1", "string2" );

您可以注意到您传入参数的对象后面没有跟;

在你的例子中,你传递的第二个对象是这个:

new ArrayList<Integer>(){{add(R.id.button_change_view);}}

所以,您不需要在 put 的右括号前加上 ;,像这样:

public static final Map<String, List> ALL_PERMISSIONS = new HashMap<String, List>() {{
        put("Change-maps", new ArrayList<Integer>(){{add(R.id.button_change_view);}});
        put("Stores-info-view", new ArrayList<Integer>(){{add(R.id.details_fragment);}});
        put("Competitors-layer", new ArrayList<Integer>(){{add(R.id.switch_concorrentes);}});
}};

您应该 format/indent 您的代码(在 Eclipse 中默认为 Ctrl-Shift-F)。

您会看到您的匿名 ArrayList class 声明(在大括号外)后面不能跟分号。

这是一个可以使用的格式化示例:

public static final Map<String, List> ALL_PERMISSIONS = new HashMap<String, List>() {
    {
        put("Change-maps", new ArrayList<Integer>() {
            {
                add(R.id.button_change_view);
            }
        });
        put("Stores-info-view", new ArrayList<Integer>() {
            {
                add(R.id.details_fragment);
            }
        });
        put("Competitors-layer", new ArrayList<Integer>() {
            {
                add(R.id.switch_concorrentes);
            }
        });
    }
};

备注

还要注意原始类型或取消警告。

我不鼓励使用双括号初始化。正如 this answer 解释的那样,它可能

  1. surprises your colleagues and is hard to read
  2. harms performance
  3. may cause problems with object equality (each object created has a unique class object).

如果可能的话,我建议使用 Guava ImmutableMap and ImmutableList

例如:

public static final Map<String, List> ALL_PERMISSIONS =  ImmutableMap.<String, List>of(
        "Change-maps", ImmutableList.of(R.id.button_change_view),
        "Stores-info-view", ImmutableList.of(R.id.details_fragment),
        "Competitors-layer", ImmutableList.of(R.id.switch_concorrentes)
);

或者如果您需要添加更多元素:

public static final Map<String, List> ALL_PERMISSIONS =  new ImmutableMap.Builder<String, List>()
        .put("Change-maps", ImmutableList.of(R.id.button_change_view))
        .put("Stores-info-view", ImmutableList.of(R.id.details_fragment))
        .put("Competitors-layer", ImmutableList.of(R.id.switch_concorrentes))
        //(... and so on...
        .build();