Lambda常用功能(排序、分组、去重、累加、截断、移除)

一、准备好一个商品实体类

@Data
@AllArgsConstructor
public class Goods {

    private Integer id;

    private Integer num;

    private BigDecimal price;

    private String goodsType;

    private String goodsName;

}

二、编写测试类 

public class LambdaTest {

    public static void main(String[] args) {
        Goods goods1 = new Goods(1, 2, new BigDecimal(3), "水果", "苹果");
        Goods goods2 = new Goods(2, 3, new BigDecimal(5), "水果", "香蕉");
        Goods goods3 = new Goods(3, 2, new BigDecimal(3), "水果", "桃子");
        Goods goods4 = new Goods(4, 4, new BigDecimal(4), "零食", "饼干");
        Goods goods5 = new Goods(5, 1, new BigDecimal(5), "饮料", "可乐");
        List<Goods> goodsList = Stream.of(goods1, goods2, goods3, goods4, goods5).collect(Collectors.toList());
      
    }
}

排序

//按照自然规则排序,适用于基本数据类型(升序)

Stream sorted()

// 根据比较器进行排序(升序),可以通过实现Comparator.comparing()方法,来创建自定义的比较器

Stream sorted(Comparator<? super T> comparator)

  •  Stream sorted()
// 将商品数量转成一个集合 
List<Integer> numList = goodsList.stream().map(Goods::getNum).collect(Collectors.toList());
System.out.println("排序前"+numList);
//对商品数量排序
numList = numList.stream().sorted().collect(Collectors.toList());
System.out.println("排序后(正序):" + numList);
//倒序(先进行正数排序,然后进行顺序颠倒)
Collections.reverse(numList);
System.out.println("倒序:" + numList);

结果

排序前[2, 3, 2, 4, 1]
排序后(正序):[1, 2, 2, 3, 4]
倒序:[4, 3, 2, 2, 1]
  • Stream sorted(Comparator<? super T> comparator) 自定义排序 
System.out.println("排序前的值:" + goodsList);
// 按照数量进行排序(正序)
goodsList = goodsList.stream().sorted(Comparator.comparing(Goods::getNum)).collect(Collectors.toList());
System.out.println("正序按照数量进行排序:" + JSON.toJSONString(goodsList));

// 按照数量进行排序(倒序)
goodsList = goodsList.stream().sorted(Comparator.comparing(Goods::getNum).reversed()).collect(Collectors.toList());
System.out.println("倒序按照数量进行排序:" + JSON.toJSONString(goodsList));

// 按金额进行倒序,金额相同就按照数量来进行正序
goodsList = goodsList.stream().sorted(Comparator.comparing(Goods::getPrice, Comparator.reverseOrder()).thenComparing(Goods::getNum)).collect(Collectors.toList());
System.out.println("按照金额倒序排序,金额相同就按照数量正序" + JSON.toJSONString(goodsList));

 结果

排序前的值:[Goods(id=1, num=2, price=3, goodsType=水果, goodsName=苹果), Goods(id=2, num=3, price=5, goodsType=水果, goodsName=香蕉), Goods(id=3, num=2, price=3, goodsType=水果, goodsName=桃子), Goods(id=4, num=4, price=4, goodsType=零食, goodsName=饼干), Goods(id=5, num=1, price=5, goodsType=饮料, goodsName=可乐)]
正序按照数量进行排序:[{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5},{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3},{"goodsName":"桃子","goodsType":"水果","id":3,"num":2,"price":3},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5},{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4}]
倒序按照数量进行排序:[{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5},{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3},{"goodsName":"桃子","goodsType":"水果","id":3,"num":2,"price":3},{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5}]
按照金额倒序排序,金额相同就按照数量正序[{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5},{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4},{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3},{"goodsName":"桃子","goodsType":"水果","id":3,"num":2,"price":3}]

reduce合并

<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);
identity:合并标志值,它将参与累加函数和合并函数的运算(即提供一个默认值,在流为空的时候返回该值,当流不为空时,该值作为起始值,参与每次累加或合并计算)
accumulator:累加函数(将流元素和identity进行累加,流元素可以不与identity相同,但是在累加函数中,需要确保返回值类型与identity相同) 
combiner:合并函数(合并多个标志,与collect方法的combiner参数原理类似,都是用于多线程的合并策略)
  •  合并所有的商品名称
String reduceName = goodsList.stream().reduce(new StringBuffer(), (result, good) -> result.append(good.getGoodsName() + ","), (r1, r2) -> r1.append(r2.toString())).toString();
System.out.println("reduce合并所有商品名称:" + reduceName);

结果 

reduce合并所有商品名称:可乐,香蕉,饼干,苹果,桃子,
  • 使用reduce进行累加
    
