java Lambda表达式集合去重&stream

1.背景

很多时候我们查询出的集合数据有重复,比如查询出产品,有同名的产品,我们需要把同名的产品名称去掉,使用lambda表示式可以优雅的实现

2.stream使用

package demo01;

import lombok.Data;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: lidp
 * @Date: 2022-04-22 14:28
 * @Description:
 */
public class Test01 {
    /**
     * 遍历
     */
    @Test
    public void test01ForEach() {
        List listNum = Lists.newArrayList(1, 2, 3, 9, 20, 7, 7, 20, 7);
        listNum.forEach(x -> System.out.println(x));
    }

    /**
     * stream
     * 两句话理解Stream:
     * 

* 1.Stream是元素的集合,这点让Stream看起来用些类似Iterator; * 2.可以支持顺序和并行的对原Stream进行汇聚的操作; * 大家可以把Stream当成一个装饰后的Iterator。原始版本的Iterator,用户只能逐个遍历元素并对其执行某些操作; * 包装后的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等, * 具体这些操作如何应用到每个元素上,就给Stream就好了!原先是人告诉计算机一步一步怎么做, * 现在是告诉计算机做什么,计算机自己决定怎么做。当然这个“怎么做”还是比较弱的。 *

* filter 条件过滤 * collect 收集结果 * Collectors.toList() -- 转为集合 */ @Test public void test02Filter() { List listNum = Lists.newArrayList(1, 2, 3, 9, 20, 7, 7, 20, 7); List collect = listNum.stream().filter(x -> x > 10).collect(Collectors.toList()); System.out.println(collect); } /** * map 对值处理或者转换,如将原来集合中的数据都乘以2 *

* mapToInt 是把处理结果转为 int */ @Test public void test03Map() { List listNum = Lists.newArrayList(1, 2, 3); List collect = listNum.stream().map(x -> x * 2).collect(Collectors.toList()); System.out.println(collect); // () -> new ArrayList() 简写为 ArrayList::new // (list, item) -> list.add(item) 简写为 ArrayList::add // (result, list) -> result.addAll(list) 简写为: ArrayList::addAll // List collect1 = listNum.stream().mapToInt(x -> x * 2).collect(() -> new ArrayList(), (list, item) -> list.add(item), (result, list) -> result.addAll(list)); List collect1 = listNum.stream().mapToInt(x -> x * 2).collect(ArrayList::new, ArrayList::add, ArrayList::addAll); System.out.println(collect1); int[] ints = listNum.stream().mapToInt(x -> x * 2).toArray(); System.out.println(ints); } /** * 分组统计 * 统计每个数字出现的次数 */ @Test public void test04GroupingBy() { List listNum = Lists.newArrayList("zs", "ls", "ww", "zs", "zs", "zs", "ww"); Map collect = listNum.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); // {ww=2, ls=1, zs=4} System.out.println(collect); // Function.identity() t -> t,指遍历出来的当前对象 Map> collect1 = listNum.stream().collect(Collectors.groupingBy(Function.identity())); //{ww=[ww, ww], ls=[ls], zs=[zs, zs, zs, zs]} System.out.println(collect1); } /** * reduce方法:reduce方法非常的通用,后面介绍的count,sum等都可以使用其实现 */ @Test public void test05Reduce() { List listNum = Lists.newArrayList(1, 2, 3, 9, 20, 7, 7, 20, 7); System.out.println("对大于5的数累加:" + listNum); // 对大于⑤的数累加:[1, 2, 3, 9, 20, 7, 7, 20, 7] =>大于5的数 [9, 20, 7, 7, 20, 7] // 执行累加 9+20=29+7=36+7=43+20=63+7=70 ,如下结果为70 Integer integer = listNum.stream().filter(x -> x > 5).reduce((x, item) -> x + item).get(); System.out.println(integer); // 70 } /** * 大小比较&&排序&&去重 * 获取数组中的最大值 * ifPresent 存在时才返回 */ @Test public void test06Sort() { List listNum = Lists.newArrayList(10, 2, 3, 9, 20, 7, 7, 20, 7); // List listNum =new ArrayList<>(); // 大小比较 listNum.stream().max((x, y) -> (x < y) ? -1 : ((x == y) ? 0 : 1) ).ifPresent(x -> System.out.println(x)); listNum.stream().max((n1, n2) -> n1.compareTo(n2) ).ifPresent(x -> System.out.println(x)); listNum.stream().max(Integer::compareTo).ifPresent(x -> System.out.println(x)); // 从小到大 List collect = listNum.stream().sorted(Integer::compareTo).collect(Collectors.toList()); System.out.println(collect); // 从大到小 List collect2 = listNum.stream().sorted((x, y) -> (x < y) ? 1 : ((x == y) ? 0 : -1)).collect(Collectors.toList()); System.out.println(collect2); listNum.sort(Integer::compareTo); System.out.println(listNum); // 去重排序 List collect3 = listNum.stream().distinct().sorted(Integer::compareTo).collect(Collectors.toList()); System.out.println(collect3); } /** * – 搜索相关 * – allMatch:是不是Stream中的所有元素都满足给定的匹配条件 * – anyMatch:Stream中是否存在任何一个元素满足匹配条件 * – findFirst: 返回Stream中的第一个元素,如果Stream为空,返回空Optional * – noneMatch:是不是Stream中的所有元素都不满足给定的匹配条件 * – max和min:使用给定的比较器(Operator),返回Stream中的最大|最小值 */ @Test public void test07AllMatch() { List listNum = Lists.newArrayList(1, 2, 3, 9, 20, 7, 7, 20, 7); boolean b = listNum.stream().allMatch(x -> x > 10); System.out.println(b);// false // java.util.NoSuchElementException: No value present 无数据时报错 Integer first = listNum.stream().filter(x -> x > 2).findFirst().get(); System.out.println(first); // Optional.empty } /** * 测试 * 3.3.1可变汇聚 * 可变汇聚对应的只有一个方法:collect,正如其名字显示的,它可以把Stream中的要有元素收集到一个结果容器中(比如Collection)。 * 先看一下最通用的collect方法的定义(还有其他override方法): * * R collect(Supplier supplier, * BiConsumer accumulator, * BiConsumer combiner); * 先来看看这三个参数的含义: * 参数一:Supplier supplier是一个工厂函数,用来生成一个新的容器; * 参数二:BiConsumer accumulator也是一个函数,用来把Stream中的元素添加到结果容器中; * 参数三:BiConsumer combiner还是一个函数,用来把中间状态的多个结果容器合并成为一个(并发的时候会用到)。看晕了?来段代码! * 集合转为map */ @Test public void test06() { List list = new ArrayList<>(); list.add(new Product(1, "手机1")); list.add(new Product(2, "手机2")); list.add(new Product(3, "手机3")); // 根据名称获取产品 HashMap resultMap = list.stream() .collect( HashMap::new, // 参数一 (map, item) -> map.put(item.getName(), item), // 参数二 HashMap::putAll); // 参数三 System.out.println(resultMap); // 方式二 HashMap resultMap2 = list.stream() .collect( HashMap::new, // 参数一 (map, item) -> map.put(item.getName(), item), // 参数二 (result, map) -> result.putAll(map)); // 参数三 System.out.println(resultMap2); // 方式三 Map resultMap3 = list.stream() .collect(Collectors.toMap(Product::getName, x -> x.getId())); System.out.println(resultMap3); } } @Data class Product { private Integer id; private String name; public Product(Integer id, String name) { this.id = id; this.name = name; } }

3.集合去重

 /**
     * 测试
     * 去除重复的产品名称
     */
    @Test
    public void test() {
        Map map1 = new HashMap<>();
        map1.put("id", "1");
        map1.put("name", "苹果");

        Map map2 = new HashMap<>();
        map2.put("id", "2");
        map2.put("name", "香蕉");

        Map map3 = new HashMap<>();
        map3.put("id", "3");
        map3.put("name", "梨子");

        Map map4 = new HashMap<>();
        map4.put("id", "4");
        map4.put("name", "香蕉");

        List> list = new ArrayList<>();
        list.add(map1);
        list.add(map2);
        list.add(map3);
        list.add(map4);
        // 去重前:[{name=苹果, id=1}, {name=香蕉, id=2}, {name=梨子, id=3}, {name=香蕉, id=4}]
        System.out.println("去重前:" + list);
        ArrayList> mapArrayList = list.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(
                                s -> String.valueOf(s.get("name"))))), ArrayList::new));

        // 去重后:[{name=梨子, id=3}, {name=苹果, id=1}, {name=香蕉, id=2}]
        System.out.println("去重后:" + mapArrayList);
    }

3.完美!

你可能感兴趣的:(问题解决,java,开发语言,后端)