Bootstrap

stream()转map转list、distinct()去重、判断空值、sorted排序正序多字段排序

package demo.io;

import demo.api.JavaBean.Student;
import org.junit.platform.commons.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: x
 * @Date: 2022-04-11 16:35
 */
public class stream流操作 {
    public static void main(String[] args) {
        Student student = new Student();
        student.setId(1);
        student.setName("dht");
        Student student2 = new Student();
        student2.setId(2);
        student2.setName("dht2");
        List<Student> studentList = new ArrayList<>();
        studentList.add(student);
        studentList.add(student2);

        //获取list<实体类>其中一个属性(可指定类型)
        List<Object> nameList = studentList.stream().map(Student::getName).collect(Collectors.toList());
        System.out.println("nameList = " + nameList);
        Object o = nameList.stream().reduce((x, y) -> x.toString() + " + " + y.toString()).get();
        System.out.println("list所有值相加 = " + o);
        //判断list<String>是否包含空字符串
        boolean b = nameList.stream().allMatch(name -> StringUtils.isBlank(name.toString()));
        System.out.println(b);
        //获取list<实体类>其中两个属性为map集合
        Map<Integer, String> map = studentList.stream().collect(Collectors.toMap(Student::getId, Student::getName));
        System.out.println("map = " + map);
        //获取list<实体类>其中两个属性为map集合,若id重复则获取后者
        Student student3 = new Student(2, "dht3");
        studentList.add(student3);
        Map<Integer, String> map2 = studentList.stream().collect(Collectors.toMap(Student::getId, Student::getName,
                (String key1, String key2) -> key2));
        System.out.println("若id重复则获取后者:map2 = " + map2);
        //获取list<实体类>其中两个属性为map集合,若id重复则获取两者
        Map<Integer, String> map3 = studentList.stream().collect(Collectors.toMap(Student::getId, Student::getName, (key1, key2) -> key1 + "," + key2));
        System.out.println("若id重复则获取两者:map3 = " + map3);
        //重要:重复时将重复key的数据组成集合
        // toMap()的第一个参数就是用来生成key值的,第二个参数就是用来生成value值的。
        // 第三个参数用在key值冲突的情况下:如果新元素产生的key在Map中已经出现过了,第三个参数就会定义解决的办法。
        Map<Integer, List<String>> map4 = studentList.stream().collect(Collectors.toMap(Student::getId,
                p -> {
                    List<String> getNameList = new ArrayList<>();
                    getNameList.add(p.getName());
                    return getNameList;
                },
                (List<String> value1, List<String> value2) -> {
                    value1.addAll(value2);
                    return value1;
                }
        ));
        System.out.println("重要:重复时将重复key的数据组成集合" + map4);

        //获取list<实体类>其中一个属性(有空值)
        Student student4 = new Student(4, null);
        // studentList.add(student4);
        List<Object> nameList2 = studentList.stream().map(sdsTest -> sdsTest.getName() == null ? "0" : sdsTest.getName()).collect(Collectors.toList());
        System.out.println("获取list<实体类>其中一个属性(有空值)nameList2 = " + nameList2);

        //去重(需使用@Data重写hashCode和equals)
        Student student5 = new Student(2, "dht3");
        studentList.add(student5);
        List<Integer> nameListNoDistinct = studentList.stream().map(Student::getId).collect(Collectors.toList());
        List<Integer> nameListDistinct = studentList.stream().distinct().map(Student::getId).collect(Collectors.toList());
        System.out.println("未去重 = " + nameListNoDistinct);
        System.out.println("distinct()去重 = " + nameListDistinct);

        //去重实体类的指定属性
        List<Integer> ids = new ArrayList<>();//用于临时存储TestValue的Name
        List<Student> studentDistinctId = studentList.stream().filter(
                v -> {
                    if (ids.contains(v.getId())) {
                        return false;
                    } else {
                        ids.add(v.getId());
                        return true;
                    }
                }).collect(Collectors.toList());
        System.out.println("去重实体类的指定属性id : " + studentDistinctId);

        //排序 加reversed()倒序
        List<Student> idListSorted = studentList.stream().sorted(Comparator.comparing(Student::getId, Comparator.nullsFirst(Integer::compareTo))//nullsFirst:空值放前面
                .reversed()//倒序(注意倒序后空值在后面)
                .thenComparing(Student::getName)//第二个排序字段正序
                .reversed()//倒序
        ).collect(Collectors.toList());
        System.out.println("排序 = " + idListSorted);
        //基本数据类型倒序
        List<Integer> integerList = Stream.of(1, 4, 3, 2).collect(Collectors.toList());
        List<Integer> integerReverseOrderList = integerList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        System.out.println("基本数据类型倒序 = " + integerReverseOrderList);

        System.out.println("studentList = " + studentList);
        //根据字段分组
        Map<String, List<Student>> map1 = studentList.stream().collect(Collectors.groupingBy(Student::getName));
        System.out.println("根据字段分组map1 = " + map1);
        // 将员工先按id分组,再按名称分组
        Map<Integer, Map<String, List<Student>>> group2 = studentList.stream().collect(Collectors.groupingBy(Student::getId, Collectors.groupingBy(Student::getName)));
        System.out.println("将员工先按id分组,再按名称分组group2 = " + group2);

        //根据实体类某字段去重
        List<Student> studentDistinctByNameArrayList = studentList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new));
        System.out.println("studentDistinctByNameArrayList = " + studentDistinctByNameArrayList);

        //求和
        System.out.println("求和:" + studentList.stream().mapToInt(Student::getId).sum());
        // 求平均值
        Double average = studentList.stream().collect(Collectors.averagingDouble(Student::getId));
        System.out.println("求平均值 = " + average);
        //求最大值
        Optional<Student> max1OfStudent = studentList.stream().max(Comparator.comparing(Student::getId));
        Optional<Integer> maxOfmaxBy = studentList.stream().map(Student::getId).collect(Collectors.maxBy(Integer::compare));
        Optional<Integer> maxOfcompare = studentList.stream().map(Student::getId).max(Integer::compare);
        System.out.println("求最大值max1OfStudent = " + max1OfStudent.get());
        System.out.println("求最大值maxOfmaxBy = " + maxOfmaxBy.get());
        System.out.println("求最大值maxOfcompare = " + maxOfcompare.get());
        // 一次性统计某字段所有信息(总数,求和,最小值,平均值和最大值)
        DoubleSummaryStatistics collect = studentList.stream().collect(Collectors.summarizingDouble(Student::getId));
        System.out.println("studentList = " + studentList);
        System.out.println("一次性统计所有信息 = " + collect);
        //拼接
        String names = studentList.stream().map(Student::getName).collect(Collectors.joining("-"));
        System.out.println("拼接names = " + names);

        //是否任一匹配
        boolean anyMatch = studentList.stream().anyMatch(student1 -> "dht".equals(student1.getName()));
        System.out.println("是否包含名字“dht” = " + anyMatch);
        //是否全部匹配
        boolean allMatch = studentList.stream().allMatch(student1 -> "dht".equals(student1.getName()));
        System.out.println("是否全部名字都为“dht” = " + allMatch);

        //获取名字最长
        List<String> list = Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");
        Optional<String> max = list.stream().max(Comparator.comparing(String::length));
        System.out.println("最长的字符串:" + max.get());
        List<Integer> integerList1 = Arrays.asList(7, 6, 9, 4, 11, 6);
        // 自然排序
        Optional<Integer> maxIntegerList1 = integerList1.stream().max(Integer::compareTo);
        // 自定义排序
        Optional<Integer> max2IntegerList1 = integerList1.stream().max(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println("自然排序的最大值:" + maxIntegerList1.get());
        System.out.println("自定义排序的最大值:" + max2IntegerList1.get());
        //统计数量
        List<Integer> listOfInt = Arrays.asList(7, 6, 4, 8, 2, 11, 9);
        long count = listOfInt.stream().filter(x -> x > 6).count();
        System.out.println("list中大于6的元素个数:" + count);
        //数组转stream且字符串转大写
        String[] strArr = {"abcd", "bcdd", "defde", "fTr"};
        List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());
        System.out.println("每个元素大写:" + strList);
        //将两个字符数组合并成一个新的字符数组。
        List<String> listOfStrArr = Arrays.asList("m,k,l,a", "1,3,5,7");
        List<String> listNewOfStrArr = listOfStrArr.stream().flatMap(s -> {
            // 将每个元素转换成一个stream
            String[] split = s.split(",");
            Stream<String> s2 = Arrays.stream(split);
            return s2;
        }).collect(Collectors.toList());
        System.out.println("处理前的集合:" + listOfStrArr);
        System.out.println("处理后的集合:" + listNewOfStrArr);
        //合并流
        String[] arr1 = {"a", "b", "c", "d"};
        String[] arr2 = {"d", "e", "f", "g"};
        Stream<String> stream1 = Stream.of(arr1);
        Stream<String> stream2 = Stream.of(arr2);
        // concat:合并两个流并去重
        List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
        System.out.println("流合并concat:" + newList);
        // limit:限制从流中获得前n个数据
        List<Integer> collectOfLimit = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
        // skip:跳过前n个数据
        List<Integer> collectOfSkip = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
        System.out.println("限制从流中获得前n个数据limit:" + collectOfLimit);
        System.out.println("跳过前n个数据skip:" + collectOfSkip);
    }
}