BigDecimal sumPrice = goodsList.stream().map(Goods::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("使用reduce进行累加BigDecimal类型的值:" + sumPrice);
//如果是Integer,double,Long可以直接使用对应的方法,比如Integer类型
Integer sumInteger = goodsList.stream().mapToInt(Goods::getNum).sum();
System.out.println("Integer类型累加:" + sumInteger);
// 如果要从某个值开始累加 10 +g.getNum
Integer tenSum = goodsList.stream().reduce(10, ((integer, g) -> integer + g.getNum()), Integer::sum);
System.out.println("从10开始进行累加:" + tenSum);

结果

使用reduce进行累加BigDecimal类型的值:20
Integer类型累加:12
从10开始进行累加:22
  • 如果是合并字符串,推荐使用joining拼接
String reduceName2 = goodsList.stream().map(Goods::getGoodsName).collect(Collectors.joining(","));
System.out.println("joining拼接:" + reduceName2);

结果

joining拼接:可乐,香蕉,饼干,苹果,桃子

取最大值或最小值

  • max()和min()
Goods maxPriceGoods = goodsList.stream().max(Comparator.comparing(Goods::getPrice)).orElse(null);
System.out.println("价格最大的商品" + JSON.toJSONString(maxPriceGoods));
Goods minPriceGoods = goodsList.stream().min(Comparator.comparing(Goods::getPrice)).orElse(null);
System.out.println("价格最小的商品" + JSON.toJSONString(minPriceGoods));
Integer maxNum = goodsList.stream().mapToInt(Goods::getNum).max().orElse(0);
System.out.println("获取到最大数量的值:" + maxNum);
Integer minNum = goodsList.stream().mapToInt(Goods::getNum).min().orElse(0);
System.out.println("获取到最小数量的值:" + minNum);
BigDecimal maxPrice = goodsList.stream().map(Goods::getPrice).collect(Collectors.toList()).stream().max(Comparator.comparing(BigDecimal::toString)).orElse(BigDecimal.ZERO);
System.out.println("获取价格最大值:" + maxPrice);
BigDecimal minPrice = goodsList.stream().map(Goods::getPrice).collect(Collectors.toList()).stream().min(Comparator.comparing(BigDecimal::toString)).orElse(BigDecimal.ZERO);
System.out.println("获取价格最小值:" + minPrice);

结果

价格最大的商品{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5}
价格最小的商品{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3}
获取到最大数量的值:4
获取到最小数量的值:1
获取价格最大值:5
获取价格最小值:3

分组

Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)

classifier:提供一个方法,该方法的返回值是键值对的健

mapfactory:提供一个初始化容器方法,用于创建新的map容器(使用该容器存放值对)

downstream:同一分组的合并方法,将同一个类型合并为指定类型,该方法返回的是键值对的值

System.out.println("分组前的数据:"+JSON.toJSONString(goodsList));
System.out.println("----------------------------------------按照商品类型进行分组------------------------------------------");
//按照商品类型进行分组
Map<String, List<Goods>> map1 = goodsList.stream().collect(Collectors.groupingBy(Goods::getGoodsType));
for (String key : map1.keySet()) {
       System.out.println("key:" + key + " values:" + map1.get(key));
}
System.out.println("----------------------------------------按照商品类型分组,给出对应的价格------------------------------------------");
// 按照商品类型分组,给出对应的价格
Map<String, List<BigDecimal>> map2 = goodsList.stream().collect(Collectors.groupingBy(Goods::getGoodsType, HashMap::new, Collectors.mapping(Goods::getPrice, Collectors.toList())));
for (String key : map2.keySet()) {
       System.out.println("key:" + key + " values:" + map2.get(key));
}
// 按照商品类型分组增加合并函数,计算每种类型的总金额
Map<String, BigDecimal> map3 = goodsList.stream().collect(Collectors.groupingBy(Goods::getGoodsType, HashMap::new, Collectors.reducing(BigDecimal.ZERO, Goods::getPrice, BigDecimal::add)));
System.out.println("-----------------------------------------按照商品类型分组增加合并函数,计算每种类型的总金额-----------------------");
for (String key : map3.keySet()) {
       System.out.println("key:" + key + " values:" + map3.get(key));
}
// 按照商品类型分组,增加平均值计算
Map<String, Double> map4 = goodsList.stream().collect(Collectors.groupingBy(Goods::getGoodsType, HashMap::new, Collectors.averagingDouble(Goods::getNum)));
System.out.println("-----------------------------------------按照商品类型分组,增加平均值计算-----------------------------------------");
for (String key : map4.keySet()) {
       System.out.println("key:" + key + " values:" + map4.get(key));
}

