在项目中经常用到从数据中查到的数据封装在domain中,返回给前台时需要做一个转换到dto里,这时候有个细节,如果中间变量初始化在外面的话,最后得到的List的元素会全是同一个。
错误的写法:
刚开始的时候认为这种写法(UserDto dto = new UserDto();)不用每次循环都初始化一个变量,省内存,但是这样最后的结果里元素都是一样的,原因就是dto在循环外作了初始化,所以dto只指向了最后循环的值。
public static void main(String[] args) {
List<User> userList = getFromDb();
List<UserDto> dtoList = new ArrayList<>();
//把domain转换为dto
UserDto dto = new UserDto();
for(User user : userList) {
dto.setName(user.getName());
dtoList.add(dto);
}
System.out.println(dtoList);
}
//这里只是模拟从数据库取值的操作
private static List<User> getFromDb() {
List<User> userList = new ArrayList<>();
for(int i = 0; i < 5; i++) {
User user = new User(i + "");
userList.add(user);
}
return userList;
}
}
User和UserDto都是简单的对象,只有一个name属性,这里就不写出来了。
打印结果
[UserDto [name=4], UserDto [name=4], UserDto [name=4], UserDto [name=4], UserDto [name=4]]
正确的写法:
public class TestList {
public static void main(String[] args) {
List<User> userList = getFromDb();
List<UserDto> dtoList = new ArrayList<>();
//把domain转换为dto
UserDto dto = null;
for(User user : userList) {
dto = new UserDto(); //new 操作要写在循环体里
dto.setName(user.getName());
dtoList.add(dto);
}
System.out.println(dtoList);
}
//这里只是模拟从数据库取值的操作
private static List<User> getFromDb() {
List<User> userList = new ArrayList<>();
for(int i = 0; i < 5; i++) {
User user = new User(i + "");
userList.add(user);
}
return userList;
}
}
结果
[UserDto [name=0], UserDto [name=1], UserDto [name=2], UserDto [name=3], UserDto [name=4]]
另外:Arrays.asList()方法可以把一个数组一起装入到List里,不用写循环,代码更加简介。