作者: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 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!