控制台打印:
nameList = [dht, dht2]
list所有值相加 = dht + dht2
false
map = {1=dht, 2=dht2}
若id重复则获取后者:map2 = {1=dht, 2=dht3}
若id重复则获取两者:map3 = {1=dht, 2=dht2,dht3}
重要:重复时将重复key的数据组成集合{1=[dht], 2=[dht2, dht3]}
获取list<实体类>其中一个属性(有空值)nameList2 = [dht, dht2, dht3]
未去重 = [1, 2, 2, 2]
distinct()去重 = [1, 2, 2]
去重实体类的指定属性id : [[id=1, name=dht], [id=2, name=dht2]]
排序 = [[id=1, name=dht], [id=2, name=dht3], [id=2, name=dht3], [id=2, name=dht2]]
基本数据类型倒序 = [4, 3, 2, 1]
studentList = [[id=1, name=dht], [id=2, name=dht2], [id=2, name=dht3], [id=2, name=dht3]]
根据字段分组map1 = {dht=[[id=1, name=dht]], dht3=[[id=2, name=dht3], [id=2, name=dht3]], dht2=[[id=2, name=dht2]]}
将员工先按id分组,再按名称分组group2 = {1={dht=[[id=1, name=dht]]}, 2={dht3=[[id=2, name=dht3], [id=2, name=dht3]], dht2=[[id=2, name=dht2]]}}
studentDistinctByNameArrayList = [[id=1, name=dht], [id=2, name=dht2], [id=2, name=dht3]]
求和:7
求平均值 = 1.75
求最大值max1OfStudent = [id=2, name=dht2]
求最大值maxOfmaxBy = 2
求最大值maxOfcompare = 2
studentList = [[id=1, name=dht], [id=2, name=dht2], [id=2, name=dht3], [id=2, name=dht3]]
一次性统计所有信息 = DoubleSummaryStatistics{count=4, sum=7.000000, min=1.000000, average=1.750000, max=2.000000}
拼接names = dht-dht2-dht3-dht3
是否包含名字“dht” = true
是否全部名字都为“dht” = false
最长的字符串:weoujgsd
自然排序的最大值:11
自定义排序的最大值:11
list中大于6的元素个数:4
每个元素大写:[ABCD, BCDD, DEFDE, FTR]
处理前的集合:[m,k,l,a, 1,3,5,7]
处理后的集合:[m, k, l, a, 1, 3, 5, 7]
流合并concat:[a, b, c, d, e, f, g]
限制从流中获得前n个数据limit:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
跳过前n个数据skip:[3, 5, 7, 9, 11]

;