结果 

分组前的数据:[{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5},{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4},{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3},{"goodsName":"桃子","goodsType":"水果","id":3,"num":2,"price":3}]
----------------------------------------按照商品类型进行分组------------------------------------------
key:水果 values:[Goods(id=2, num=3, price=5, goodsType=水果, goodsName=香蕉), Goods(id=1, num=2, price=3, goodsType=水果, goodsName=苹果), Goods(id=3, num=2, price=3, goodsType=水果, goodsName=桃子)]
key:饮料 values:[Goods(id=5, num=1, price=5, goodsType=饮料, goodsName=可乐)]
key:零食 values:[Goods(id=4, num=4, price=4, goodsType=零食, goodsName=饼干)]
----------------------------------------按照商品类型分组,给出对应的价格------------------------------------------
key:水果 values:[5, 3, 3]
key:饮料 values:[5]
key:零食 values:[4]
-----------------------------------------按照商品类型分组增加合并函数,计算每种类型的总金额-----------------------
key:水果 values:11
key:饮料 values:5
key:零食 values:4
-----------------------------------------按照商品类型分组,增加平均值计算-----------------------------------------
key:水果 values:2.3333333333333335
key:饮料 values:1.0
key:零食 values:4.0

去重

Stream distinct()

// 按照价格去重
List<BigDecimal> distinctPrice = goodsList.stream().map(Goods::getPrice).distinct().collect(Collectors.toList());
System.out.println("按照价格去重,获取对应价格:" + distinctPrice);
// 按照某个值对实体类进行去重
List<Goods> list1 = goodsList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Goods::getPrice))), ArrayList::new));
System.out.println("按照对象某个值去重,获取对象:" + list1);

结果

按照价格去重,获取对应价格:[5, 4, 3]
按照对象某个值去重,获取对象:[Goods(id=1, num=2, price=3, goodsType=水果, goodsName=苹果), Goods(id=4, num=4, price=4, goodsType=零食, goodsName=饼干), Goods(id=5, num=1, price=5, goodsType=饮料, goodsName=可乐)]

截断

// 从哪个小标开始截取,注意,下标从0开始

Stream skip(long n)

// 截取的数量

Stream limit(long maxSize)

System.out.println("全量数据:" + JSON.toJSONString(goodsList));
System.out.println("第一页的数据为:" + JSON.toJSONString(goodsList.stream().skip(0).limit(2).collect(Collectors.toList())));
goodsList = goodsList.stream().skip(2).limit(2).collect(Collectors.toList());
System.out.println("第二页的数据为:" + JSON.toJSONString(goodsList));

 结果

全量数据:[{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5},{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4},{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3},{"goodsName":"桃子","goodsType":"水果","id":3,"num":2,"price":3}]
第一页的数据为:[{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5}]
第二页的数据为:[{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4},{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3}]

移除

//按条件移除

boolean removeIf(Predicate<? super E> filter)
//移除某个对象
boolean remove(Object o);
//移除集合
boolean removeAll(Collection<?> c);

//按照条件移除
goodsList.removeIf(g -> g.getGoodsType().equals("零食"));
System.out.println("移除零食类型的数据为:" + JSON.toJSONString(goodsList));
//按照对象移除
goodsList.remove(goods1);
System.out.println("移除对象为:" + JSON.toJSONString(goodsList));
//按照集合移除
List<Goods> goodsListNew = Stream.of(goods1, goods2 ).collect(Collectors.toList());
System.out.println("需要移除的集合值"+JSON.toJSONString(goodsListNew));
goodsList = Stream.of(goods1, goods2, goods3, goods4, goods5).collect(Collectors.toList());
System.out.println("新的集合值"+JSON.toJSONString(goodsList));
goodsList.removeAll(goodsListNew);
System.out.println("移除集合以后的集合值:"+JSON.toJSONString(goodsList));

 结果

移除零食类型的数据为:[{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3}]
移除对象为:[]
需要移除的集合值[{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5}]
新的集合值[{"goodsName":"苹果","goodsType":"水果","id":1,"num":2,"price":3},{"goodsName":"香蕉","goodsType":"水果","id":2,"num":3,"price":5},{"goodsName":"桃子","goodsType":"水果","id":3,"num":2,"price":3},{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4},{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5}]
移除集合以后的集合值:[{"goodsName":"桃子","goodsType":"水果","id":3,"num":2,"price":3},{"goodsName":"饼干","goodsType":"零食","id":4,"num":4,"price":4},{"goodsName":"可乐","goodsType":"饮料","id":5,"num":1,"price":5}]

猜你喜欢

转载自blog.csdn.net/qq_36138652/article/details/131668583