Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 克隆列表-如何完成?_Java_Android_List_Clone_Shallow Copy - Fatal编程技术网

Java 克隆列表-如何完成?

Java 克隆列表-如何完成?,java,android,list,clone,shallow-copy,Java,Android,List,Clone,Shallow Copy,我想制作一个通过方法调用返回的列表的浅层副本(它是来自Android的public List getScanResults(),请参阅)。问题是,clone()不是在列表接口上定义的,而是只在具体的类(如ArrayList)上定义的,但是我不知道getScanResults()在内部使用什么,所以我不能简单地将其强制转换,还是我错了?然后我想到了类似的事情 if(getScanResults() != null) anExistingList.add(getScanResults());

我想制作一个通过方法调用返回的列表的浅层副本(它是来自Android的public List getScanResults(),请参阅)。问题是,clone()不是在列表接口上定义的,而是只在具体的类(如ArrayList)上定义的,但是我不知道getScanResults()在内部使用什么,所以我不能简单地将其强制转换,还是我错了?然后我想到了类似的事情

if(getScanResults() != null)
    anExistingList.add(getScanResults());
添加(getScanResults())

但是,如果没有要返回的内容,getScanResults()似乎会返回null而不是空列表,因此也没有选项。 我什么时候会这样做

if(getScanResults() != null)
    anExistingList.add(getScanResults());
getScanResults()的返回值可能会在第一行和第二行代码之间发生变化,因此它可能会首先传递“not equals null”条件,然后在第二行中为null,或者我错了吗

那么,我应该如何创建getScanResults()返回值的浅拷贝,或者只是制定我的目标:从getScanResults()获取一个值,并确保在使用它时它不会更改

谢谢你的提示:-)
(我想我只是理解错了什么)

java.util.Collections
提供静态方法
copy
将内容从一个列表复制到另一个列表。

所有行为良好的集合都有复制构造函数。因此,根据您的需要(例如,快速索引或高效删除某些元素),创建所需列表类型的实例

在这种情况下,您需要做更多的工作来处理可能出现的null带来的不便。比如说:

/**
 * @return a copy of the original; an empty list if original is null.
 */
public static <T> List<T> randomAccessibleCopy(List<T> original) {
    return (null == original) 
             ? Collections.<T>emptyList() 
             : new ArrayList<T>(original);
}
/**
*@返回原件的副本;如果原始值为空,则为空列表。
*/
公共静态列表randomAccessibleCopy(列表原件){
返回值(null==原始值)
?Collections.emptyList()
:新阵列列表(原件);
}
现在,您可以使用返回列表的基础API的结果调用此方法

if(getScanResults() != null)
    anExistingList.add(getScanResults());
应该是

List x = getScanResults();
if(x != null)
    anExistingList.add(x);

由于该方法现在只被调用一次,因此不能同时更改。

不幸的是,如果getScanResults()返回null,Collections.copy会导致NullPointerException):那么您可能需要调用
getScanResults()
,将其保存到一个临时变量中,检查它是否为null(与您的示例一样)然后继续复制。但是x只是持有对getScanResults()返回值的引用,并且getScanResults()返回值可能会在不调用getScanResults()的情况下更改,例如,如果getScanResults()返回值是一个类变量,它可能会在内部更改。“getter”不应返回修改过的结果。特别是当它被称为“结果”时。API显示:返回最新访问点扫描的结果。这意味着,调用该方法时的最后一次访问点扫描。因此,该列表永远不会被API修改。可以安全使用。注意:即使列表发生变化;它永远不能将对对象的引用从
x
变量更改为null;这在Java中是非法的。但是,它可能会更改其内部状态,但在检查null时这不是问题。因此,即使我上面的评论是错误的(我非常怀疑),它仍然是正确的代码。因此:无论在
getScanResults()
上有什么实现,上面的代码都会给出列表的副本。或者,这是在
List x=getScanResult
中给出的值的副本,或者,当实现修改给定列表时,在
anExistingList中添加(x)
。我很怀疑API是否修改了列表;由于Java中的
List
类是线程不安全的,这意味着一些客户端会在非常罕见的情况下崩溃。如果它想修改返回的列表,它应该返回一个线程安全版本的
列表
,或者在文档中说返回的
列表
是线程安全的。这两种情况都不存在,因此您可以假设调用返回的
列表
永远不会被修改。但是我只能创建目标列表,copy()意味着提供一个副本,而不是从另一个列表复制(在这种情况下是getScanResults())@stefan,我编辑了这篇文章来展示如何处理null。但是,阅读您的其他评论,您似乎也在关注并发的更改。如果返回的基础列表是“live”,那么您使用的API也需要提供一些同步语义。