在Java中将列表与单个元素连接到单个逻辑行中的正确方法?

Gou*_*hor 2 java java-8

在我的代码中,我有这个:

    private static final List<String> a = new ArrayList<String>() {{
        addAll(b);
        addAll(c);
        add(d);
        add(e);
    }};
Run Code Online (Sandbox Code Playgroud)

我在某些地方读到双括号语法创建了一个匿名类或其他东西,这是一种非常糟糕的语法。

由于这是一个静态最终变量,因此需要在单个逻辑行中设置它。

我找到了使用流在单行中连接列表的代码示例,但没有一个允许添加单个元素。

我正在寻找一种与 Java 8 兼容的语法,但(如果不同)仅与更高版本的 Java 兼容的更好语法也将受到欢迎。

Hol*_*ger 12

不需要static final在 \xe2\x80\x9c 单逻辑行\xe2\x80\x9d 中初始化变量。

\n

你可以简单地写

\n
private static final List<String> a = new ArrayList<>();\nstatic {\n    a.addAll(b);\n    a.addAll(c);\n    a.add(d);\n    a.add(e);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这称为静态初始化块。

\n
\n

请注意,由于此列表在整个运行时保持可变,因此您可以随时随地添加到列表中。

\n

由于您可能不想要这个,而是使用类初始化的真正不可变的列表,您甚至可以编写

\n
private static final List<String> a;\nstatic {\n    List<String> tmp = new ArrayList<>();\n    tmp.addAll(b);\n    tmp.addAll(c);\n    tmp.add(d);\n    tmp.add(e);\n    a = List.copyOf(tmp);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

换句话说,将最终结果分配给初始化块末尾的字段。

\n

List.copyOf(\xe2\x80\xa6)(自 Java\xc2\xa09 起)创建一个不可变的副本,但不允许使用null元素,并且通常具有非常严格的行为。null

\n

如果您需要一个支持 null 的不可修改列表,则可以使用tmp.stream().toList()(since Java\xc2\xa016)。

\n
\n

但即使对于那些不了解静态初始化器的人来说,对于复杂的字段初始化器也有一个非常简单的解决方案:

\n
private static final List<String> a = createA();\n\nprivate static List<String> createA() {\n    List<String> tmp = new ArrayList<>();\n    tmp.addAll(b);\n    tmp.addAll(c);\n    tmp.add(d);\n    tmp.add(e);\n    return List.copyOf(tmp);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • `List.copyOf(…)` 返回的列表不允许 `null` 元素,甚至在尝试 `contains(null)` 时抛出异常。如果您需要“null”支持,可以使用“tmp.stream().toList()”(使用最新的 Java 版本)。您可以拥有任意多个初始化块,但您也可以在一个块中编写多个变量的代码。由你决定。是的,它适用于所有类型的对象,包括“Set”。 (2认同)