当前位置: 首页 > news >正文

List集合根据对象某个元素去重

序言

检视代码时有下面这样一段代码(已脱敏处理),

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;public class RemoveDuplicateDemo {@Data@NoArgsConstructor@AllArgsConstructorstatic class A {private String aliasName;private int age;}@Data@NoArgsConstructor@AllArgsConstructorstatic class B {private String name;private int age;}private static List<B> removeDuplicateOrigin(List<A> list) {List<B> listB = new ArrayList<>();if (CollectionUtils.isNotEmpty(list)) {Set<String> allName = list.stream().map(A::getAliasName).collect(Collectors.toSet());for (String aliasName : allName) {B b = new B();b.setName(aliasName);listB.add(b);}}return listB;}public static void main(String[] args) {List<A> list = Arrays.asList(new A("tom", 15), new A("john", 16), new A("tim", 11), new A("tom", 30));System.out.println(removeDuplicateOrigin(list));}
}

先思考一下,这样写是否有问题?乍一看,功能上好像没有太大问题。
两个对象A和B,把A对象集合中根据别名进行去重放到B对象集合中。

但实际上有好几处可以优化的地方:

  • 1)方法第一行先就创建了一个初始容量为10的数组,假设A对象集合是空的,那么你平白无故创建了一个集合没有任何作用。判空逻辑建议提前。
  • 2)使用stream流遍历了一遍A对象集合,后面又重新遍历了一遍A集合的结果集,且A对象的所有元素不能赋值到B对象集合。

改进建议

  • 1)使用卫语句减少逻辑嵌套;
  • 2)使用HashMap减少遍历次数;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import org.apache.commons.collections4.CollectionUtils;import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;public class RemoveDuplicateDemo {@Data@NoArgsConstructor@AllArgsConstructorstatic class A {private String aliasName;private int age;}@Data@NoArgsConstructor@AllArgsConstructorstatic class B {private String name;private int age;}private static List<B> removeDuplicate(List<A> list) {if (CollectionUtils.isEmpty(list)) {return new ArrayList<>();}// 去重return list.stream().filter(distinctKey(A::getAliasName)).map(RemoveDuplicateDemo::buildB).collect(Collectors.toList());}public static void main(String[] args) {List<A> list = Arrays.asList(new A("tom", 15), new A("john", 16), new A("tim", 11), new A("tom", 30));System.out.println(removeDuplicate(list));}private static Predicate<? super A> distinctKey(Function<? super A, ?> key) {Map<Object, Boolean> map = new ConcurrentHashMap<>();return t -> map.putIfAbsent(key.apply(t), Boolean.TRUE) == null;}private static B buildB(A a) {B b = new B();b.setName(a.getAliasName());b.setAge(a.getAge());return b;}
}
http://www.lryc.cn/news/289730.html

相关文章:

  • QML Qt4版本移植到Qt5概述
  • 【极数系列】Flink环境搭建Linux版本 (03)
  • 2023年深圳市节假日人口迁入数据,shp/excel格式,需要自取!
  • Windows10上通过MSYS2编译FFmpeg 6.1.1源码操作步骤
  • HiveSQL题——用户连续登陆
  • 题解仅供学习使用
  • Linux命令-apt-get命令(Debian Linux发行版中的APT软件包管理工具)
  • matlab appdesigner系列-仪器仪表3-旋钮
  • 常见の算法5
  • MYSQL中group by分组查询的用法详解(where和having的区别)!
  • 架构篇25:高可用存储架构-双机架构
  • 微信小程序(十五)自定义导航栏
  • Python3进行pdf文件分割及转word
  • 深入理解TCP网络协议(1)
  • QT 中如何使用 JSON 功能?
  • C++面试:算法的执行效率和资源消耗、时间和空间复杂度分析根据实际场景,选用合适的数据结构和算法进行程序设计
  • 力扣100215-按键变更的次数
  • STM32-GPIO输出(HAL库)
  • 倒计时80天
  • PBM模型参数详解
  • 贪吃蛇/链表实现(C/C++)
  • Qlik Sense : IntervalMatch(离散匹配)
  • MySql45讲-08.事务到底是隔离的还是不隔离的?(结合MVCC视频)
  • 备战蓝桥杯----数据结构及STL应用(基础2)
  • 日常学习之:vue + django + docker + heroku 对后端项目 / 前后端整体项目进行部署
  • LangGraph:一个基于LangChain构建的AI库,用于创建具有状态、多参与者的应用程序
  • 04-Nacos-服务注册基于spring boot实现
  • iOS 闭包和Block的区别
  • 后端学习笔记——后端细碎知识点(每天更新......)
  • 二进制中1的个数