Java Stream 處理分組后取每組最大
有一個需求功能:先按照某一字段分組,再按照另外字段獲取最大的那個
Map<String, HitRuleConfig> configMap = configList.parallelStream().collect(
Collectors.groupingBy(HitRuleConfig::getAppId, // 先根據(jù)appId分組
Collectors.collectingAndThen(
Collectors.reducing(( c1, c2) -> c1.getVersionSort() > c2.getVersionSort() ? c1 : c2), Optional::get)));
先根據(jù)appId分組,然后根據(jù)versionSort取最大.
【編程技巧】Stream流之list轉(zhuǎn)map、分組取每組第一條
前言
JDK1.8推出的stream流能極大的簡化對集合的操作,讓代碼更美觀,老規(guī)矩,直接上代碼。
一、list轉(zhuǎn)map
取list中對象的某個屬性作為唯一key,對象作為value形成一個map集合,能夠便于在后續(xù)業(yè)務(wù)中取值而不用遍歷list集合,使代碼更優(yōu)雅。
代碼如下(示例):
public class StreamSkill {
public static void main(String[] args) {
List<TestData> list = new ArrayList<>();
TestData.TestDataBuilder builder = TestData.builder();
builder.id(1).name("老王").age(50).address("隔壁");
list.add(builder.build());
builder.id(2).name("司馬老賊").age(45).address("許昌");
list.add(builder.build());
System.out.println(list);
Map<Integer, TestData> map = list.stream().collect(Collectors.toMap(TestData::getId, Function.identity()));
System.out.println(map.get(1));
}
}
@Data
@Builder
class TestData{
private Integer id;
private String name;
private Integer age;
private String address;
}
運(yùn)行結(jié)果:
二、分組取每組第一條數(shù)據(jù)
通過分組取每組第一條數(shù)據(jù)的操作可以在很多場景適用,比如取多條數(shù)據(jù)中最新的一條數(shù)據(jù)等場景。
代碼如下(示例):
public class StreamSkill {
public static void main(String[] args) {
List<TestData> list = new ArrayList<>();
TestData.TestDataBuilder builder = TestData.builder();
builder.id(1).name("老王").age(50).address("隔壁");
list.add(builder.build());
builder.id(2).name("司馬老賊").age(45).address("許昌");
list.add(builder.build());
builder.id(3).name("曹賊").age(43).address("許昌");
list.add(builder.build());
builder.id(4).name("大耳朵").age(52).address("益州");
list.add(builder.build());
builder.id(5).name("燕人").age(58).address("益州");
list.add(builder.build());
System.out.println(list);
Map<String, TestData> map = list.stream().collect(
Collectors.groupingBy(TestData::getAddress, Collectors.collectingAndThen(
Collectors.reducing((t1, t2) -> t1.getAge() > t2.getAge() ? t1 : t2),
Optional::get
))
);
System.out.println(map);
}
}
@Data
@Builder
class TestData{
private Integer id;
private String name;
private Integer age;
private String address;
}
運(yùn)行結(jié)果:
從運(yùn)行結(jié)果可以看出,根據(jù)address分組后取每組年齡最大的對象信息僅需要
小小的幾行代碼就可以搞定
總結(jié)
實際業(yè)務(wù)中根據(jù)業(yè)務(wù)合理利用stream流能夠很大程度的簡化代碼,但是這種寫法在出現(xiàn)bug的時候排查較為復(fù)雜,建議不要在使用stream流的時候在其中寫太復(fù)雜的邏輯。
Java 8 Collectors:reducing 示例(List分組取最值)
簡介
Java 8 Collectors.reducing
利用Comparator(比較器)
和BinaryOperator(二元運(yùn)算符)
進(jìn)行減少流中的元素。Collectors.reducing
返回帶有Optional
數(shù)據(jù)的Collector(收集器)
。
Collectors.reducing
在Java
Doc
的方法語法如下。
public static <T> Collector<T,?,Optional<T>> reducing(BinaryOperator<T> op)
Collectors.reducing
返回一個Optional
類的收集器。
我們需要傳遞BinaryOperator(二元運(yùn)算符)
的BinaryOperator.maxBy
或BinaryOperator.minBy
方法。
BinaryOperator(二元運(yùn)算符)
將Comparator(比較器)
作為參數(shù)。
根據(jù)該Comparator(比較器)
和BinaryOperator(二元運(yùn)算符)
,流元素被減少,最后可以作為一個組來收集。
使用場景
Collectors.reducing
主要用于取List
列表中的某一類型中的最大或最小的一個元素,例如下列代碼,取出各個班級中年齡最大的學(xué)生信息。
注:如果最值相同,取列表順序最先出現(xiàn)的一個。
代碼示例
Student.java
package com.concretepage.util;
public class Student {
private String name;
private Integer age;
private String className;
public Student(String name,Integer age, String className){
this.name=name;
this.age=age;
this.className = className;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public String getClassName() {
return className;
}
}
ReducingDemo.java文章來源:http://www.zghlxwxcb.cn/news/detail-577464.html
package com.concretepage.util;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
public class ReducingDemo {
public static void main(String[] args) {
Student s1 = new Student("Shyam", 22,"A");
Student s2 = new Student("Ram",23,"A");
Student s3 = new Student("Mohan",22,"B");
Student s4 = new Student(null,21,"B");
List<Student> list = Arrays.asList(s1,s2,s3,s4);
Comparator<Student> ageComparator = Comparator.comparing(Student::getAge);
Map<String, Optional<Student>> eldestByClass = list.stream().collect(Collectors.groupingBy(Student::getClassName,
Collectors.reducing(BinaryOperator.maxBy(ageComparator))));
eldestByClass.forEach((k,v)->System.out.println("Class:"+k+" Age:"+
((Optional<Student>)v).get().getAge()+" Name:"+((Optional<Student>)v).get().getName()));
}
}
輸出文章來源地址http://www.zghlxwxcb.cn/news/detail-577464.html
Class:A Age:23 Name:Ram
Class:B Age:22 Name:Mohan
到了這里,關(guān)于Java Stream 處理分組后取每組最大&Stream流之list轉(zhuǎn)map、分組取每組第一條&Java 8 Collectors:reducing 示例(List分組取最值)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!