需求:
List<UserPojo> users = new ArrayList<>();
//第一个user和第4个user应该是相等的,因为它们的name和address相等
//id name address age
users.add(new UserPojo(1, "daji", "山东省青岛市", 19));
users.add(new UserPojo(2, "daji2", "山东省济南市", 20));
users.add(new UserPojo(3, "daji3", "北京市", 22));
users.add(new UserPojo(4, "daji, "山东省青岛市", 23));
上面有4个user,对其进行去重,去重逻辑是根据name字段和address字段来决定(name和address字段相等 ,即可判定这两个对象相等,不必关心其他字段是否相等)
因此:第一个user和第4个user应该是相等的,因为它们的name和address相等
解决方案
stream的distinct去重方法,是根据 Object.equals,和 Object.hashCode这两个方法来判断是否重复的。
所以我们可以利用这个特性 ,重写pojo的 Object.equals,和 Object.hashCode这两个方法,来实现。
1、重写Object.equals方法
@Override
public boolean equals(Object o) {
UserPojo thisPojo = (UserPojo) o;
//只有name 和 address 相等,也算相等
if (this.getName().equals(thisPojo.getName()) && this.getAddress().equals(thisPojo.getAddress())){
return true;
}else {
return false;
}
}
2、重写Object.hashCode方法
重写hashCode需要根据你选择的字段重新计算。
本例就是根据name和address重新计算hashcode。规则如下图:
最终方法:
@Override
public int hashCode() {
//根据name和address重新计算hashcode
int result = getName().hashCode();
//17是死值, jdk建议用17
result = 17 * result + getAddress().hashCode();
return result;
}
3、使用distinct去重:
users = users.stream().distinct().collect(Collectors.toList());
结果(去重成功,去掉了一个重复值):
问题到此成功解决
4、[可选方案] 继承pojo重写equals和hashcode
如果我们不想动原有的pojo,我们可以新建一个新的pojo,来继承原有的pojo。
1、 新建一个子类,继承UserPojo
2、 重写该子类的 equals方法和hashcode 方法
3、 将父类的全部数据灌入子类,对子类 使用stream的distinct去重
代码如下:
@Test
void test15() {
List<UserPojo> users = new ArrayList<>();
//第一个user和第4个user应该是相等的,因为它们的name和address相等
users.add(new UserPojo(1, "daji", "山东省青岛市", 19));
users.add(new UserPojo(2, "daji2", "山东省济南市", 20));
users.add(new UserPojo(3, "daji3", "北京市", 22));
users.add(new UserPojo(4, "daji", "山东省青岛市", 23));
/*
解决方案:使用stream的distinct去重
1、 新建一个子类,继承UserPojo
2、 重写该子类的 equals方法和hashcode 方法
3、 将父类的全部数据灌入子类,对子类 使用stream的distinct去重
*/
List<OverrideEqualsPojo> overrideEqualsPojos = new ArrayList<>();
for (UserPojo user : users) {
OverrideEqualsPojo overrideEqualsPojo = new OverrideEqualsPojo();
BeanUtils.copyProperties(user,overrideEqualsPojo);
overrideEqualsPojos.add(overrideEqualsPojo);
}
overrideEqualsPojos = overrideEqualsPojos.stream().distinct().collect(Collectors.toList());
System.out.println(overrideEqualsPojos);
}
子类pojo代码:
package com.daji.stream;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Objects;
public class OverrideEqualsPojo extends UserPojo{
public OverrideEqualsPojo(int id, String name, String address, int age) {
super(id, name, address, age);
}
public OverrideEqualsPojo() {
}
@Override
public boolean equals(Object o) {
OverrideEqualsPojo thisPojo = (OverrideEqualsPojo) o;
//只有name 和 address 相等,也算相等
if (this.getName().equals(thisPojo.getName()) && this.getAddress().equals(thisPojo.getAddress())){
return true;
}else {
return false;
}
}
@Override
public int hashCode() {
//根据name和address重新计算hashcode
int result = getName().hashCode();
//17是死值, jdk建议用17
result = 17 * result + getAddress().hashCode();
return result;
}
}
相关文章
暂无评论...