【问题标题】:Android - Working with Multidimensional String ArraysAndroid - 使用多维字符串数组
【发布时间】:2013-01-13 00:41:40
【问题描述】:

我在处理多维字符串数组时遇到了问题,希望能得到澄清。

我将在下面发布一个示例代码,我编写该示例代码只是为了了解多维字符串数组的工作原理。我在 cmets 中写下了我期望发生的事情以及我期望的结果,但事实并非如此。我的问题几乎是为什么它不像我想的那样工作,它应该创建矩阵 [1][2][3]

[4][5][6]

还有一个额外的问题,如果我已经设置了 2x3 矩阵,我如何重新分配特定元素中的值,例如 [1][1],或者我是否必须调用该行并将其分配给多变的。整个示例代码让我学习如何在多维字符串数组中分配元素,然后重新分配它们。这些字符串数组列表,我不知道提前的维度和值的变化,我需要使用.add方法并最终使用.set。

提前感谢您的帮助,Stack Overflow 上似乎是一个很棒的社区

TextView displayanswer;
String text0, text1, text2, text3, text4, text5, text6;
ArrayList<String> column = new ArrayList<String>();
ArrayList<ArrayList<String>> row = new ArrayList<ArrayList<String>>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test1);
    displayanswer = (TextView) findViewById(R.id.textView1);

    //Creates Matrix in column variable of [1][2][3]
    column.add("1");
    column.add("2");
    column.add("3");  

    row.add(column);  //Creates Matrix in row variable of [1][2][3]
    row.add(column);  //Creates 2 dimension matrix of  [1][2][3]
                     //                                [1][2][3]

    column.set(0, "4"); //column variable Matrix becomes  [4][2][3]
    column.set(1, "5"); //column variable Matrix becomes  [4][5][3]
    column.set(2, "6"); //column variable Matrix becomes  [4][5][6]
    row.set(1,column);  //2 dimensional matrix becomes  [1][2][3]
                                                                  //[4][5][6]

           column = row.get(0); //get first row of 2 row matrix, should be[1][2][3]

    //Assigning first row elements to text strings
    text0 = column.get(0); text1 = column.get(1); text2 = column.get(2);

    column = row.get(1); //gets second row of 2 row matrix, should be [4][5][6]

    //Assigning second row elements to text strings
    text3 = column.get(0); text4 = column.get(1); text5 = column.get(2);

    //should give me 123456 but instead I get 456456???
    displayanswer.setText(""+text0 +text1 +text2 +text3 +text4 +text5);

}

}

