需求:
现在我有一个用户集合,集合中的各个用户的电话号码可能会重复,电话号码重复的用户只需要保留一个即可。
用户实体:
package com.javabasic.javabasic.workidea;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Long id;
/**
* 手机号码
*/
private String phone;
/**
* 密码,加密存储
*/
private String password;
/**
* 昵称,默认是随机字符
*/
private String nickName;
/**
* 用户头像
*/
private String icon = "";
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
解决方案:
直接上代码
no bb ,show me your code
package com.javabasic.javabasic.workidea;
import cn.hutool.core.util.StrUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author: Ambation
* @Description:
* @Date Created in 2023-11-16-21:39
* @Modified By:
*/
public class TestDeWeight {
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User();
user.setId((long) i);
user.setPhone("13412345678");
user.setPassword("qwer" + i);
user.setNickName("小米" + i);
userList.add(user);
}
/**
* 要求根据phone字段进行去重
*/
//方法一: 使用集合双重循环进行去重
for (int i = 0; i < userList.size(); i++) {
for (int j = i + 1; j < userList.size(); j++) {
if (userList.get(i).getPhone().equals(userList.get(j).getPhone())) {
userList.remove(j);
j--;
}
}
}
System.out.println(userList);
//方法二: 使用集合的hashSet进行去重
HashSet<String> hashSet = new HashSet<>();
//遍历集合,将phone去重放入hashSet
for (User user : userList) {
String phone = user.getPhone();
if (phone != null && !phone.isEmpty()) {
hashSet.add(phone);
}
}
//遍历用户集合,如果phone在hashSet中,则将该用户添加到新建的集合中
ArrayList<User> distictUserList = new ArrayList<>();
for (String phone : hashSet) {
for (User user : userList) {
String phoneu = user.getPhone();
if (phoneu != null && !phoneu.isEmpty()) {
if (phone.equals(phoneu)) {
distictUserList.add(user);
break;
}
}
}
}
System.out.println(distictUserList);
//方法三: stream流进行去重
userList.stream().collect(
() -> new HashSet<>(),
(hashSet1, user) -> {
String phone = user.getPhone();
if (phone != null && !phone.isEmpty()) {
hashSet1.add(phone);
}
},
(hashSet1, hashSet2) -> {
hashSet1.addAll(hashSet2);
}
);
System.out.println(userList);
//方法四:stream流分组进行去重
ArrayList<User> distictUserLists = new ArrayList<>();
Map<String, List<User>> groupByPhone = userList.stream().filter(u -> StrUtil.isNotBlank(u.getPhone()))
.collect(Collectors.groupingBy(User::getPhone));
groupByPhone.forEach((k, v) -> {
distictUserLists.add(v.get(0));
});
System.out.println(distictUserLists);
//=====================ChatGTP推荐的方案=====================
//方法五: 自定义对象进行去重,比较器实现
Set<User> set = new TreeSet<>(new MyObjectComparator());
// 将需要去重的对象添加到set中
set.addAll(userList);
System.out.println(set);
//方法六: 使用stream流进行去重
/**
* 在这个示例中,我们通过stream将原始列表转换为流,
* 然后使用Collectors.toMap方法以Phone字段作为键进行收集。
* 在这个过程中,我们使用了一个合并函数(existing, replacement) -> existing
* 来指定如果遇到重复的键时保留已存在的值。
* 最后,我们取出map的值部分,并再次使用collect方法转换为列表,
* 得到了根据Phone字段去重后的列表。
*/
List<User> uniqueObjects = userList.stream()
.collect(Collectors.toMap(User::getPhone, obj -> obj, (existing, replacement) -> existing))
.values()
.stream()
.collect(Collectors.toList());
System.out.println(uniqueObjects);
//=====================文心一言 推荐的方案=====================
//方法七: 使用map进行去重
Map<String, User> phoneUserMap = new HashMap<>();
for (User user : userList) {
if (!phoneUserMap.containsKey(user.getPhone())) {
phoneUserMap.put(user.getPhone(), user);
}
}
// Print out the unique users
for (User user : phoneUserMap.values()) {
System.out.println(user);
}
//方法八: 使用stream流进行去重
List<User> uniqueUserList = userList.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getPhone))),
ArrayList::new));
// Print out the unique users
uniqueUserList.forEach(System.out::println);
}
}
class MyObjectComparator implements Comparator<User> {
@Override
public int compare(User o1, User o2) {
return o1.getPhone().compareTo(o2.getPhone());
}
}
总结:
自己想起来的实现方案会有些复杂,不得不说chatGTP确实很厉害,直接把这个问题的最优代码给你,完全无需优化。文心一言要差一些,你需要问它,还有什么更好的解决方案吗?它才会给你最优方案。
思考:
人工智能给的方案确实很好,但是它给你的代码,你真的能看的明白,并理解吗?现在的各种模型,把你的需求讲给它,10秒钟,它就会生成一段无需优化的最优代码,很快很准。如果我们提前经过思考,想过很多方法,却不知如何实现,一问人工智能,它给的方案会让你醍醐灌顶,那种感觉很爽很爽。
多思考,多尝试。
尾声:
大家有什么好的去重方案,欢迎讨论。