Android (java)开发遇到的 ArrayList 嵌套赋值的怪现象,求高人指点。

2016-01-30 16:52:39 +08:00
 Neveroldmilk

我建了一个两层嵌套的 ArrayList,给他赋值的过程中出了奇怪的现象,就是使用.get()获得特定的第一维元素之后,再继续.set 第二维元素时就会使得所有的元素被赋予了同样的数值,具体代码如下:

private List<List<Double>> SourceDataPosition = new ArrayList<List<Double>>(Collections.nCopies(3,new ArrayList<Double>(Collections.nCopies(3,Double.valueOf(0)))));

public boolean SetSourcePosition (double[][] InputSourcePosition) {

for ( int FirstDimensionIndex = 0 ; FirstDimensionIndex < InputSourcePosition.length; FirstDimensionIndex ++){

        for ( int SecondDimensionIndex = 0 ; SecondDimensionIndex < InputSourcePosition[FirstDimensionIndex].length; SecondDimensionIndex ++){
         this.SourceDataPosition.get(FirstDimensionIndex).set(SecondDimensionIndex, InputSourcePosition[FirstDimensionIndex][SecondDimensionIndex]);

        }

    }
    return true;
}




比如说,我定义
double[][] InputSourcePosition = {{20.0,50,80},{30.0,60,90},{40.0,70,0}} ;
理论上应该生成同样的二维 ArrayList ,但是输出结果却是 {{40.0,70,0},{40.0,70,0},{40.0,70,0}}。
难道说 ArrayList.get 是获得了二维数组的第一列元素?而不是第一个一维对象么?我不知道自己的意思表达清楚没有。抱歉排版啊,不知道怎么 V2EX 弄成了这个鸟样。
6359 次点击
所在节点    Android
6 条回复
incompatible
2016-01-30 17:02:21 +08:00
问题出在这句上: private List<List<Double>> SourceDataPosition = new ArrayList<List<Double>>(Collections.nCopies(3,new ArrayList<Double>(Collections.nCopies(3,Double.valueOf(0)))));

最终生成的 SourceDataPosition 里的 3 个 ArrayList 是同一个对象。
Neveroldmilk
2016-01-30 17:08:13 +08:00
哦, Collections.nCopies 不能嵌套使用么?那请问要初始化这个嵌套 ArrayList 的元素数值该怎么做呢?只能一个个赋值?
incompatible
2016-01-30 17:24:52 +08:00
@Neveroldmilk 你可以读一下 Collections.nCopies()的源码,它生成的是一个 CopyList ,每次调用这个 CopyList 的 get()返回的都是同一个对象。

对于你这个问题,据我所知的确是只能一个个赋值(也许 jdk 或其它公共库提供了相关方法,等待其他网友补充好了)。但是为了防止以后需求变动时 n 会发生改变你可以写一个 for 循环来完成这 n 次赋值。
SoloCompany
2016-01-30 19:57:45 +08:00
nCopies 是给数组批量赋值,不是 clone 之后赋值,请先搞清楚这一点上的区别
acjiji
2016-01-30 20:42:39 +08:00
你这里字段 SourceDataPosition 是一个 list ,里面有三个元素(引用),因为 nCopies 的特殊性,这三个引用都指向同一个 list 也就是说 this.SourceDataPosition.get(FirstDimensionIndex)都是返回了同一个 list 。你的 SetSourcePosition 方法只改变了第二维元素的引用,所以导致了你那样的结果。

如果你在第一个 for 循环之后加上:
SourceDataPosition.set(FirstDimensionIndex,new ArrayList<Double>(Collections.nCopies(3,Double.valueOf(0))));
这个时候你也改变了第一维引用指向的对象,就可以得到你期望的结果。

个人 YY ,如有错误,欢迎指出,谢谢!!!
Neveroldmilk
2016-01-31 11:31:32 +08:00
多谢各位高人指点。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/254470

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX