V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Neveroldmilk
V2EX  ›  Android

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

  •  
  •   Neveroldmilk · 2016-01-30 16:52:39 +08:00 · 5730 次点击
    这是一个创建于 2980 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我建了一个两层嵌套的 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 弄成了这个鸟样。
    
    6 条回复    2016-01-31 11:31:32 +08:00
    incompatible
        1
    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
        2
    Neveroldmilk  
    OP
       2016-01-30 17:08:13 +08:00
    哦, Collections.nCopies 不能嵌套使用么?那请问要初始化这个嵌套 ArrayList 的元素数值该怎么做呢?只能一个个赋值?
    incompatible
        3
    incompatible  
       2016-01-30 17:24:52 +08:00 via iPhone
    @Neveroldmilk 你可以读一下 Collections.nCopies()的源码,它生成的是一个 CopyList ,每次调用这个 CopyList 的 get()返回的都是同一个对象。

    对于你这个问题,据我所知的确是只能一个个赋值(也许 jdk 或其它公共库提供了相关方法,等待其他网友补充好了)。但是为了防止以后需求变动时 n 会发生改变你可以写一个 for 循环来完成这 n 次赋值。
    SoloCompany
        4
    SoloCompany  
       2016-01-30 19:57:45 +08:00
    nCopies 是给数组批量赋值,不是 clone 之后赋值,请先搞清楚这一点上的区别
    acjiji
        5
    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
        6
    Neveroldmilk  
    OP
       2016-01-31 11:31:32 +08:00
    多谢各位高人指点。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   943 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:00 · PVG 05:00 · LAX 14:00 · JFK 17:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.