一、排序
注明:StudentInfo是一个DTO对象里面包含age,height属性。
通过age正序,
list.stream()
.sorted(Comparator.comparing(StudentInfo::getAge))
.collect(Collectors.toList());
通过age倒序:先正序,在使用reversed翻转。
list.stream()
.sorted(Comparator.comparing(StudentInfo::getAge).reversed())
.collect(Collectors.toList());
通过age倒序,在通过height正序。
list.stream()
.sorted(Comparator.comparing(StudentInfo::getAge).reversed().thenComparing(StudentInfo::getHeight))
.collect(Collectors.toList());
通过age倒序,如果age相等在通过height倒序。当然如果还有属性,后面还可以拼接很多个thenComparing()方法。
list.stream()
.sorted(Comparator.comparing(StudentInfo::getAge).reversed().thenComparing(StudentInfo::getHeight).reversed())
.collect(Collectors.toList());
//按照日期类型排序
list.stream().sorted((before, after) -> {
return before.getDate().compareTo(after.getDate());
}).collect(Collectors.toList());
二、分组
//使用年龄分组
studentList.stream().collect(Collectors.groupingBy(StudentInfo::getAge));
//使用多个属性同时分组
studentList.stream().collect(Collectors.groupingBy(item->{
return item.getAge()+"_"+item.getHeight();
}));
//当然也可以设置更多分组条件
studentList.stream().collect(Collectors.groupingBy(item->{
return item.getAge()>18 ? 1:2;
}));
//多个属性分组后再分组。注意返回值的类型。
Map<Integer, Map<Double, List<StudentInfo>>> collect =
studentList.stream()
.collect(Collectors.groupingBy(StudentInfo::getAge, Collectors.groupingBy(StudentInfo::getHeight)));
//分组后,计算每组的数量。
Map<Integer, Long> collect1 = studentList.stream()
.collect(Collectors.groupingBy(StudentInfo::getAge, Collectors.counting()));
//分组后,计算每组里面的对象的某个属性求和
studentList.stream()
.collect(Collectors.groupingBy(StudentInfo::getHeight, Collectors.summingInt(StudentInfo::getAge)));
三、分组后排序:
先看下 groupingBy()三个参数的源码
public static <T, K, D, A, M extends Map<K, D>> Collector<T, ?, M>
groupingBy(
Function<? super T, ? extends K> classifier,
Supplier<M> mapFactory,
Collector<? super T, A, D> downstream)
groupingBy方法又三个参数:第一个是分组条件,第二个分组最后用什么容器保存返回(默认是HashMap::new),第三个是使用容器来收集分完组之后每组里面的集合。
TreeMap<Integer, List<StudentInfo>> collect3 = studentList.stream()
.collect(Collectors.groupingBy(StudentInfo::getAge, TreeMap::new, Collectors.toList()));
分组之后排序,因为分组之后得到的是一个map,所以我们只需要对map进排序就好了。而TreeMap又自带排序功能
排序
排序
list.sort(Comparator.comparing(person -> person.getSalary()));//正序
list.stream().sorted(Comparator.comparing(Person::getSalary).reversed()).collect(Collectors.toList());//倒叙
四、类型转换
//List转Map1
userList.stream().collect(Collectors.toMap(User::getId,User::getName));
//List转Map2
Map<String, String> actualNavMap = nullNavFundCodes.stream().collect(Collectors.toMap(
nullNavFundCodesItem -> this.getSingularFundNavKey(nullNavFundCodesItem),
nullNavFundCodesItem -> {
return nullNavFundCodesItem.getId();
}));
//List转Map3
Map<String, Column> copy = original.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
e -> new Column(e.getValue())
));
//map转map
stcodeMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
在使用flatMap的时候,返回值是Stream《DTO》类型
List<ADTO> result = fundCodes.stream().flatMap(item -> {
if (item != null) {
return Stream.of(JSONObject.parseObject(item, ADTO.class));
} else {
return Stream.of();
}
}).collect(Collectors.toList());
List<DTO> result = map.entrySet().stream().flatMap(item -> {
List<DTO> values = item.getValue();
if (CollectionUtils.isEmpty(values)) {
return Stream.of();
}
return Stream.of(values);
}).collect(Collectors.toList());
五、聚合操作
求最大值:
max = list.stream().mapToInt(accountItem -> Integer.valueOf(accountItem.getId().toString())).max().getAsInt();
max = list.stream().mapToInt(accountItem -> Integer.valueOf(accountItem.getId().toString())).boxed().reduce(Integer::max).get();
//获取BigDecimal最大值
BigDecimal max = list.stream().map(item -> {
return item.getBigDecimal();
}).max((before, after) -> before.compareTo(after)).get();
//获取BigDecimal最小值
BigDecimal min = list.stream().map(item -> {
return item.getBigDecimal();
}).min((before, after) -> before.compareTo(after)).get();
求和
求和
appTFundPromotionCoupons.stream().map(appTFundPromotionCouponItem -> {
return appTFundPromotionCouponItem.getFullReduceAmt();
}).reduce(BigDecimal.ZERO, BigDecimal::add);
IntStream、LongStream 和 DoubleStream的区别
IntStream intStream = list.stream().mapToInt(accountItem -> Integer.valueOf(accountItem.getId().toString()));
Stream<Integer> boxed = list.stream().mapToInt(accountItem -> Integer.valueOf(accountItem.getId().toString())).boxed();
IntStream、LongStream 和 DoubleStream 分别表示原始 int 流、 原始 long 流 和 原始 double 流。
这三个原始流类提供了大量的方法用于操作流中的数据,同时提供了相应的静态方法来初始化它们自己。
java.util.stream.IntStream 是一个原始整数值序列 ( sequence ) 。该流提供了许多方法可以对该流中的元素顺序执行或并行执行一些聚合操作,比如 max() 或 average()
Reduce 原意:减少,缩小。根据指定的计算模型将Stream中的值计算得到一个最终结果
连接操作:
String mergeString = strings.stream()
.filter(string -> !string.isEmpty())
.collect(Collectors.joining(","));
六、去重操作
//distinct去重
stringList = stringList.stream().distinct().collect(Collectors.toList());
//Object对象通过上面方式去重用的是toString的方法,如果需要通过某一个属性去重可以使用下面的方式。
studentList.stream().collect(
collectingAndThen(
toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new)
);
七、其他
通过stream往List里面追加元素
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Accumulator<S, T> {
private final Function<S, T> transformation;
private final List<T> internalList = new ArrayList<T>();
public Accumulator(Function<S, T> transformation) {
this.transformation = transformation;
}
public void option1(List<S> newBatch) {
internalList.addAll(newBatch.stream().map(transformation).collect(Collectors.toList()));
}
public void option2(List<S> newBatch) {
newBatch.stream().map(transformation).forEach(internalList::add);
}
}