简体   繁体   English

ArrayList.clear()正在更新List <>的先前值

[英]ArrayList.clear() is updating previous values of List<>

I am getting JSONArray from server. 我从服务器获取JSONArray The JSON I am getting has the following format. 我得到的JSON具有以下格式。

[ {
   "area_name":"abc",
   "coordinates":[
     {
     "lat":1.123,
     "lng":2.123,
     },
     {
     "lat":1.123,
     "lng":2.123,
     },
     .
     .
     ]
},
{
.
.
.
}
] 

In order to plot the areas on map I am adding areas to areaList and their corresponding coordinate in coordinatesList 为了绘制我加入区域在地图上的区域areaList及其相应的协调coordinatesList

ArrayList<HashMap<String, LatLng>> coordinatesList; // initialised in onCreate
List<ArrayList<HashMap<String, LatLng>>> areaList; // initialised in onCreate

for (int i = 0; i < areaArray.size(); i++) {
     coordinatesList.clear();
     //coordinatesList = new ArrayList<>();
     //  parsing of json and other non-related stuff

      for (int j =0; j < pointsArray.size(); j++) {
          // Getting data from json and saving to hashmap and adding to coordinatesList
          coordinatesList.add(pointsHashMap);
     }

     areaList.add(coordinatesList);
}

Now if I try to get values from this areaList at a certain function. 现在,如果我尝试从某个函数的areaList获取值。 I get the same values for all position. 我对所有位置都得到相同的值。

log.d(TAG, "area " + areaList.get(i).get(0).get("lat_lng)); // its in a loop

for any value of i I get the last added value by areaList.add(coordinatesList); 对于i任何值, i通过areaList.add(coordinatesList);获得最后一个增加的值areaList.add(coordinatesList); . All the previously added values in the areaList are replaced. 替换了areaList中所有先前添加的值。

But when I comment coordinatesList.clear(); 但是当我评论coordinatesList.clear(); and uncomment coordinatesList = new ArrayList<>(); 和取消注释coordinatesList = new ArrayList<>(); everything works as expected. 一切都按预期进行。

Can someone please elaborate this, why is it happening like this? 有人可以详细说明一下,为什么会这样吗?

因为每次您在循环中使数组列表满足需要时,都尝试在onCreate()中使数组满足需要

coordinatesList = new ArrayList<>();

As this is initialised in our onCreate method, which will be called once the activity is pushed to backstack. 由于这是在我们的onCreate方法中初始化的,因此将活动推送到后退栈时将调用该方法。 ArrayList<HashMap<String, LatLng>> coordinatesList;

Now the instance of your coordinatesList is valid throughout your Class / Activity . 现在,coordinateList的实例在整个Class / Activity都有效。

So if you want to get new results all the time while invoking your function for coordinatesList implementation, either you need to reinitialize the ArrayList object or clear it to get new results poplated. 因此,如果您希望在调用所有坐标列表实现的函数时始终获得新结果,则需要重新初始化ArrayList对象或清除它以获取新结果。

You definitely need to add a new ArrayList to areaList each iteration through the loop. 您肯定需要在循环中的每次迭代中向AreaList添加一个新的ArrayList。 Right now you're adding the same instance of coordinatesList to areaList each time through the loop. 现在,您每次通过循环都将相同的ordinatesList实例添加到areaList。 That same instance is getting cleared at the top of the list. 同一实例在列表顶部被清除。

Adding the same coordinatesList to the areaList doesn't copy the elements, it merely adds the reference to the existing list. 将相同的坐标列表添加到areaList不会复制元素,而只是将引用添加到现有列表。

The following should work 以下应该工作

public void onCreate(Bundle b){
    super(b);

    parseResponse();
}

private final void parseResponse(){

    areaList = new ArrayList<ArrayList<HashMap<String, LatLng>>>>(jsonArray.length());
    for(int i=0;i<areaList.size();i++){

        List<HashMap<String,LatLng>> coordinatesList = new ArrayList<>();
        //  parsing of json and other non-related stuff

        for (int j =0; j < pointsArray.size(); j++) {
            // Getting data from json and saving to hashmap and adding to coordinatesList
            coordinatesList.add(pointsHashMap);
        }

     areaList.set(i,coordinatesList);
}

Note: The length of the JSON Array is the same as the length of areaList so we can initialize areaList to the same length when parsing. 注意: JSON数组的长度与areaList的长度相同,因此我们在解析时可以将areaList初始化为相同的长度。 This can be more efficient then initializing a default-sized ArrayList 与初始化默认大小的ArrayList这可能会更有效率

Code Review: 代码审查:

This snippet of code is rather unreadable: 此代码段相当不可读:

ArrayList<HashMap<String, LatLng>> coordinatesList; 
List<ArrayList<HashMap<String, LatLng>>> areaList; 

I think it would be a lot cleaner if you declared an Area class that encapsulated the pertinent details. 我认为,如果您声明一个封装了相关细节的Area类,将会更加干净。 For example: 例如:

public class Area{
   private String name;
   private List<LatLng> coordinates; 

   public Area(String name, List<LatLng> coordinates){//...}
}

This would then reduce the code in your Activity to: 然后,这会将您活动中的代码减少为:

List<Area> areaList; 

private final void parseResponse(){

    areaList = new ArrayList<Area>(jsonArray.length());
    for(int i=0;i<areaList.size();i++){

        List<LatLng> coordinatesList = new ArrayList<>();
        //  parsing of json and other non-related stuff
        // Getting area_name and coordinates from json

         areaList.add(new Area(areaName,coordinatesList));
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM