最近粗心导致项目出了一点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.