如何从Java中的CopyOnWriteArrayList中获取底层静态数组?

如何从Java中的CopyOnWriteArrayList中获取底层静态数组?,java,arrays,copy-on-write,Java,Arrays,Copy On Write,我有一个类,它维护该类的一系列特性。与读取相比,这些特性很少发生变化。读取几乎总是通过功能列表进行迭代。因此,我使用的是CopyOnWriteArrayList 我想要一个这样的函数: function Feature[] getFeatures() { .. implementation goes here .. } for (Feature f: object.getFeatures()) { .. do something interesting .. } 我承认,原因可能是有

我有一个类,它维护该类的一系列特性。与读取相比,这些特性很少发生变化。读取几乎总是通过功能列表进行迭代。因此,我使用的是
CopyOnWriteArrayList

我想要一个这样的函数:

function Feature[] getFeatures() {
  .. implementation goes here ..
}
for (Feature f: object.getFeatures()) {
  .. do something interesting ..
}
我承认,原因可能是有点懒惰。我想写这样的代码:

function Feature[] getFeatures() {
  .. implementation goes here ..
}
for (Feature f: object.getFeatures()) {
  .. do something interesting ..
}
与此相反:

Iterator<Feature> iter = object.getFeatureIterator();
while (iter.hasNext()) {
  Feature f = iter.next();
  .. do something interesting ..
}
Iterator iter=object.getFeatureIterator();
while(iter.hasNext()){
特征f=iter.next();
做点有趣的事。。
}
主要问题是——我在这里懒惰吗?我将经常遵循这种模式,我认为第一段代码更容易维护。显然,我永远不会更改底层数组,我会将其放在文档中


处理这种情况的正确方法是什么?

我不理解您的原因:返回
列表,使用您的
CopyOnWriteArrayList
或不可修改的副本,并使用
foreach
。你为什么特别想要一个数组?

我不明白你的理由:返回一个
列表,使用你的
copyonwritearaylist
或不可修改的副本,然后使用
foreach
。为什么特别需要数组?

只需调用列表中的toArray方法:

public Feature[] getFeatures() {
    return this.featureList.toArray(new Feature[this.featureList.size()]);
}
public List<Feature> getFeatures() {
    return Collections.unmodifiableList(this.features);
}
请注意,foreach语法可以用于所有Iterable对象,而List是Iterable,因此您可以

public List<Feature> getFeatures() {
    return this.features;
}
public List getFeatures(){
返回此文件。返回特征;
}
并使用相同的foreach循环。如果不希望呼叫者修改内部列表,请返回列表的不可修改视图:

public Feature[] getFeatures() {
    return this.featureList.toArray(new Feature[this.featureList.size()]);
}
public List<Feature> getFeatures() {
    return Collections.unmodifiableList(this.features);
}
public List getFeatures(){
返回集合。不可修改列表(this.features);
}

只需调用列表中的toArray方法:

public Feature[] getFeatures() {
    return this.featureList.toArray(new Feature[this.featureList.size()]);
}
public List<Feature> getFeatures() {
    return Collections.unmodifiableList(this.features);
}
请注意,foreach语法可以用于所有Iterable对象,而List是Iterable,因此您可以

public List<Feature> getFeatures() {
    return this.features;
}
public List getFeatures(){
返回此文件。返回特征;
}
并使用相同的foreach循环。如果不希望呼叫者修改内部列表,请返回列表的不可修改视图:

public Feature[] getFeatures() {
    return this.featureList.toArray(new Feature[this.featureList.size()]);
}
public List<Feature> getFeatures() {
    return Collections.unmodifiableList(this.features);
}
public List getFeatures(){
返回集合。不可修改列表(this.features);
}
类实现了
Iterable
,这就是使用sugared
for
循环语法所需的全部内容。在上面描述的情况下,您不需要显式地掌握
迭代器

您发现它没有编译吗?

类实现了
Iterable
,这就是您使用sugared
进行循环语法所需的全部内容。在上面描述的情况下,您不需要显式地掌握
迭代器

您发现它没有编译吗?

您可以克隆列表

public List<Feature> getFeatures() {
    return (List<Feature>)this.features.clone();
}
public List getFeatures(){
返回(列出)this.features.clone();
}
克隆copyOnWriteArrayList不会复制基础数组

您可以克隆该列表

public List<Feature> getFeatures() {
    return (List<Feature>)this.features.clone();
}
public List getFeatures(){
返回(列出)this.features.clone();
}
克隆copyOnWriteArrayList不会复制底层数组

写入时复制(COW)属性的
copyonWriterarayList
对象意味着,在列表的每次修改中,您都会得到其基础数组的新实例,其中包含所有条目,但修改都是从上一个实例复制的

为了在其他线程不断更改列表内容时在列表上迭代时提供一致的视图,调用
iterator()
方法将迭代器绑定到数组,而不是列表。当修改更改列表时,新数组将保存新内容,但迭代器将继续运行调用
iterator()
时可用的旧数组。这意味着您将浏览列表的一致快照

(相反,像
for(int i=0;i
这样的循环不会保护您免受其他线程的修改,如果在调用
list.size()
和相应的
list.get(i)
之间,某些元素已被删除,您可能会很容易地跑出列表末尾!)

由于for-each样式for循环在幕后使用迭代器,因此可以得到这种一致性保证。使用
forEach()
方法时也会得到它。这将在调用
forEach()
时在可用的数组中迭代(使用数组索引)

最后,
clone()
方法基本上会获取类似的快照。如果您的代码是唯一使用克隆版本的地方,或者您使其不可修改,那么您将查阅原始快照。原稿的牛本性保护您的副本不受原稿更改的影响。如果您不想依赖具有的
clone()
,您可以复制列表数据,但这至少涉及使用另一个分配复制数组。
copyonwritearaylist
对象的写入时复制(COW)性质意味着每次修改列表时,您都会得到其基础数组的新实例,除了从上一个实例复制的修改之外,其他所有条目都包含

为了在其他线程不断更改列表内容时在列表上迭代时提供一致的视图,调用
iterator()
方法将迭代器绑定到数组,而不是列表。当修改更改列表时,新数组将保存新内容,但迭代器将继续运行调用
iterator()
时可用的旧数组。这意味着您将浏览列表的一致快照

(相反,像
for(int i=0;i
这样的循环不能保护您免受其他线程的修改,如果在调用
list.size()和