package org.hzero.demo.java300.JavaStream18; import com.alibaba.fastjson.JSONArray; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.hzero.demo.TestLeetCode.Son; import java.util.*; import java.util.stream.Collectors; public class TestStream { /** * 总结一个流式处理可以分为三个部分:转换成流、中间操作、终端操作。 * 集合.stream变成流 数组流 文件流 * 中间操作 filter过滤 distinct去重 limit限制 sorted排序 map映射 flatmap * 终端操作 * anymatch allmatch查找 collect收集 * groupingBy 归类 reduce规约 * findFrist查找第一个 * 详解链接 * https://www.cnblogs.com/gaopengfirst/p/10813803.html * * @param args */ public static void main(String[] args) { String sssss = "wangqianyu-1110"; System.out.println(StringUtils.substringAfter(sssss , "-")); //初始化集合 List<User> list = new ArrayList<User>() { { add(new User(1L, "张三", 10, "清华大学")); add(new User(2L, "李四", 12, "清华大学")); add(new User(3L, "王五", 15, "清华大学")); add(new User(4L, "赵六", 12, "清华大学")); add(new User(5L, "田七", 25, "北京大学")); add(new User(6L, "小明", 16, "北京大学")); add(new User(7L, "小红", 14, "北京大学")); add(new User(8L, "小华", 14, "浙江大学")); add(new User(9L, "小丽", 17, "浙江大学")); add(new User(10L, "小何", 10, "浙江大学")); } }; //測試过滤方法 fileter(list); //distinct去重 distinct(list); //取前两名 limit(list, 2); //排序 sorted(list); //skip跳过 skip(list, 3); //映射 map(list); //求和 mapToInt(list); //扁平化流 flatMap(); //查找 allMatch(list); //查找第一个 findFirst(list); //规约 reduce(list); //计数 counting(list); //计算最大值 maxBy(list); //通过收集取总和 summingInt(list); //拼接 joining(list); //根据某个字段去重 distinctBySchool(list); } /** * 1. 过滤 * 1.1 filter * 我们希望过滤筛选出处所有学校是清华大学的user: */ public static void fileter(List<User> list) { list = list.stream().filter(user -> user.getSchool().equals("清华大学")).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { list.forEach(user -> System.out.print(user.getName() + ",")); } System.out.println("fileter=================="); } /** * 1.2 distinct * 去重,我们希望获取大学代表 * //过滤出有效的卡信息(根据患者id去重) * List effectList = patientServerVOList.stream(). * collect(Collectors.collectingAndThen(Collectors.toCollection(()-> * new TreeSet<>(Comparator.comparing(PatientServerVO::getPatId))),ArrayList::new)); */ public static void distinctBySchool(List<User> list) { list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection( () -> new TreeSet<>(Comparator.comparing(User::getSchool))) , ArrayList :: new) ); System.out.println("distinctBySchool=================="); System.out.println(list.size()); List<Integer> ageList = list.stream().map(user -> user.getAge()).distinct().collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { ageList.forEach(integer -> System.out.print(integer + ",")); } } /** * 1.2 distinct * 去重,我们希望获取所有user的年龄(年龄不重复) */ public static void distinct(List<User> list) { List<Integer> ageList = list.stream().map(user -> user.getAge()).distinct().collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { ageList.forEach(integer -> System.out.print(integer + ",")); } System.out.println("distinct=================="); } /** * 1.3 limit * 返回前n个元素的流,当集合的长度小于n时,则返回所有集合。 * 如获取年龄是偶数的前2名user: */ public static void limit(List<User> list, int n) { list = list.stream().filter(user -> user.getAge() % 2 == 0).limit(n).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { list.forEach(user -> System.out.print(user.getName() + ",")); } System.out.println("limit=================="); } /** * 1.4 sorted * 排序,如现在我想将所有user按照age从大到小排序 */ public static void sorted(List<User> list) { //Map<String, String> map = list.stream().collect(Collectors.toMap(User :: getName , User -> User.getSchool()== null ? "" : User.getSchool())); list = list.stream().sorted((user1, user2) -> user2.getAge() - user1.getAge()).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { list.forEach(user -> System.out.print(user.getName() + ",")); } System.out.println("sorted=================="); } /** * 1.5 skip * 跳过n个元素后再输出 * 如输出list集合跳过前两个元素后的list */ public static void skip(List<User> list, int n) { list = list.stream().skip(n).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(list)) { list.forEach(user -> System.out.print(user.getName() + ",")); } System.out.println("skip=================="); } /** * 2 映射 * 2.1 map * 就是讲user这个几个精简为某个字段的集合 * 如我现在想知道学校是清华大学的所有学生的姓名: */ public static void map(List<User> list) { List<String> nameList = list.stream(). filter(user -> "清华大学".equals(user.getSchool())). map(user -> user.getName().equals("") ? "" : user.getName()) .collect(Collectors.toList()); List<String> list1 = list.stream().map(User -> StringUtils.isBlank(User.getName()) ? "" : User.getName()).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(nameList)) { nameList.forEach(s -> System.out.print(s + ",")); } System.out.println("map=================="); } /** * 除了上面这类基础的map,java8还提供了 * mapToDouble(ToDoubleFunction<? super T> mapper), * mapToInt(ToIntFunction<? super T> mapper), * mapToLong(ToLongFunction<? super T> mapper), * 这些映射分别返回对应类型的流, * java8为这些流设定了一些特殊的操作,比如查询学校是清华大学的user的年龄总和: */ public static void mapToInt(List<User> list) { int ageNum = list.stream(). filter(user -> "清华大学".equals(user.getSchool())). mapToInt(User::getAge).sum(); System.out.println("清华大学所有人加起来年龄:" + ageNum); System.out.println("mapToInt=================="); } /** * flatMap与map的区别在于 flatMap是将一个流中的每个值都转成一个个流, * 然后再将这些流扁平化成为一个流 。举例说明, * 假设我们有一个字符串数组String[] strs = {"hello", "world"};, * 我们希望输出构成这一数组的所有非重复字符,那么我们用map和flatMap 实现如下: */ public static void flatMap() { String[] strings = {"Hello", "World"}; List l11 = Arrays.stream(strings).map(str -> str.split("")).map(str2 -> Arrays.stream(str2)).distinct().collect(Collectors.toList()); List l2 = Arrays.asList(strings).stream().map(s -> s.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList()); System.out.println(l11.toString()); System.out.println(l2.toString()); System.out.println("flatMap=================="); /** * 由上我们可以看到使用map并不能实现我们现在想要的结果, * 而flatMap是可以的。这是因为在执行map操作以后, * 我们得到是一个包含多个字符串(构成一个字符串的字符数组)的流, * 此时执行distinct操作是基于在这些字符串数组之间的对比,所以达不到我们希望的目的; * flatMap将由map映射得到的Stream<String[]>,转换成由各个字符串数组映射成的流Stream<String>, * 再将这些小的流扁平化成为一个由所有字符串构成的大流Steam<String>, * 从而能够达到我们的目的。 */ } /** * 3.1 allMatch * 用于检测是否全部都满足指定的参数行为,如果全部满足则返回true, * 例如我们判断是否所有的user年龄都大于9岁,实现如下: * anyMatch则是检测是否存在一个或多个满足指定的参数行为,如果满足则返回true * noneMatch用于检测是否不存在满足指定行为的元素,如果不存在则返回true */ public static void allMatch(List<User> list) { Boolean ageFlag = list.stream(). allMatch(user -> user.getAge() > 9); System.out.println("是否所有的user年龄都大于9岁:" + ageFlag); System.out.println("allMatch=================="); } /** * 3.4 findFirst * findFirst用于返回满足条件的第一个元素,比如返回年龄大于12岁的user中的第一个,实现如下: * 相似如 * findAny相对于findFirst的区别在于,findAny不一定返回第一个,而是返回任意一个, * 比如返回年龄大于12岁的user中的任意一个 */ public static void findFirst(List<User> list) { Optional<User> users = Optional.ofNullable(list) .orElse(new ArrayList<>()) .stream() .filter(user -> "清华大学".equals(user.getSchool())). findFirst(); if (users.isPresent()) { System.out.println("清华大学第一人:" + users.get().getName()); } System.out.println("findFirst=================="); } /** * 现在我的目标不是返回一个新的集合,而是希望对经过参数化操作后的集合进行进一步的运算,那么我们可用对集合实施归约操作。java8的流式处理提供了reduce方法来达到这一目的。 * <p> * 比如我现在要查出学校是清华大学的所有user的年龄之和: */ public static void reduce(List<User> list) { //前面用到的方法 Integer ages = list.stream().filter(student -> "清华大学".equals(student.getSchool())).mapToInt(User::getAge).sum(); System.out.println(ages); System.out.println("归约 - - 》 start "); Integer ages2 = list.stream().filter(student -> "清华大学".equals(student.getSchool())).map(User::getAge).reduce(0, (a, c) -> a + c); Integer ages3 = list.stream().filter(student -> "清华大学".equals(student.getSchool())).map(User::getAge).reduce(0, Integer::sum); Integer ages4 = list.stream().filter(student -> "清华大学".equals(student.getSchool())).map(User::getAge).reduce(Integer::sum).get(); System.out.println(ages2); System.out.println(ages3); System.out.println(ages4); System.out.println("归约 - - 》 end "); } /** * 前面利用collect(Collectors.toList())是一个简单的收集操作, * 是对处理结果的封装,对应的还有toSet、toMap,以满足我们对于结果组织的需求。 * 这些方法均来自于java.util.stream.Collectors,我们可以称之为收集器。 * <p> * 收集器也提供了相应的归约操作,但是与reduce在内部实现上是有区别的 * ,收集器更加适用于可变容器上的归约操作, * 这些收集器广义上均基于Collectors.reduc */ public static void counting(List<User> list) { long sum = list.stream() .filter(user -> user.getSchool().equals("清华大学")). collect(Collectors.counting()); System.out.println("清华大学有" + sum + "人"); } /** * 5.2 maxBy、minBy * <p> * 计算最大值和最小值 * 如我现在计算user的年龄最大值和最小值: */ public static void maxBy(List<User> list) { Integer num = list.stream().collect(Collectors. maxBy((age1, age2) -> age1.getAge() - age2.getAge())).get().getAge(); System.out.println("年纪最大的是:" + num + "岁"); System.out.println("=================maxBy"); } /** * 取总和 * summingInt、summingLong、summingDouble * 取平均 * averageInt、averageLong、averageDouble * 一次性查询元素个数、总和、最大值、最小值和平均值 * summarizingInt、summarizingLong、summarizingDouble */ public static void summingInt(List<User> list) { int sumAge = list.stream().collect(Collectors.summingInt(User::getAge)); System.out.println(sumAge); int sumAge2 = list.stream().mapToInt(User::getAge).sum(); System.out.println(sumAge2); Long startTime = System.currentTimeMillis(); IntSummaryStatistics intSummaryStatistics = list.stream().collect(Collectors.summarizingInt(User::getAge)); System.out.println("耗时" + (System.currentTimeMillis() - startTime)); System.out.println(intSummaryStatistics); System.out.println("============summingInt"); } /** * 5.6 joining * 字符串拼接 * 如输出所有user的名字,用“,”隔开 */ public static void joining(List<User> list) { String names = list.stream().map(User::getName).collect(Collectors.joining(",")); System.out.println(names); System.out.println("============joining"); } /** * groupingBy 根据某个属性分组 */ /** * 替换集合中某个字段为固定的值时,可以这样 */ public void testForeach(){ List<Son> sonList = new ArrayList<>(); sonList.add(new Son("111" , 1)); sonList.add(new Son("222" , 2)); System.out.println(sonList); System.out.println(sonList.get(0).getName()); sonList.stream().forEach(son1 -> son1.setName("testStream")); System.out.println(sonList.toString()); System.out.println(sonList.get(0).getName()); } /** * 使用java8的流进行转换两个对象属性不同的集合 * */ public void test(){ /** List<Student> students =new ArrayList<>(); students.add(new Student("1","aaa","男",new Date())); students.add(new Student("2","bbb","女",new Date())); List<User> copyUsers = students.stream().map(s -> { User user = new User(); user.setUid(s.getId()); user.setUname(s.getName()); return user; } ).collect(Collectors.toList()); System.out.println(copyUsers); * */ } }
stream流在项目中常见操作
最新推荐文章于 2023-12-25 17:32:23 发布