stream流各种操作案例(附上java和jsonObject、jsonArray的转换)

直接上代码,该案例可以作为个人的案例储备,用于自己的知识储备,不断更新

package com.generate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 注意这里只适用fastJson
 * 各种数据类型的转换,可以在这个基础上自行做一份属于自己的代码案例
 * @author IT701820
 */
public class StreamExample {

    @Data
    static class Student {

        private String id;

        @ApiModelProperty("名称")
        private String name;

        @ApiModelProperty("年龄")
        private Integer age;

        @ApiModelProperty("电话号码")
        private String phoneString;

        @ApiModelProperty("电话号码")
        private List<Integer> phones;

        @ApiModelProperty("分数")
        private Double grade;

        @ApiModelProperty("性别")
        private String sex;

        public Student(String name, Integer age, Double grade, String sex) {
            this.grade = grade;
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    }

    /**
     * 不可变的list对象创建
     */
    private final List<Student> list = Collections
            .singletonList(new Student("t", 1, (double) 20, "男"));

    /**
     * 可变的list对象创建,但是这里用了final,仅仅说明是在代码中是可变方式的创建
     */
    private final List<Student> changeList = Stream
            .of(new Student("t", 1, (double) 20, "男")).collect(Collectors.toList());

    /**
     * stream的案例方法
     */
    public void streamExample() {
        //取其中某个元素作为集合
        //1.取其中一个元素作为集合
        List<Integer> ageList = list.stream()
                .map(Student::getAge).collect(Collectors.toList());
        Set<Integer> ageSet = list.stream()
                .map(Student::getAge).collect(Collectors.toSet());
        //2.flat用法,取出某个字段重新组合结果值
        List<String> phoneList = list.stream().map(Student::getPhoneString)
                .flatMap(s -> Arrays.stream(s.split(","))).collect(Collectors.toList());

        //2.数学计算(求和,取平均值等等)
        //1> 求和,对学生的所有的成绩进行求和mapToDouble,当然有各种类型的数据类型求和方式mapToInteger、mapToLong等等
        double sumStudentScoreDouble = list.stream().mapToDouble(Student::getGrade).sum();
        //2> 获取对象中的年龄最大值(这里注意只能获取到一个,想要获取到年龄最大的集合需要根据最大年龄再重新获取)
        Integer maxAge = list.stream()
                .max(Comparator.comparing(Student::getAge)).get().getAge();
        Integer maxAge2 = list.stream()
                .mapToInt(Student::getAge).max().getAsInt();
        //3> 最小值(多个值取第一个,只能取一个,有点随机的意思,所以这个慎用)
        Student student = list.stream()
                .min(Comparator.comparing(Student::getGrade)).get();
        //4> 统计所有的成绩
        DoubleSummaryStatistics statistics = list.stream()
                .collect(Collectors.summarizingDouble(Student::getGrade));
        //平均值
        double average = statistics.getAverage();
        //总数
        long count = statistics.getCount();
        //最大值
        double max2 = statistics.getMax();
        //最小值
        double min2 = statistics.getMin();
        //求和总值
        double sum = statistics.getSum();

        //3.去重
        //1> 对象去重(根据id去重),这种重复的值默认取第一个
        List<Student> studentList = list.stream()
                .collect(Collectors.collectingAndThen
                        (Collectors.toCollection(() ->
                                new TreeSet<>(Comparator.comparing(Student::getId))), ArrayList::new));
        //多条件去重(根据name+age去重,如果单个条件无法去重的时候)
        List<Student> studentList2 = list.stream()
                .collect(Collectors.collectingAndThen
                        (Collectors.toCollection(() ->
                                new TreeSet<>(Comparator.comparing
                                        (o -> o.getAge() + ";" + o.getName()))), ArrayList::new));
        //8种基础数据类型去重
        List<Integer> pathList = ageList.stream()
                .distinct().collect(Collectors.toList());
        //4.条件过滤
        //对象过滤(查询age年龄大于18岁的)(名字中包含唐的对象)
        List<Student> resultList1 = list.stream()
                .filter(s -> s.getAge() > 18).collect(Collectors.toList());
        List<Student> resultList2 = list.stream()
                .filter(s -> ageList.contains(s.getAge())).collect(Collectors.toList());
        List<Student> resultList3 = list.stream()
                .filter(s -> s.getName().contains("唐")).collect(Collectors.toList());


        //5.获取各种map形式
        Map<String, Integer> map = list.stream()
                .collect(Collectors.toMap(Student::getId, Student::getAge));
        //针对重复的key去重(根据name去重),这种可以自定义取哪个值,并相加
        Map<String, Integer> map1 = list.stream()
                .collect(Collectors.toMap(Student::getName, Student::getAge, Integer::sum));
        Map<String, Student> collect = list.stream()
                .collect(Collectors.toMap(Student::getId, Function.identity()));
        //针对重复的key去重(根据name去重),这种可以自定义取哪个值
        Map<String, Student> studentMap = list.stream()
                .collect(Collectors.toMap(Student::getName, Function.identity(),
                        (o1, o2) -> o2));
        Map<String, Student> studentMap2 = list.stream()
                .collect(Collectors.toMap(Student::getName, Function.identity(),
                        (o1, o2) -> {
                            //对重复的值进行操作(重复的值操作的都是value对象,所以这个返回值一定要是对象值)
                            o1.setAge(o1.getAge()+o2.getAge());
                            return o1;
                        }));

        //将对象的重复属性为key,重复的对象集合为value(存在多个对象,其中有一些值是重复的,那么可以单独拎出来作为一个集合)
        Map<String, List<Student>> attendanceMap = list.stream()
                .collect(Collectors.groupingBy(Student::getName, Collectors.toList()));
        //分组之后,获取每个组种某个参数最大的属性值
        Map<String, Double> stringDoubleMap = list.stream().collect(Collectors.groupingBy(Student::getName,
                Collectors.collectingAndThen(
                        Collectors.maxBy(Comparator.comparing(Student::getGrade))
                        , f -> f.map(Student::getGrade).get())));

        //分组之后,获取每个组种某个参数最大的对象
        Map<String, Student> stringStudentMap = list.stream().collect(Collectors.toMap(Student::getName,
                Function.identity(), BinaryOperator.maxBy(Comparator.comparing(Student::getGrade))));
        //根据名称分组,取成绩的平均值(Collectors.averagingDouble也有Collectors.averagingInt,根据数据类型选择)
        Map<String, Double> userMap = list.stream()
                .collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getGrade)));
        //根据名称分组,然后组装成新的对象StudentVo,这个是分组之后再转换,也可以直接转换再分组,这样的话就分为两步进行操作
        Map<String, List<StudentVo>> studentVoMap = list.stream()
                .collect(Collectors.groupingBy(Student::getName,
                        Collectors.mapping(s -> new StudentVo(s.getName(),s.getAge(),s.getGrade(), s.getSex()),
                                Collectors.toList())));
        //根据性别进行分组(分组求和)
        Map<String, DoubleSummaryStatistics> collectGroupBySex = list.stream()
                .collect(Collectors.groupingBy(Student::getSex,
                        Collectors.summarizingDouble(Student::getGrade)));
        System.out.println("男生:" + collectGroupBySex.get("男"));
        System.out.println("男生的分数和:" + collectGroupBySex.get("男").getSum());
        System.out.println("男生中最大分数:" + collectGroupBySex.get("男").getMax());
        System.out.println("男生中最小分数:" + collectGroupBySex.get("男").getMin());
        System.out.println("男生中平均分数:" + collectGroupBySex.get("男").getAverage());
        System.out.println("男生个数:" + collectGroupBySex.get("男").getCount());

        //自定义分组求和并排序
        Map<Student, Double> studentDoubleTreeMap = list.stream()
                .collect(Collectors.groupingBy(o -> new Student(o.getName(), null, o.getGrade(), o.getSex()),
                        TreeMap::new, Collectors.summingDouble(Student::getGrade)));
        //分组之后,value值为集合大小
        Map<String, Long> attendanceMap1 = list.stream()
                .collect(Collectors.groupingBy(Student::getName, Collectors.counting()));
        //根据多条件分组,分组顺序为name和成绩和分数,简单的来说就是以最后的成绩进行分组
        Map<String, Map<Integer, Map<Double, List<Student>>>> mapMap = list.stream()
                .collect(Collectors.groupingBy(Student::getName,
                        Collectors.groupingBy(Student::getAge,
                                Collectors.groupingBy(Student::getGrade))));
        //根据年龄进行分组,然后对每个组内的所有成绩求和,先分组再求和(扩展,这里面可以是double也可以是Integer)
        Map<Integer, Double> doubleMap = list.stream()
                .collect(Collectors.groupingBy
                        (Student::getAge, Collectors.summingDouble(Student::getGrade)));
        //6.排序
        //从小到大(正序)
        List<Student> productList3 = list.stream()
                .sorted(Comparator.comparing(Student::getAge))
                .collect(Collectors.toList());
        //从大到小(倒序)
        List<Student> productList4 = list.stream()
                .sorted(Comparator.comparing(Student::getAge).reversed())
                .collect(Collectors.toList());

        //(多条件排序)对所有的同学先进行性别排序,然后再根据成绩排序(当然后续可以无限制增加条件)
        List<Student> collectSortedMore = list.stream()
                .sorted(Comparator.comparing(Student::getSex).reversed()
                        .thenComparing(Student::getGrade).reversed()).collect(Collectors.toList());

        //7.转换(Integer和String之间的互相转换,同理转换成Long或者Double都是同类似的)
        //1> List<Integer>转换成String数据类型
        List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
        String collect1 = integerList.stream().map(String::valueOf).collect(Collectors.joining(","));
        //2> 将对象的电话集合属性转换成电话字段
        list.forEach(s -> s.setPhoneString(s.getPhones().stream().map(String::valueOf).collect(Collectors.joining(","))));
        //3> List<Integer>转换成List<String>数据类型
        List<String> stringList = integerList.stream().map(String::valueOf).collect(Collectors.toList());
        //4> String(逗号拼接)转换成List<Integer>数据类型
        String numberString = "1,2,3";
        List<Integer> integerList1 = Arrays.stream(numberString.split(",")).map(Integer::valueOf).collect(Collectors.toList());
        //5> 对map的操作转换Map<String, List<Student>> attendanceMap
        attendanceMap.forEach((key, list) -> System.out.println("分数的总和为:"+list.stream().mapToDouble(Student::getGrade).sum()));
    }

