【问题标题】:Android Arrays contents are getting changed for no reasonAndroid Arrays 内容无缘无故地被更改
【发布时间】:2011-08-05 01:20:23
【问题描述】:

我正在尝试在我的活动中创建一个 ExpandableListView,它在顶层显示葡萄酒的类型,在第二层显示个别瓶装葡萄酒。我正在从我创建的 CSV 文件中读取我的所有数据,并填充了 8 瓶特定的葡萄酒,这些葡萄酒目前都属于一个类别。我遇到了一个问题,我正在将我的数据从 csv 文件读取到一个数组中,我可以在读取它时将其报告给日志,并且它显示正确。但是,一旦我尝试将它放入我的适配器,然后放入列表视图中,数组中就会充满 8 个相同的 Wine 对象,这些对象是我文件中的最后一个对象。

这是我用来读取文件并创建 Wine 对象数组的代码。

编辑:我更改了代码以在 while 循环完成填充后检查我的数组写入,并且得到相同的结果。这是较新版本的代码。

        handler = new Handler()
    {

        @Override
        public void handleMessage(Message msg)
        {
            Log.i(myTag, "Notify Change");
            //By the time I get to here every object in the array is identical
            for(int i = 0; i < chrd.length; i++){
                Log.i(myTag,i + " " + chrd[i].toString());
            }


            super.handleMessage(msg);
        }

    };



    Runnable r = new Runnable(){
        public void run()
        {

            current = new Chardonnay();
            //final int ITEMS = 15;
            int count = 0;

            try {
                File myFile = new File ("/sdcard/chardonnay.txt");
                fis = new FileInputStream(myFile); 
                BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
                String line;
                while ((line = reader.readLine()) != null) {
                     String[] RowData = line.split(",");
                     current.setName(RowData[0]);
                     current.setPlace(RowData[1]);
                     current.setDescription(RowData[2]);
                     current.setYear(Integer.valueOf(RowData[3]));
                     current.setPriceBottle(Integer.valueOf(RowData[4]));
                     current.setPriceGlass(Integer.valueOf(RowData[5]));

                     chrd[count] = current;
                     Log.i(myTag, count + " " + chrd[count]);
                     count++;
                }

                for(int i = 0; i < chrd.length; i++){
                    Log.i(myTag,i + " " + chrd[i]);
                }
            }
            catch (IOException ex) {
                // handle exception
                ex.printStackTrace();
            }


            handler.sendEmptyMessage(1);
            try {
                fis.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }


        }
    };
    Thread thread = new Thread(r);
    thread.start();
}

这是运行它创建的日志输出:

04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 0 Wine [name=Acre, place=Central Coast, description=Seductive apple pie crust and lemon blossom aromas introduce crisp juicy flavors enriched by a creaminess resulting from surlie barrel aging, year=2008, priceBottle=25, priceGlass=7]
04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 1 Wine [name=Silver Palm, place=North Coast, description=Fermented in stainless steel* this wine's delicate fruit characteristics were preserved without any overbearing flavors that an oak barrel might impart, year=2009, priceBottle=30, priceGlass=10]
04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 2 Wine [name=Franciscan, place=Napa Valley, description=Ripe* generous aromas of apple* pear* and honey with toasty oak. Lively* rich creamy and supple with notes of vanilla on the finish, year=2009, priceBottle=30, priceGlass=-1]
04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 3 Wine [name=Sonoma Cutrer, place=Russian River, description=The 2nd most popular chardonnay in W&S Restaurant Poll* this wine is beautifully balanced with well integrated oak, year=2008, priceBottle=35, priceGlass=11]
04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 4 Wine [name=Matanzas Creek, place=Sonoma, description=92 pts WE* this wine has a silky texture with flavors of lemon cream* peach and pear which feels elegant and creamy on the palate, year=2007, priceBottle=40, priceGlass=-1]
04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 5 Wine [name=Silver by Mer Soleil, place=Santa Lucia Highlands, description=Combines ripe* intense peach* nectarine and tangerine fruit with touches of floral and spice, year=2007, priceBottle=40, priceGlass=-1]
04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 6 Wine [name=Jordan, place=Russian River, description=Voted Best Chardonnay by respected wine journalists who attended 2010 Critics Challenge, year=2008, priceBottle=50, priceGlass=-1]
04-13 15:45:09.390: INFO/One2OneWineMenu(6472): 7 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): Notify Change
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 0 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 1 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 2 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 3 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 4 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 5 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 6 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]
04-13 15:45:09.405: INFO/One2OneWineMenu(6472): 7 Wine [name=Ramey, place=Santa Lucia Highlands, description=94 pts RP* intense and vibrant* shows full-bodied citrus* melon* and hazelnut flavors that turn subtle and offer hints of fig/tangerine, year=2007, priceBottle=90, priceGlass=-1]

