最近粗心导致项目出了一点bug,调试了一个小时才发现是java引用的问题。
一般地,我们不在循环内进行变量的定义和分配内存,因为循环次数太多的话容易造成内存溢出。我通常也遵循这样的规则,但是在一些特殊情况下常常忘记变量的处理(重新初始化或别的)。常见的有两种情况:
- 将本该在循环内定义的Collection变量定义在循环外部,如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| dataRowToDataSet(List<String> windows) { List<List<String>> dataSet=new LinkedList<>(); List<String> recond=new LinkedList<>(); for(int i=0;i<windows.size();i++) { String[] strs=windows.get(i).split(","); for(String s:strs) { recond.add(s); } dataSet.add(recond); } return dataSet; }
|
此种写法是错误的。会不断地加入新元素。即使在第一个循环结尾加上recond.clear()也是错误的,因为recond从始至终指向同一块内存。
正确的写法应该把
1
| List<String> recond=new LinkedList<>();
|
放到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static List<List<String>> dataRowToDataSet(List<String> windows) { List<List<String>> dataSet=new LinkedList<>(); List<String> recond=null; for(int i=0;i<windows.size();i++) { String[] strs=windows.get(i).split(","); recond=new LinkedList<>(); for(String s:strs) { recond.add(s); } dataSet.add(recond); } return dataSet; }
|
- 两个List之间的赋值方式如下(忌用=进行引用赋值):
1 2
| List<String> subLabels=new LinkedList<>(); subLabels.addAll(labels); //labels is other list.
|