Java 返回arraylist的常量引用

Java 返回arraylist的常量引用,java,performance,return,const-reference,Java,Performance,Return,Const Reference,我非常欣赏java的特性,我不想在下一个问题上放弃使用它: 我有一个可能被继承的类,其中有一个private ArrayList arr返回const ARR;,它将返回对变量的常量引用 我非常需要不要克隆或手动复制变量,因为有太多的计算需要(只读取变量)为什么java中没有常量返回????我有没有办法逃避抄袭 p、 s(final ArrayList arr;)不是一个选项,因为数组总是更改大小或元素值 如果我找不到解决方法,我威胁要回到C++或使所有的事物公开,而你永远也得不到我的软件:d

我非常欣赏java的特性,我不想在下一个问题上放弃使用它:

我有一个可能被继承的类,其中有一个
private ArrayList arr返回arr
返回对该变量的引用,任何能够编辑整个数组的人都不会使用该变量,而我不希望使用该变量,因为它是私有的

在C++中,我只会写代码>返回const ARR;<代码>,它将返回对变量的常量引用

我非常需要不要克隆或手动复制变量,因为有太多的计算需要(只读取变量)为什么java中没有常量返回????我有没有办法逃避抄袭

p、 s
(final ArrayList arr;)
不是一个选项,因为数组总是更改大小或元素值

如果我找不到解决方法,我威胁要回到C++或使所有的事物公开,而你永远也得不到我的软件:d



编辑:还有一个更重要的问题:我是不是在要求一些不好的东西(软件工程方面),我的意思是如果JAVA创建者认为没有const引用(返回只读引用),那么我必须要求一些可以用其他方式处理的东西。或者我的程序设计错了,我很困惑。

用。它不复制数据,而是包装原始列表,并将只读操作委托给基础列表。将修改列表的操作在运行时通过
UnsupportedOperationException
被拒绝

你的

变成

return Collections.unmodifiableList(arrayList);
不幸的是,编译器不会强制执行只读约束。但是,它们将在运行时强制执行


您还可以使用:、和。如果这些还不够,您仍然可以从这种通用设计方法中获得灵感,创建自己的自定义只读包装类。

:)您有几个选项:

  • 不要公开getter,只提供允许调用的方法,例如

    public void addToList(Object arg){this.arr.add(arg);}

  • 返回不可变对象:

    public List getArr(){return Collections.unmodifiableList(this.arr);}

肯定是答案。

您也可以使用的不可变。在这种情况下,您将在字段中存储一个

当然,如果类需要在内部修改此列表,那么使用ImmutableList可能不是一个好主意,因为每次都需要创建一个新的ImmutableList实例并将其重新分配给字段

但是,当您知道列表在对象构造后不会更改时,这是完美的

不可变示例(对象构造后列表不会更改)
@不可变
公开期末班{
@非空
私人最终不可变名单;
public Foo(@Nonnull List){
//您还可以在此计算适当的列表
//在将其指定给字段之前
this.list=ImmutableList.copyOf(列表);
}
公共ImmutableList getList(){
退货清单;
}
}
可变示例(只能使用setter修改列表)
公共类Foo{
@非空
私有ImmutableList=ImmutableList.of();
公共ImmutableList getList(){
退货清单;
}
public void setList(@Nonnull List){
this.list=ImmutableList.copyOf(列表);
}
}
评论
  • 我知道人们经常建议方法返回最通用的类型(在本例中为
    List
    ),但我更喜欢将getter的返回类型声明为
    ImmutableList
    ,因为它充当文档(无需在Javadoc中记录返回的列表的不变性)和API契约。这就像说“我保证这个列表是不可变的,你不必担心或者防御性地复制它”。而且非常简洁
  • ImmutableList.copyOf()
    非常好,因为它会自动拒绝空列表(通过抛出
    NullPointerException
    )。它还拒绝空元素。如果源列表已经是不可变列表,它就不会复制源列表,这避免了无用的对象实例化
  • 在第二个示例中,我使用
    ImmutableList.of()
    将字段初始化为空的ImmutableList,因为返回空集合而不是空值()是一种很好的做法。您可能认为这会创建不必要的对象实例化,但
    ImmutableList.of()
    实际上会返回一个单例

@GMan:我不同意。如果C++中有什么好的想法,那么学习其他语言中的好思想是值得的。如果没有,这会教你一些关于两种语言的知识。如果Bjarne Stroustrup在C编程时没有考虑过Simula,那么我们就不会有C++了。错误是假设如果C++中的某个东西是好主意,那么它必然是所有其他语言的好主意。”史提夫:我不同意。为什么不干脆去掉“等价物”这个词呢?“其他语言中的好主意是什么”学习好主意之前,你不需要知道任何语言。它不会让你产生不同的好主意,只会让你误入歧途。那么,在尝试学习一门新语言的同时,白日梦有什么好处呢?我会说发明一种新语言是一个完全不同于学习一门语言的任务。@白日做梦的好处是,如果伊斯梅尔不熟悉C++中的const引用,那么他就不容易想到限制他的呼叫者阅读而不写他的数组。当然,他在这个问题上可以少提及C++,并集中在const引用实际完成的核心任务上。我认为通过了解多种语言和范例可以获得很多好处
return Collections.unmodifiableList(arrayList);
@Immutable
public final class Foo {

    @Nonnull
    private final ImmutableList<String> list;

    public Foo(@Nonnull List<String> list) {
        // you could also compute the appropriate list here
        // before assigning it to the field
        this.list = ImmutableList.copyOf(list);
    }


    public ImmutableList<String> getList() {
        return list;
    }
}
public class Foo {

    @Nonnull
    private ImmutableList<String> list = ImmutableList.of();

    public ImmutableList<String> getList() {
        return list;
    }

    public void setList(@Nonnull List<String> list) {
        this.list = ImmutableList.copyOf(list);
    }
}