首页 > 其他分享 >自定义方法,实现按指定属性进行去重

自定义方法,实现按指定属性进行去重

时间:2023-05-30 17:45:01浏览次数:36  
标签:ConcurrentHashMap users 自定义 指定 API key new 方法 属性

实例:根据age、sex、name对user对象集合进行去重

//构建user对象
public class User {
    private int id;
    private String name;
    private int age;
    private String sex;
    private double height;

    // 构造方法、getter和setter略
}

//创建对象集合
List<User> users = new ArrayList<>();
users.add(new User( 1, "张三", 20, "男", 170));
users.add(new User( 2, "李四", 22, "男", 175));
users.add(new User( 3, "张三", 20, "男", 170));
users.add(new User( 4, "王五", 21, "女", 162));
users.add(new User( 5, "赵六", 20, "女", 168));

//调用自定义方法
List<User> distinctUsers = users.stream()
    .filter(distinctByKey(user -> user.getName() + user.getAge() + user.getSex()))
    .collect(Collectors.toList());


// 自定义distinctByKey()方法,实现按指定属性进行去重
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Map<Object, Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

上述代码中,distinctByKey()方法使用Map实现对元素去重的逻辑,filter()方法使用distinctByKey()方法返回的Predicate过滤重复元素,最终将结果收集到List集合中。

请注意,上述代码中的distinctByKey()方法是自定义的函数式接口,用于支持Stream API提供的所有接口方法。

t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null
这行代码使用Java 8的Lambda表达式实现了一个Predicate接口的匿名函数;

这个函数的作用是:对于List中的每个元素t,使用keyExtractor函数提取t对象的指定属性(这里是根据name、age和sex进行去重),并将该属性作为key放入一个ConcurrentHashMap实例中,如果这个key不存在,则返回null,表示元素t没有重复,该元素将被Stream API保留,如果这个key已经存在于ConcurrentHashMap中,则说明该元素已经出现过,将被Stream API去重丢弃。

具体而言,putIfAbsent(K key, V value)方法是ConcurrentHashMap中用于添加元素的原子方法,如果指定的key存在,则方法直接返回该key关联的value值;如果不存在,则将key和value添加到map中,并返回null。根据该方法的特性,我们可以利用putIfAbsent()方法进行去重操作。在上述Lambda表达式中,我们使用Boolean.TRUE表示ConcurrentHashMap中每个key对应的value值都为true,这个值对我们去重没有实际影响。

综上所述,该Lambda表达式的返回值是一个Predicate实例,用于对Stream API中的元素执行去重操作。

使用ConcurrentHashMap主要是为了保证多线程下的正确性。

在Stream API中,可能会出现并行stream的情况,也就是多线程处理集合中的元素。在这种情况下,如果使用非线程安全的HashMap,那么在出现线程竞争的情况下,可能会导致putIfAbsent()方法的返回值出现问题,多线程之间可能会出现覆盖的情况。这样就会导致去重操作失效,出现重复的元素。

因此,针对多线程的情况,使用线程安全的ConcurrentHashMap来实现去重操作,可以保证程序的正确性。注意,虽然Stream API中的filter()方法等是线程安全的,但内部实现会根据使用情况而选择串行执行或者并行执行,因此,无法完全保证多线程的正确性,因此,使用线程安全的容器类可以起到一个保险作用,将程序的正确性保障得更加充分。

标签:ConcurrentHashMap,users,自定义,指定,API,key,new,方法,属性
From: https://www.cnblogs.com/wxguo/p/17443917.html

相关文章

  • react 滚动到指定位置上方100像素的位置
    /*使用方法:import{useRef}from'react';constanchor=useRef<HTMLDivElement>(null);<divref={anchor}>test</div><buttononClick={()=>{scrollWithAnimation(anchor.current?.offsetTop||0);}}>jump</b......
  • js 轮播图中点击小圆圈图片跳到指定图片
    html代码(部分)<divclass="w"><divclass="main"><!--焦点图模块--><divclass="focusfl"><ahref="javascript:;"class="arrow-l"><</a>......
  • uiautomator2获取UIObject元素的属性info用法
    info是UIAutomator2中用来获取控件属性信息的方法。该方法可以获取到指定元素的一些属性信息,例如控件的文本、坐标、大小、类名、包名、是否可见等。使用该方法可以帮助我们更好的理解应用程序的UI结构,并找到需要操作的控件元素。d(text=element,instance=index).infoinfo是U......
  • C# 程序开发中如何移除List集合的某列(属性)呢?
    如题,在C#&.NET,.NETCore程序开发中如何移除List集合的某列(属性)呢?比如,有以下的MyClass类: publicclassMyClass{publicintColumn1{get;set;}publicstringColumn2{get;set;}publicintColumn3{get;set;}}现在MyClass的集合myList,如何......
  • priority_queue自定义比较函数的两种方法
    1#include<iostream>2#include<vector>3#include<queue>4usingnamespacestd;5intmain(){6structListNode{7intval;8ListNode*next;9ListNode():val(0),next(nullptr){}10L......
  • 使用 Collections中的replaceAll方法 替换list中的指定元素
    以下实例演示了如何使用Collections类的replaceAll()来替换List中所有的指定元素:importjava.util.Arrays;importjava.util.Collections;importjava.util.List;publicclassImoocStudent{publicstaticvoidmain(String[]args)throwsException{......
  • vscode 自定义代码字体颜色,局部变量、全局变量、函数、宏、属性
    vscode自定义代码字体与颜色风格在setting.json中修改即可:在这里插入图片描述"editor.semanticTokenColorCustomizations":{       "enabled":true,//enableforallthemes       "rules":{           "*.static":{             ......
  • 自定义表单设计器助您随心所欲定制专属表格!
    在新的发展时代,传统的表格设计器已经无法满足日愈繁杂的办公需求。那么,如何来定制专属的办公表格?其实,这也不是一件难事,只需要了解自定义表单设计器就行。在快速发展的现代化社会中,低代码开发平台也迎来了蓬勃的发展商机,它的灵活、简便和易操作等优势在无数行业办公领域深受喜爱,也......
  • 12)自定义函数
     1、创建自定义函数语法:createfunction函数名(参数1,参数2,...)returns返回值数据类型begin函数体return语句;end;要注意:1)、自定义函数是数据库的对象,创建时,需要指定该函数属于哪个数据库;2)、同一个数据库内,自定义函数不能和已有的函数名重名;3)、函数必须......
  • jwt原理,jwt开发流程,drf-jwt快速使用,drf-jwt定制返回格式,drf-jwt自定义用户表签发,drf-j
    jwt原理:  JWT就是一段字符串,由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串1headerjwt的头部承载两部分信息:声明类型,这里是jwt声明加密的算法通常直接使用HMACSHA256公司信息......