我尝试了相同的逻辑概念,但使用 ArrayList 而不是 Wine[] 并且它有同样的问题。我被难住了,我从来没有见过 Array 的内容会因为这样的明显原因而改变。也许我忽略了一些相对简单的事情,有没有人知道这里可能发生了什么?

【问题讨论】:

  • chrd 定义是必需的......充满了决赛,静力学和东西
  • 您如何为 ExpandableListAdapter 格式化数据。根据我的经验,必须将组格式化为 List>,将子组格式化为 List>>。我在答案中提供了一些示例代码来说明。
  • chrd 是这样定义的:Wine[] chrd;和 chrd = new Wine[8];

标签: android arrays arraylist expandablelistview


【解决方案1】:

您将相同的对象 (current) 分配给 chrd 的所有单元格,这就是您最终得到最后一个值的原因。你应该在循环内初始化current 来解决这个问题。

 while ((line = reader.readLine()) != null) {
                     current = new Chardonnay();
                     String[] RowData = line.split(",");
                     current.setName(RowData[0]);
                     current.setPlace(RowData[1]);
                     current.setDescription(RowData[2]);
                     current.setYear(Integer.valueOf(RowData[3]));
                     current.setPriceBottle(Integer.valueOf(RowData[4]));
                     current.setPriceGlass(Integer.valueOf(RowData[5]));

                     chrd[count] = current;
                     Log.i(myTag, count + " " + chrd[count]);
                     count++;
                }

【讨论】:

  • 谢谢!你说得对。如果我这样做,它会起作用。现在我正试图围绕为什么它会第一次正确报告(来自循环内的日志)但是一旦我离开循环就会切换。是因为我只是在数组中分配对当前的引用吗?如果我会圆顶类似 chrd[count].setName(RowData[0]);等等...而不是对当前对象执行所有操作,我认为它也可以避免这个问题。
  • 第一次是在你的循环中,所以它打印对象的当前值,在下一个循环中,所有单元格中的值已经改变,因为它是同一个对象。
【解决方案2】:

问题出在这一行:

current = new Chardonnay();

您只创建一个对象,while 的每个循环都会替换该对象中的属性,因此您以最后一个结束。

在while循环内移动对象的创建。

【讨论】:

    【解决方案3】:

    move "current = new Chardonnay();"到while循环

    在您的代码中,数组中的每个项目都指向同一个霞多丽实例

    【讨论】:

      【解决方案4】:

      根据我的经验,这就是我必须为 ExpandableListAdapter 组格式化数据的方式:

          ArrayList<HashMap<String, String>> alist = new ArrayList<HashMap<String, String>>();
      
          ...
      
          //provided there are entries in the database, iterate through them all. create a hashmap using "company" as the key and 
          //the company as the item and add this hashmap to the array of maps.
          if (cursor.moveToFirst()) {
      
              do {
                  HashMap<String, String> m = new HashMap<String, String>();
                  m.put("company", cursor.getString(cursor.getColumnIndex(CompanyAndProductDatabaseAdapter.company_column))); 
                  alist.add(m);
              } while (cursor.moveToNext());
          }
      

      【讨论】:

      • 嗯,似乎其他答案更合适。一旦这些对您有用,请忽略这一点。
      猜你喜欢
      • 1970-01-01
      • 2010-12-24
      • 1970-01-01
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      • 2018-10-23
      相关资源
      最近更新 更多