关于java:如何根据对象的属性去重JDK-8-Stream-轻松搞定来长长见识

44次阅读

共计 3054 个字符,预计需要花费 8 分钟才能阅读完成。

作者:goodluckwj\
起源:blog.csdn.net/qq_35634181/article/details/108867857

ExportTemperatureDto 实体对象:

@Getter
@Setter
@ToString
public class ExportTemperatureDto {
    private String name;
    private Double morningTemperature;
    private Double afternoonTemperature;
    private String classId;
    private String gradeId;
    private Integer personId;
}

在一个 ExportTemperatureDto 的汇合中,依据 personId 属性去重,生成一个新的汇合。

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;
 
public class StreamTest {public static void main(String[] args) {List<ExportTemperatureDto> temperatureList = Lists.newArrayList();
        temperatureList.add(new ExportTemperatureDto(1, "haha"));
        temperatureList.add(new ExportTemperatureDto(2, "haha"));
        temperatureList.add(new ExportTemperatureDto(3, "haha"));
        temperatureList.add(new ExportTemperatureDto(4, "haha"));
 
        temperatureList.add(new ExportTemperatureDto(1, "hahaasdas"));
        temperatureList.add(new ExportTemperatureDto(2, "hahaasdas"));
 
        List<ExportTemperatureDto> result = temperatureList.stream()
                .collect(
                        collectingAndThen(
                                toCollection(() -> new TreeSet<>(comparing(ExportTemperatureDto::getPersonId))
                                ),
                                ArrayList::new
                        )
                );
 
        result.forEach(System.out::println);
 
        /*
            输入后果为:personId 为 1 的,其名称为 haha
                personId 为 2 的,其名称为 haha
            因为 TreeSet 底层是应用 TreeMap 进行实现的,传入了依据 getPersonId 进行比拟的比拟器
            在判断 personId 雷同时,其比拟后果为 0,而后就会替换其 value 值,而 key 值是不会变动的,又因为 TreeSet 是将传入的元素作为 key 的,所以应用 TreeSet 时,当比拟器比拟的后果雷同时,以不会将原来的值替换成比拟后的值
         */
 
    }
}

知其然知其所以然,这个 stream 流的操作看起来还是有点难度的,这里记录一下。

应用到了 collectingAndThen 实现依据属性进行去重的操作,对于该去重操作的要害应用到了 collectingAndThen、toCollection、TreeSet,有点难以了解,过后我也是懵逼的,这里记录一下,当前必定还会用的到。

了解依据对象的属性进行去重的外围是,将汇合放到 TreeSet 中,而后再将 TreeSet 转为 List,其中 TreeSet 要传入一个依据哪个属性进行比拟的比拟器,而后应用 public ArrayList(Collection<? extends E> c) 将 TreeSet 放入结构器中生成 List。

下面的 Stream 操作能够应用一般的汇合:

TreeSet<ExportTemperatureDto> treeSet = new TreeSet<>(Comparator.comparing(ExportTemperatureDto::getPersonId));
for (ExportTemperatureDto temperatureDto : temperatureList){treeSet.add(temperatureDto);
}
List<ExportTemperatureDto> result2 =  new ArrayList<>(treeSet);

只有可能了解一般汇合怎么操作的,那么应用 Stream 流操作时,就是要看对于 API 的应用是否相熟,其实这个才是要害,只有了解了 collectingAndThen、toCollection、JDK8 的匿名函数这样内容,才能看懂这个式子。

上面就简略介绍一下:

首先说一下 collectingAndThen 办法的应用 ——-先进行后果集的收集,而后将收集到的后果集进行下一步的解决,红字的两句话是了解 collectingAndThen 的要害,首先看一下 collectingAndThen 须要传递的参数:

public static<T,A,R,RR> Collector<T,A,RR> 
         collectingAndThen(Collector<T,A,R> downstream,
         Function<R,RR> finisher) 

能够看到第一个参数是 Collector 接口的子类,所以还是对于对于 Collector 的解决,Collectors 工具类外面的 toList()toSet()joining()mapping()collectingAndThen() 等简直所有的办法都能够应用,这样感觉这个 collectingAndThen 就很弱小了,能够嵌套的去应用。

第二个参数是一个 Function 函数,相熟的同学都晓得,Function 函数是这样的:R apply(T t),这个也是了解下面去重式子的要害,原来我想的是 ArrayList::new 调用的无参的构造方法,其实他调用的 ArrayList 的有参构造方法,

public ArrayList(Collection<? extends E> c)

调用的是下面那个构造方法,这样就很清晰,就是把第一个参数 downstream 的后果,交给第二个参数 Function 函数的参数外面,R apply(T t),也就是将后果设置成 t。

对于 toCollection 是一个通用的转为汇合的操作,当然在 Collectors 类外面也有 toList()toSet() 办法,然而都不满足于应用 TreeSet 来收集汇合的办法,所以应用 toCollection 是一个通用的办法,应用 TreeSet 进行收集,而后传入依据哪个属性进行比拟的比拟器,这样就能够了。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0