【问题讨论】:

    标签: android string multidimensional-array matrix


    【解决方案1】:

    我猜您是在假设当您向列表中添加某些内容时,它会创建数据的副本。然而,事实并非如此。该列表将包含对您正在添加的数据的引用,而不是实际内容本身的(副本)。

    所以即使下面的 cmets 是正确的,因为您要添加两次“列”对象...

    row.add(column);  //Creates Matrix in row variable of [1][2][3]
    row.add(column);  //Creates 2 dimension matrix of  [1][2][3]
    

    ...两个列表条目将引用同一个对象。然后,通过尝试更改一列的值,您实际上是在更改引用的对象,因此您正在更改两个条目。这就是你最终得到“456456”的原因。

    这实际上会影响两列,因为前两个位置引用了同一个对象:

    column.set(0, "4"); //column variable Matrix becomes  [4][2][3]
    column.set(1, "5"); //column variable Matrix becomes  [4][5][3]
    column.set(2, "6"); //column variable Matrix becomes  [4][5][6]
    

    以下说法不正确:

    row.set(1,column);  //2 dimensional matrix becomes  [1][2][3]
                                                                  //[4][5][6]
    

    两个条目都发生了变化(因为它们都引用同一个对象),因此您最终得到:

    [4][5][6]
    [4][5][6]
    

    要“修复”此问题,请确保在添加第二列之前创建一个新的“列”对象。或者,如果您希望继续修改同一个对象,请确保将数据的副本添加到列表中。例如:

    //Creates Matrix in column variable of [1][2][3]
    column.add("1");
    column.add("2");
    column.add("3");
    
    row.add(new ArrayList<String>(column));
    row.add(new ArrayList<String>(column));
    

    之后,您可以安全地更改column,而不会影响列表的内容。您也可以直接操作列表内容,因为我们将数据的副本添加为行,因此每个条目都指向不同的对象。希望这是有道理的。

    附带说明:如果您打算做更复杂的事情,我可能会考虑创建一个实际的Matrix 类。列表对于表示矩阵并不是特别理想。或者,您周围可能有大量矩阵实现可以学习或借鉴。只是一个想法。 :)

    【讨论】:

    • 感谢您的解释和修复,非常感谢!像你这样的人让这个社区变得很棒:)
    【解决方案2】:

    看看你做了什么:

    column.add("1");
    column.add("2");
    column.add("3");
    

    column.set(0, "4"); //column variable Matrix becomes  [4][2][3]
    column.set(1, "5"); //column variable Matrix becomes  [4][5][3]
    column.set(2, "6"); //column variable Matrix becomes  [4][5][6]
    

    这就是您看到 456 的原因,因为您正在用 4、5 和 6 覆盖索引 0、1 和 2

    我为您制作了一个测试脚本,以便您更好地理解它:

    import java.util.ArrayList;
    
    
    public class Initialize {
    
    static ArrayList<String> column = new ArrayList<String>();
    static ArrayList<String> newColumn  = null;
    static ArrayList<ArrayList<String>> row = new ArrayList<ArrayList<String>>();
    
    public static void main(String[] str){
    
        // Stuffing the column ArrayList for later use
        for( int i = 1; i <= 6; i++ ){
            column.add( Integer.toString(i) );
            if( i == 6 ){
                row.add( column );
                break;
            }
        }
    
    
        for( int rowsCounter = 0; rowsCounter < row.size(); rowsCounter++ ){
            //this is where you can print the row content
            System.out.println( "Row index: " + rowsCounter );
    
            //passing the row content to a new ArrayList so that we can print the elements for the next loop
            if( newColumn == null ){
                newColumn = new ArrayList<String>();
            }
            newColumn = row.get(rowsCounter);
    
            for( int colsCounter = 0; colsCounter < column.size(); colsCounter++ ){
                //this is where you can print the column content
                System.out.println( "Column index: " + colsCounter + " | value: " + column.get(colsCounter) );
            }
    
        }
    }
    

    }

    如果您仍然不明白,请尝试重复,如果您遇到困难,请寻求帮助!祝你好运!

    【讨论】:

      【解决方案3】:

      借助 MH 的回答,我想出了一个简单的例子:

      (我遇到的最大问题与 OP 相同:带有内部数组列表的数组列表仅创建引用,而不是副本!下面的示例创建副本)

      //Create list objects
      ArrayList<String> innerArray = new ArrayList<String>();     //Columns with data
      ArrayList<ArrayList<String>> outterArray = new ArrayList<ArrayList<String>>();  //Rows with columns
      
      //Populate row 1
      innerArray.add("Row1: Column1");                        //column1
      innerArray.add("Row1: Column2");                        //column2
      innerArray.add("Row1: Column3");                        //column3
      outterArray.add(new ArrayList<String>(innerArray));     //add contents to main array
      innerArray.clear();                                     //clear contents since we added it to main array and want it empty for next row
      
      //Populate row 2
      innerArray.add("Row2: Column1");                        //column1
      innerArray.add("Row2: Column2");                        //column2
      innerArray.add("Row2: Column3");                        //column3
      outterArray.add(new ArrayList<String>(innerArray));                                 //add contents to main array
      innerArray.clear();                                     //clear contents since we added it to main array and want it empty for next row
      
      //Display all data from array
      int index=0;
      for(ArrayList<String> row : outterArray){
          Log.w(TAG,"(Row"+index+") " + row.get(0) + " | "+row.get(1)+ " | "+row.get(2));
          index++;
      }
      

      【讨论】:

        猜你喜欢
        • 2011-07-22
        • 2011-08-16
        • 1970-01-01
        • 1970-01-01
        • 2010-11-07
        • 2014-04-18
        • 2014-02-01
        • 2013-11-05
        • 2015-06-16
        相关资源
        最近更新 更多