直接上代码,该案例可以作为个人的案例储备,用于自己的知识储备,不断更新
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;
}
}
}