Guava类库中Lists.transform踩坑
前言
最近在Java踩坑的道路上越踩越多坑,随手写篇笔记做个记录。
问题分析
Guava类库很强大,但也有一点坑,最近在做项目的正好遇到。使用Lists.transform
转换数据,遇到坑①修改源对象数据会直接影响转换后数据 ②直接修改转换后数据修改无效
代码例子:
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.List;
//源对象
class People {
private String name;
private int age;
private String desc;
public People() {
}
public People(String name, int age, String desc) {
this.name = name;
this.age = age;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", desc='" + desc + '\'' +
'}';
}
}
// 转换目标对象
class PeopleVo {
private String name;
private int age;
private String desc;
public PeopleVo() {
}
public PeopleVo(String name, int age, String desc) {
this.name = name;
this.age = age;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", desc='" + desc + '\'' +
'}';
}
}
public class GuavaExample {
public static PeopleVo peopleToVo(People people) {
PeopleVo peopleVo = new PeopleVo();
peopleVo.setName(people.getName());
peopleVo.setAge(people.getAge());
peopleVo.setDesc(people.getDesc() + " To Vo");
return peopleVo;
}
public static void main(String[] args) {
List<People> peopleList = ImmutableList.of(
new People("icharle", 18, "good"),
new People("pad", 19, "better"),
new People("soarteam", 20, "best")
);
List<PeopleVo> peopleVos = Lists.transform(peopleList, new Function<People, PeopleVo>() {
@Override
public PeopleVo apply(People people) {
return peopleToVo(people);
}
});
//1.对源对象数据进行修改会影响到转换对象的数据
System.out.println("-----------------源对象数据-----------------");
System.out.println(peopleVos.toString());
System.out.println("----------------对源对象修改-----------------");
for(People people : peopleList){
people.setAge(people.getAge()+1);
}
System.out.println(peopleVos.toString());
//2.对转换后的对象进行修改数据,修改无效
System.out.println("-----------------修改转换对象数据-----------------");
for(PeopleVo peopleVo : peopleVos){
peopleVo.setAge(peopleVo.getAge()+1);
}
System.out.println(peopleVos.toString());
}
}
输出数据:
# 输出片段一
-----------------源对象数据-----------------
[People{name='icharle', age=18, desc='good To Vo'}, People{name='pad', age=19, desc='better To Vo'}, People{name='soarteam', age=20, desc='best To Vo'}]
# 输出片段二
----------------对源对象修改-----------------
[People{name='icharle', age=19, desc='good To Vo'}, People{name='pad', age=20, desc='better To Vo'}, People{name='soarteam', age=21, desc='best To Vo'}]
# 输出片段三
-----------------修改转换对象数据-----------------
[People{name='icharle', age=19, desc='good To Vo'}, People{name='pad', age=20, desc='better To Vo'}, People{name='soarteam', age=21, desc='best To Vo'}]
情况说明:
- 输出判断一跟片段二对比,当对源数据
peopleList
的age加一操作情况下,输出转换对象后的数据是更变的。 - 输出片段二跟片段三对比,当对转换后数据
peopleVos
的age加一的操作情况下,输出转换对象的数据是不改变。
查阅谷歌相关文章,发现转换后的数据是一个视图模型,因此再修改原对象情况下,必然会影响视图内容;而直接修改视图,对它的任何更改都是无效的。