首页 > 其他分享 >Stream流根据属性去重

Stream流根据属性去重

时间:2023-05-13 16:33:35浏览次数:33  
标签:name Stream 根据 age list User new hobby 属性

List根据属性去重

创建一个user集合

 User user1 = new User("user1", 18, "AAA");
        User user2 = new User("user2", 18, "BBB");
        User user3 = new User("user3", 18, "AAA");
        User user4 = new User("user4", 75, "CCC");
        User user5 = new User("user5", 35, "AAA");

        ArrayList<User> list = new ArrayList<>();
        list.add(user1);
        list.add(user2);
        list.add(user3);
        list.add(user4);
        list.add(user5);

自定义Predict函数,使用filter()

写一个Predict
public class DistinctKeyUtil {
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}
使用filter方法
/**
* 写一个Predict进行属性过滤
*/
//先过滤age在过滤hobby
List<User> result = list.stream()
.filter(DistinctKeyUtil.distinctByKey(n -> n.getAge()))
.filter(DistinctKeyUtil.distinctByKey(n -> n.getHobby()))
.collect(Collectors.toList());

result.forEach(System.out::println);
结果:
User{name='user1', age=18, hobby='AAA'}
User{name='user4', age=75, hobby='CCC'}
小结:

实质上是将每个元素都放到distinctByKey()中的ConcurrentHashMap作为key进行过滤,如果key不存在那么就加上去,如果已经存在了就不加。所以这种方式的过滤只保留第一个重复元素。

利用TreeSet

        //过滤age
        ArrayList<User> result2 = list.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(
                                () -> new TreeSet<>(Comparator.comparing(o -> o.getAge()))), ArrayList::new));
								
        result2.forEach(System.out::println);

结果与上面的一样

同时过滤两个属性

        //age和hobby一起过滤
        ArrayList<User> result1 = list.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(
                                () -> new TreeSet<>(Comparator.comparing(o -> o.getHobby() + ";" + o.getAge()))), ArrayList::new)
        );
        result1.forEach(System.out::println);
结果:
User{name='user1', age=18, hobby='AAA'}
User{name='user5', age=35, hobby='AAA'}
User{name='user2', age=18, hobby='BBB'}
User{name='user4', age=75, hobby='CCC'}
小结:

TreeSet存储唯一的元素,并且按升序对元素进行排序。

Map:保证Key的唯一性

        /**
         * map 根据某属性过滤
         */
        //  Function.identity() 相等于  o->o
        Map<String, User> map1 = list.stream().collect(Collectors.toMap(User::getHobby, Function.identity(), (t1, t2) -> t1));
        Set<Map.Entry<String, User>> entries1 = map1.entrySet();
        entries1.forEach(System.out::println);
结果:
AAA=User{name='user1', age=18, hobby='AAA'}
CCC=User{name='user4', age=75, hobby='CCC'}
BBB=User{name='user2', age=18, hobby='BBB'}
小结:

map可以选择保留重复属性中的前一条数据还是后一条:(t1, t2) -> t1)

标签:name,Stream,根据,age,list,User,new,hobby,属性
From: https://www.cnblogs.com/star037/p/17397593.html

相关文章

  • 本程序是三菱FX3U PLC编写的铝材过秤包装平台,主要功能:秤完铝材重量后,根据不同的铝材
    本程序是三菱FX3UPLC编写的铝材过秤包装平台,主要功能:秤完铝材重量后,根据不同的铝材总量,选择不同的包装速度,重量越重,包装速度越慢,包装纸就越重,反之亦然,不同重量可以随意设置不同速度,不同的速度也可以设置不同的重量,当选择段速包装时,一共5段速可以设置,当需要恒速包装时电机频率可......
  • 根据窗口句柄获取所在程序路径
    本例效果图:代码文件:unitUnit1;interfaceuses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms, Dialogs,StdCtrls;type TForm1=class(TForm)  Button1:TButton;  Button2:TButton;  procedureButton1Click(S......
  • Stream流anyMatch,allMatch,noneMatch
    publicclassActor{privateStringname;privateintage;privateList<Person>personList=newArrayList<Person>();publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.na......
  • 关于 Delphi 中流的使用 用 TMemoryStream(内存流) 入门
    所谓"流",就是一段数据或是一块内存;在进行流操作时,我们不必关心流中的数据到底是什么;只需要知道流的大小和当前的指针位置.所以流只有两个属性:Size、Position.对流的操作,不过就是读取和写入.所以流最主要的方法就是Read和Write.在很多控件的使用中,读取主要用Load......
  • com-alibaba-fastjson转换json时默认将属性第一个字母转小写
    问题描述将实体类对象转为json字符串的时候,会将属性名首字母改为小写例如此出User队形有两个属性,USER_NAME和USER_AGE,首字母均为大写将实体类对象转为JSON后首字母全都转换为了小写解决方法这是因为阿里巴巴的fastjson框架默认使用了JavaBean规范中的命名约定,将属性名首字......
  • Picturefill.WP – 根据屏幕尺寸加载合适的图片
    Picturefill.WP插件利用picturefill.js脚本展示Responsive图片,即根据视口宽度选择尺寸合适的图片加载,节省带宽,提高网站载入速度。例如用户用手机访问站点,该插件会选择适合手机尺寸的图片(如缩略图)加载,不会加载完整尺寸图片。使用方法没有选项,无需任何设置,下载插件激活,网站文章中的所......
  • Json序列化对象后,使用Lombok后属性xAxis大写变成小写xaxis解决方法
    一、问题描述最近在开发后端接口时,发现返回结构中,一个字段大小写转化有问题。lombok版本:1.18.14VO对象如下,字段为echarts趋势图组件。预期返回xAxis,实际返回xaxis@DatapublicclassULineBarVO{/***X轴信息*/privateULineBarDataVOxAxis;/*......
  • 三菱FX3U的plc画圆程序,程序将圆分为360等份进行插补,才用子程序循环调用的方式,根据这个
    三菱FX3U的plc画圆程序,程序将圆分为360等份进行插补,才用子程序循环调用的方式,根据这个原理可自行编写多种图形的程序ID:3116665969838784......
  • 客户端javascript对象的几何属性(获得大小及坐标)
    在一些客户端javascript对象中,存在着如宽度、高度、坐标类的几何属性,同时这些属性在不同的浏览器下又有不同的属性名。现在将所有的此类对象的几何属性汇总,便于学习,免得搞混。1.浏览器窗口在桌面的坐标(x,y)Window      IE下:window.screenLeft,window.screenTo......
  • 整一个工具类【根据URL地址获取file文件对象】
    整一个工具类【根据URL地址获取file文件对象】直接将网络url文件转换为file对象importjava.io.*;importjava.net.URL;publicclassImgUtils{/**从URL中获取图片输入流*并创建本地文件*@paramimageUrl*@paramsavePath*@return*......