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

问题描述 投票:0回答:2

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

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

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

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

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

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

java java-8
2个回答
5
投票

不需要在“单个逻辑行”中初始化

static final
变量。

你可以简单地写

private static final List<String> a = new ArrayList<>();
static {
    a.addAll(b);
    a.addAll(c);
    a.add(d);
    a.add(e);
}

这称为静态初始化块。


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

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

private static final List<String> a;
static {
    List<String> tmp = new ArrayList<>();
    tmp.addAll(b);
    tmp.addAll(c);
    tmp.add(d);
    tmp.add(e);
    a = List.copyOf(tmp);
}

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

List.copyOf(…)
创建一个不可变的副本,但请注意它不允许
null
)。


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

private static final List<String> a = createA();

private static List<String> createA() {
    List<String> tmp = new ArrayList<>();
    tmp.addAll(b);
    tmp.addAll(c);
    tmp.add(d);
    tmp.add(e);
    return List.copyOf(tmp);
}

1
投票

如果你想要单行,你可以使用 Stream API:

private static final List<String> a = Stream.of(b, c, List.of(d), List.of(e))
        .flatMap(List::stream)
        .toList();

从 JDK 16+ 开始,

mapMulti
可以避免过度的平面映射:

private static final List<String> a = Stream.of(b, c, List.of(d), List.of(e))
        .<String>mapMulti(Iterable::forEach)
        .toList();
© www.soinside.com 2019 - 2024. All rights reserved.