我们经常使用List来做数据集合存放数据,经常使用时我们知道list是可以实现地址传递,也就是在list通过方法的入参传递到方法内后,整个list的值可以在方法内使用:
通过add方法可以在原来的基础上增加新值,
也可以通过set(index,值)的方式改变原来index位置的数据
而且入参传递的值经过add、set等后再方法外也是生效的,就是这个操作后的值,这就是地址传递,也就是对象传递。
但是,我们容易忽略的一点儿是:
当在方法内发生新的list整体赋值给入参的list的时候(例如例子里的stringList = newList;), 这样对入参的修改,方法外获取不到,似乎上就不是地址传递了。
其实,原因是,这里的newList是new过的,是新的内存的一块,只是在方法内将stringList的地址指向了newList,所以方法内我们使用stringList的值就是newList的,而一旦方法内的作用域结束后,newList被销毁,stringList就和newList值无关了,所以就似乎不是地址传递了。
解决办法:
那我们怎么实现方法内的new的list传递给方法外呢?
1.可以作为方法的返回值,将新new的list作为值,return到方法外。
2.但是我们在实际开发中经常返回值还有其他作用,例如已经被boolean表示操作成功失败的的返回信息占用,我们必须要实现入参传递的list将新的list带出去。
使用list提供的addAll方法,很好的处理了这个问题。(在我没注意到addAll方法前,我首先我想到clone方法,但是List不支持clone方法,而addAll方法很好用,也就没必要clone)
以下是在IDE上测试的各种情况,可以使用哟:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 对list的各种赋值方式的测试
* 找到整体新的list赋值传递到方法外仍然有效的的方法 addAll
* @author zml
* @date 2018/3/20
*/
public class TestList {
public static void main(String[] args) {
TestList test = new TestList();
List<String> stringList1 = new ArrayList<>();
test.addList(stringList1);
System.out.println("长度是" + stringList1.size());//1
List<String> stringList2 = new ArrayList<>();
test.equalList(stringList2);
System.out.println("长度是" + stringList2.size());//0
List<String> stringList3 = new ArrayList<>();
test.arrayAsList(stringList3);
System.out.println("长度是" + stringList3.size());//0
List<String> stringList4 = new ArrayList<>();;
test.newArrayAsList(stringList4);
System.out.println("长度是" + stringList4.size());//2
List<String> stringList5 = new ArrayList<>();;
stringList5 = test.returnList();
System.out.println("长度是" + stringList5.size());//2
}
/**
* add方法往入参的list传值
* 地址传递,有效
* @param stringList list
*/
public void addList(List<String> stringList) {
stringList.add("add");
}
/**
* 方法内的new的list赋值给入参的list
* 方法外无效
* @param stringList list
*/
public void equalList(List<String> stringList) {
List<String> newList = new ArrayList<>();
newList.add("new");
stringList = newList;
}
/**
* 数组通过Arrays.asList方法转化为list赋值给入参的list
* 方法外无效 Arrays.asList的实现机制是new
* @param stringList list
*/
public void arrayAsList(List<String> stringList) {
String[] arrayStr = {"arrayStr1", "arrayStr2"};
List<String> newList = Arrays.asList(arrayStr);
stringList = newList;
}
/**
* 使用list的addAll方法将new的list传递给入参list
* addAll是list提供的用于整体赋值list的方法,相当于将每项取出来多次遍历去add
* @param stringList list
*/
public void newArrayAsList(List<String> stringList) {
String[] arrayStr = {"arrayStr1", "arrayStr2"};
List<String> newList = Arrays.asList(arrayStr);
stringList.addAll(newList);
//List不支持clone方法,但是addAll很好用
}
/**
* 方法内的list做返回值返回到方法外
*/
public List<String> returnList() {
String[] arrayStr = {"arrayStr1", "arrayStr2"};
List<String> newList = Arrays.asList(arrayStr);
return newList;
}
}