Java Lazy使用Collections.emptyList()声明后将列表重新设置为可修改

Java Lazy使用Collections.emptyList()声明后将列表重新设置为可修改,java,reference,new-operator,Java,Reference,New Operator,要将列表声明为list info=Collections.emptyList() 但当用户调用add(stringmsg)时,则重新初始化到可修改列表 这是正确的方法吗 private List<String> info = Collections.emptyList(); public void addInfo(String s){ final List<String> e = Collections.emptyList(); if(in

要将列表声明为
list info=Collections.emptyList()
但当用户调用add(stringmsg)时,则重新初始化到可修改列表

这是正确的方法吗

private List<String> info = Collections.emptyList();
public void addInfo(String s){
        final List<String> e = Collections.emptyList();
        if(info == e){
            info = new ArrayList<>();
        }
        info.add(s);
    }
我想由于创建了新的列表,以下内容将不起作用

private void addTo(String s, @org.jetbrains.annotations.NotNull List<String> t){
    final List<String> e = Collections.emptyList();
    if(t.equals(e)){
        t = new ArrayList<>();
    }
    t.add(s); 
}
private void addTo(字符串s,@org.jetbrains.annotations.NotNull List t){
最终列表e=Collections.emptyList();
如果(t等于(e)){
t=新的ArrayList();
}
t、 添加(s);
}
考虑到您的代码:

    final List<String> e = Collections.emptyList();
    if(info == e){
        info = new ArrayList<>();
    }
    info.add(s);
鉴于您将要向其中添加一项,此测试无论如何只会通过一次。

考虑到您的代码:

    final List<String> e = Collections.emptyList();
    if(info == e){
        info = new ArrayList<>();
    }
    info.add(s);

如果您将要向其中添加一个项目,此测试无论如何只会通过一次。

使用
。equals
是唯一正确的解决方案,但与更简单的
信息相当。isEmpty()
使用
。equals
是唯一正确的解决方案,但与更简单的
信息相当。isEmpty()

请注意,即使
Collections.emptyList()
始终返回
Collections.EMPTY\u LIST
中保存的一个实例,当调用方使用JDK 9+
LIST.of()
初始化字段时,引用比较也不会检测到。另一方面,非空也不能保证可变性

整个逻辑仅适用于
private
方法,因为所有调用方及其用法都是已知的

但是你应该考虑放弃这些特殊情况。自Java 8以来,默认构造函数
new ArrayList()
将不会创建备份数组。它被推迟到元素的第一次添加


因此,您可以使用普通的
new ArrayList()
初始化所有字段,并使用普通的
add
调用实现
addInfo
addWarn
addrr
,从而摆脱
addTo
方法、条件和重复赋值。甚至可以声明字段
final
。尽管未使用的列表仍然不需要大量内存。

请注意,即使
Collections.emptyList()
始终返回
Collections.EMPTY\u LIST
中保存的一个实例,调用方使用JDK 9+
LIST.of()
初始化字段时,引用比较也不会检测到。另一方面,非空也不能保证可变性

整个逻辑仅适用于
private
方法,因为所有调用方及其用法都是已知的

但是你应该考虑放弃这些特殊情况。自Java 8以来,默认构造函数
new ArrayList()
将不会创建备份数组。它被推迟到元素的第一次添加


因此,您可以使用普通的
new ArrayList()
初始化所有字段,并使用普通的
add
调用实现
addInfo
addWarn
addrr
,从而摆脱
addTo
方法、条件和重复赋值。甚至可以声明字段
final
。但对于未使用的列表仍然不需要大量内存。

谢谢,这是最简单的方法。另外,我想对于第二个问题,如果我创建了一个新对象,是否需要返回ref
if(t.isEmpty()){t=newarraylist();}返回t?@sprinter,如前所述,您确实需要返回引用。如果集合最初为空,则OP的最后一个代码示例为no OP。谢谢,这是最简单的方法。另外,我想对于第二个问题,如果我创建了一个新对象,是否需要返回ref
if(t.isEmpty()){t=newarraylist();}返回t?@sprinter,如前所述,您确实需要返回引用。如果集合最初为空,则OP的最后一个代码示例为no OP。使用empty,但另一种方法是
final static List empty\u List=Collections.emptyList();列表信息=空列表然后我认为在func中可以使用info==EMPTY\u LIST,虽然不是“普通”的Java代码,但可以工作。我喜欢这样,因为我们使用这个对象从API返回信息。在98%的情况下,列表是空的。但是在2%的情况下,当我们有警告,错误。。。需要适应他们。这样节省内存有助于拉伸节点以处理更多TXN。有时节点的负载是3倍,从每秒10个事务增加到30个(每个节点),这有助于减少使用empty所需的总节点数,但另一种方法是
final static List empty_List=Collections.emptyList();列表信息=空列表然后我认为在func中可以使用info==EMPTY\u LIST,虽然不是“普通”的Java代码,但可以工作。我喜欢这样,因为我们使用这个对象从API返回信息。在98%的情况下,列表是空的。但是在2%的情况下,当我们有警告,错误。。。需要适应他们。这样节省内存有助于拉伸节点以处理更多TXN。有时节点的负载是3倍,从每秒10个事务增加到30个事务(每个节点),这有助于降低需要了解、研究和返回的节点总数
if (info.isEmpty())
    info = new ArrayList<>();