//    public static void main(String[] args) {
//        List<Student> list = new ArrayList<>();
//        Student student1 = new Student("1",18,(double) 98,"男");
//        Student student2 = new Student("1",17,(double) 98,"男");
//        Student student3 = new Student("3",18,(double) 98,"男");
//        Student student4 = new Student("4",18,(double) 98,"男");
//        Student student5 = new Student("5",18,(double) 98,"男");
//        Student student6 = new Student("6",18,(double) 98,"男");
//        list.add(student1);
//        list.add(student2);
//        list.add(student3);
//        list.add(student4);
//        list.add(student5);
//        list.add(student6);
//        List<Student> studentArrayList = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
//                () -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new));
//        System.out.println(studentArrayList);
//    }

    /**
     * 对象转json字符串,或者转jsonObject等等的关于对象操作的案例
     * 这里完全使用到FastJson工具包(当然其他工具包也行,但是各种转换之间最好统一工具包,否则会有报错的可能性)
     */
    public void entity2JsonExample() {
        List<Student> list = new ArrayList<>();
        Student student1 = new Student("1",18,(double) 98,"男");
        Student student2 = new Student("1",17,(double) 98,"男");
        list.add(student1);
        list.add(student2);
        //1.java对象转json字符串
        String jsonString = JSON.toJSONString(student1);

        //2.json字符串转java对象(注意这种转换要先明确string字符串是对象的格式,要是集合的json串就要往jsonArray转,否则就会报错)
        Student parseObject = JSON.parseObject(jsonString, Student.class);
        //3.List<java对象>转json字符串(SerializerFeature.UseSingleQuotes表示每个key,value使用的是单引号,
        // 没有这个参数就是双引号的,当然存在很多格式,可以自己去SerializerFeature挨个试试,推荐使用双引号,没必要画蛇添足)
        String jsonArrayStringSing = JSON.toJSONString(list, SerializerFeature.UseSingleQuotes);
        String jsonArrayString = JSON.toJSONString(list);

        //4.json转List数组
        List<Student> studentList = JSON.parseArray(jsonArrayString, Student.class);

        //5.json转List<map>
        List<Map> maps = JSON.parseArray(jsonArrayString, Map.class);

        //6.json转map(可以指定key和value的数据类型,也可以写Integer等等,但是注意类型匹配)
        Map<String, String> stringMap = JSON.parseObject(jsonArrayString, new TypeReference<Map<String, String>>() {});

        //7.打印出存在null值的数据
        StudentVo studentVo = new StudentVo();
        studentVo.setName("学生");
        studentVo.setStudentList(list);
        System.out.println(JSON.toJSONString(studentVo, SerializerFeature.WriteMapNullValue));
        //输出类的地址值
        System.out.println(JSON.toJSONString(studentVo, SerializerFeature.WriteMapNullValue,SerializerFeature.WriteClassName));

        //8.json字符串转Map<String, Object>
        String stringJson = JSON.toJSONString(studentVo, SerializerFeature.WriteMapNullValue);
        Map<String, Object> map = JSONObject.parseObject(stringJson, new TypeReference<Map<String, Object>>() {});
        //同理map再转成jsonObject
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));


        //9.对时间进行格式化(默认是yyyy-MM-dd HH:mm:ss),这玩意还是很不错的
        System.out.println(JSON.toJSONString(new Date(), SerializerFeature.WriteDateUseDateFormat));
        //当然也可以指定输出哪种时间格式
        System.out.println(JSON.toJSONStringWithDateFormat(new Date(), "yyyy-MM-dd"));
    }

    /**
     * 对象和json和jsonObject、jsonArray之间的转换
     */
    public void entity2JsonObjectExample() {
        List<Student> list = new ArrayList<>();
        Student student1 = new Student("1",18,(double) 98,"男");
        Student student2 = new Student("1",17,(double) 98,"男");
        list.add(student1);
        list.add(student2);

        //操作单个对象----------------------------------
        //1.java对象转json字符串
        String jsonString = JSON.toJSONString(student1);

        //2.json字符串转jsonObject
        JSONObject jsonObject = JSONObject.parseObject(jsonString);

        //3.对象转jsonObject
        JSONObject toJson = (JSONObject) JSONObject.toJSON(student1);

        //4.json对象转json字符串,这个和toString还是有点不一样的,转成string的时候推荐使用下面这种
        String string = toJson.toJSONString();

        //5.json对象转成java对象
        Student toJavaObject = JSONObject.toJavaObject(toJson, Student.class);

        //6.json字符串转java对象
        Student parseObject = JSONObject.parseObject(jsonString, Student.class);

        //操作集合对象----------------------------------
        //7.java集合对象转json字符串
        String jsonArrayString = JSON.toJSONString(list);

        //8.json字符串转JSONArray
        JSONArray jsonArray = JSONObject.parseArray(jsonArrayString);

        //9.json字符串转List<Map>(如果是用[]包裹的字符串就用parseArray,使用{}包裹的就用parseObject),这个map不指定类型也没关系,那就手动转换一下
        List<Map> mapList = JSONArray.parseArray(JSON.toJSONString(jsonArrayString), Map.class);
        List<Map> mapList2 = JSONObject.parseArray(JSON.toJSONString(jsonArrayString), Map.class);

        //10.JSONArray转list对象
        List<Student> studentList = JSONObject.parseArray(jsonArray.toJSONString(), Student.class);

        //11.json字符串转list对象
        List<Student> studentList1 = JSONObject.parseArray(jsonArrayString, Student.class);

    }
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        Student student1 = new Student("1",18,(double) 98,"男");
        Student student2 = new Student(null,17,(double) 98,"男");
        list.add(student1);
        list.add(student2);
        String jsonArrayStringSing = JSON.toJSONString(list, SerializerFeature.UseSingleQuotes);
        System.out.println(jsonArrayStringSing);
        String jsonArrayString = JSON.toJSONString(list);
        System.out.println(jsonArrayString);
        StudentVo studentVo = new StudentVo();
        studentVo.setName("学生");
        studentVo.setStudentList(list);
        System.out.println(JSON.toJSONString(studentVo, SerializerFeature.WriteMapNullValue));
        System.out.println(JSON.toJSONString(studentVo, SerializerFeature.WriteMapNullValue,SerializerFeature.WriteClassName));
    }

    @Data
    static class StudentVo {

        private String id;

        @ApiModelProperty("名称")
        private String name;

        @ApiModelProperty("年龄")
        private Integer age;

        @ApiModelProperty("电话号码")
        private String phoneString;

        @ApiModelProperty("电话号码")
        private List<Integer> phones;

        @ApiModelProperty("分数")
        private Double grade;

        @ApiModelProperty("性别")
        private String sex;

        @ApiModelProperty("学生对象集合")
        private List<Student> studentList;

        public StudentVo(){}

        public StudentVo(String name, Integer age, Double grade, String sex) {
            this.grade = grade;
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    }
}


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值