stream流使用的多吗?

2020-08-05 11:08发布

1条回答
我的网名不再改
1楼 · 2020-08-05 16:52.采纳回答

1.简介

Stream流 最全的用法
Stream 能用来干什么?用来处理集合,通过 使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询,Stream API 提供了一种高效且易于使用的处理数据的方式

为什么用Java 8 Stream ?因为 操作简单
为什么操作简单?因为 Lambda 表达式,它极大的提高了编程效率和程序可读性
怎么操作流? 首先你的有个数据源(数组、集合),操作会产生新的流对象,原来的流对象不会改变
流用法有结束操作,这种代码不是你写了一个方法就执行一个方法,而是最后触发结束操作的时候才统一执行的,collect、foreach 方法就是一种结束方法,详情看代码及结果参考 2.映射map、flatMap用法 部分

2.具体用法

2.1 创建流

// 集合创建流List list = new ArrayList<>();// 获取一个顺序流Stream listStream = list.stream();// 获取一个并行流Stream parallelListStream = list.parallelStream();// 数组创建流Integer[] nums = new Integer[] { 1, 2, 3, 4, 5 };Stream arrStream = Arrays.stream(nums);arrStream.forEach(System.out::println);// 1 2 3 4 5// 静态方法of创建流Stream ofStream = Stream.of(1, 2, 3, 4, 5);ofStream.forEach(System.out::println);// 1 2 3 4 5// 静态方法iterate 创建流Stream iterateStream = Stream.iterate(1, (x) -> x + 10).limit(4);iterateStream.forEach(System.out::println); // 1 11 21 31// 静态方法generate 创建流Stream generateStream = Stream.generate(Math::random).limit(2);generateStream.forEach(System.out::println);

2.2 操作流

1.过滤

filter:过滤流中的某些元素(可以做一些基本的判空、替换、判断逻辑操作)
limit(n):获取n个元素,结果获取几个元素
skip(n):跳过n元素,配合limit(n)可实现分页
distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素

//filter 判空Stream notNullStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);Stream notNullStream = notNullStreamObj.filter(i -> (null != i));notNullStream.forEach(System.out::println);//1 2 4 5 6 7 2//filter 逻辑判断Stream logicStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);Stream logicStream = logicStreamObj.filter(i -> (i != null && i > 5));logicStream.forEach(System.out::println); // 6 7//filter 替换Stream strStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");Stream strStream = strStreamObj.filter(str -> (null != str && str.contains("a")));strStream.forEach(System.out::println); // aa ab ac//skip 跳过Stream skipStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");Stream skipStream = skipStreamObj.skip(2);skipStream.forEach(System.out::println); // null ac bd ee//distinct 去重Stream disStreamObj = Stream.of("aa", "ab", null, "ac", "aa", "ab", null, "ee");Stream disStream = disStreamObj.distinct();disStream.forEach(System.out::println); // aa ab null ac ee

2.映射

map:接收一个函数作为参数,该函数会被应用到每个元素上,映射成一个新的元素。
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
peek:这个操作很骚,类似map只不过map 是Func函数,提供返回值,而peer是取出元素,Consumer表达式设值,我个人觉得没啥区别呢,官方文档提示:该方法主要用于调试,做一些消耗这个对象但不修改它的东西,没啥事不要用
很想问一下 这俩map、flatMap 区别 ,细品,你细品,你细细品
map是将每个元素 映射成一个新元素,除非你过滤了,否则不会改变元素个数
flatMap是将原流中的每个值都变成另一个流,然后把流合并串起来,必须有返回值,拼装成新的流

//map 把包含a的元素,替换成| 注意,注意, 元素还是一个整体,对每个元素Stream mapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream mapStream = mapStreamObj.map(str -> str.replaceAll(",", "|"));mapStream.forEach(System.out::println); // a|b|c a|e|f h|i|j//flatMap 可以把元素 切分后,再按照新元素组成新的字符串Stream flatMapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream flatMapStream = flatMapStreamObj.flatMap(str -> {String[] arr = str.split(",");Stream result = Arrays.stream(arr);return result;});flatMapStream.forEach(System.out::println); //a b c d e f g h iSystem.out.println("1===========");Stream peekStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream peekStream = peekStreamObj.peek(e -> System.out.println("Filtered value: " + e)).map(String::toUpperCase).peek(e -> System.out.println("Mapped value: " + e));System.out.println("2=========== peek代码结束,但是日志没打印");Set stringSet = peekStream.collect(Collectors.toSet());System.out.println("3=========== collect结束操作,代码日志打印");stringSet.forEach(System.out::println);

map执行结果

//看下执行结果,说明 collect才是结束操作,代码结束,但是并不是真正结束1===========2=========== peek代码结束,但是日志没打印Filtered value: a,b,cMapped value: A,B,CFiltered value: a,e,fMapped value: A,E,FFiltered value: g,h,iMapped value: G,H,I3=========== collect结束操作,代码日志打印A,B,CA,E,FG,H,I

3.排序

sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):定制排序,自定义Comparator排序器
先构建一个User类

public static class User {private String name;private Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}}

然后 看下sort用法

//按字母排序Stream sortStreamObj = Stream.of("a,e,f", "a,d,c", "a,b,i");Stream sortStream = sortStreamObj.sorted();sortStream.forEach(System.out::println); //abi adc aefUser u1 = new User("bb", 1);User u2 = new User("aa", 2);User u3 = new User("cc", 3);User u4 = new User("aa", 4);Set userSet = Sets.newHashSet(u1, u2, u3, u4);Stream userStream = userSet.stream().sorted((obj1, obj2) -> {if (obj1.getName().equals(obj2.getName())) {//name相等 按agereturn obj1.getAge() - obj2.getAge();}return obj1.getName().compareTo(obj2.getName());});userStream.forEach(System.out::println);// u2 u4 u1 u3

sort 执行结果

a,b,ia,d,ca,e,fUser{name='aa', age=2}User{name='aa', age=4}User{name='bb', age=1}User{name='cc', age=3}

4.流匹配

allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
findFirst:返回流中第一个元素
findAny:返回流中的任意元素
count:返回流中元素的总个数
max:返回流中元素最大值
min:返回流中元素最小值

List numLists = Arrays.asList(3, 4, 5, 6, 10);// 全部匹配 - trueboolean allMatch1 = numLists.stream().allMatch(e -> e > 2); //trueSystem.out.println("allMatch1:" + allMatch1);// 全部匹配 - trueboolean allMatch2 = numLists.stream().allMatch(e -> e > 5); //falseSystem.out.println("allMatch2:" + allMatch2);// 全部都不符合 - trueboolean noneMatch = numLists.stream().noneMatch(e -> e > 20); //trueSystem.out.println("noneMatch:" + noneMatch);// 任一元素符合 - trueboolean anyMatch = numLists.stream().anyMatch(e -> e > 4);  //trueSystem.out.println("anyMatch:" + anyMatch);//返回第一个Integer findFirst = numLists.stream().findFirst().get(); //3System.out.println("findFirst:" + findFirst);//返回任一个Integer findAny = numLists.stream().findAny().get();System.out.println("findAny:" + findAny);//返回 countlong count = numLists.stream().count(); //5System.out.println("count:" + count);//返回maxInteger max = numLists.stream().max(Integer::compareTo).get(); //10System.out.println("max:" + max);//返回minInteger min = numLists.stream().min(Integer::compareTo).get();//3System.out.println("min:" + min);

匹配执行结果

allMatch1:trueallMatch2:falsenoneMatch:trueanyMatch:truefindFirst:3findAny:3count:5max:10min:3

5.组合操作

Reduce 就是组合操作
Reduce(BinaryOperator accumulator) 没有起始值,按照运算规则进行运算操作
解释:第一次执行时,accumulator函数的第一个参数为流中的第一个元素,第二个参数为流中元素的第二个元素,按照函数进行操作;
第二次执行时,第一个参数为第一次函数执行操作的结果,第二个参数为流中的第三个元素;往下依次类推,返回Optinal 通过get()方法获取结果
Reduce(T identity, BinaryOperator accumulator)含有初始值,第二个是第一个的变形,跟第一个方法对比,不同的是此次这个会接受一个identity参数,用来指定Stream循环的初始值。如果Stream为空,就直接返回该值,特殊:该方法不会返回 Optional

Optional sumResult = Stream.of(1, 2, 3, 4).reduce((sum, item) -> {System.out.println("sum : " + sum);sum += item;System.out.println("item: " + item);System.out.println("sum+ : " + sum);System.out.println("-----——---");return sum;});System.out.println("========sumResult: " + sumResult.get());Integer sumDefineResult = Stream.of(1, 2, 3, 4).reduce(100, (sum, item) -> {System.out.println("sum : " + sum);sum += item;System.out.println("item: " + item);System.out.println("sum+ : " + sum);System.out.println("---——-----");return sum;});System.out.println("========sumDefineResult: " + sumDefineResult);

reduce 执行结果

//下面是执行结果//查看执行结果sum : 1item: 2sum+ : 3-----——---sum : 3item: 3sum+ : 6-----——---sum : 6item: 4sum+ : 10-----——---========sumResult: 10sum : 100item: 1sum+ : 101---——-----sum : 101item: 2sum+ : 103---——-----sum : 103item: 3sum+ : 106---——-----sum : 106item: 4sum+ : 110---——-----========sumDefineResult: 110

6. 收集转换操作

这是个最最最最最基本的操作,10个流操作 9个都会使用到当前操作

collect(Collectors.toList()) 转换List
collect(Collectors.toSet()) 转换Set
Collectors.toMap(key, value) 转换Map ,如果key重复,!!!报错
Collectors.joining() join进行拼接
Collectors.groupingBy(key) 以Key为map的 key分组
Collectors.partitioningBy(规则) 以规则分区 比如 >5 ,map key为true,false

User s1 = new User("aa", 1);User s2 = new User("bb", 2);User s3 = new User("cc", 3);User s4 = new User("dd", 2);List list = Arrays.asList(s1, s2, s3, s4);//转换listList ageList = list.stream().map(User::getAge).collect(Collectors.toList()); // [1, 2, 3]System.out.println(ageList.toString());//转成setSet ageSet = list.stream().map(User::getAge).collect(Collectors.toSet()); // [1, 2, 3]System.out.println(ageSet);//转成map,注:key不能相同,否则报错Map userMap = list.stream().collect(Collectors.toMap(User::getName, User::getAge)); // {cc=10, bb=20, aa=10}System.out.println(userMap);//字符串分隔符连接String joinName = list.stream().map(User::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)System.out.println(joinName);//分组Map> ageMap = list.stream().collect(Collectors.groupingBy(User::getAge));System.out.println(ageMap);//多重分组,先根据类型分再根据年龄分Map>> typeAgeMap = list.stream().collect(Collectors.groupingBy(User::getAge, Collectors.groupingBy(User::getAge)));System.out.println(typeAgeMap);//分区//分成两部分,true 一部分age大于2岁, false 一部分age小于等于2岁Map> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 2));System.out.println(partMap);

collect 执行结果

[1, 2, 3, 2][1, 2, 3]{dd=2, cc=3, bb=2, aa=1}(aa,bb,cc,dd){1=[User{name='aa', age=1}], 2=[User{name='bb', age=2}, User{name='dd', age=2}], 3=[User{name='cc', age=3}]}{1={1=[User{name='aa', age=1}]}, 2={2=[User{name='bb', age=2}, User{name='dd', age=2}]}, 3={3=[User{name='cc', age=3}]}}{false=[User{name='aa', age=1}, User{name='bb', age=2}, User{name='dd', age=2}], true=[User{name='cc', age=3}]}

最后

大家看完有什么不懂的可以在下方留言讨论,也可以关注我私信问我,我看到后都会回答的。也欢迎大家关注我的公众号:前程有光,金三银四跳槽面试季,整理了1000多道将近500多页pdf文档的Java面试题资料,文章都会在里面更新,整理的资料也会放在里面。谢谢你的观看,觉得文章对你有帮助的话记得关注我点个赞支持一下!


相关问题推荐

  • 回答 156

    对于每一位才开始接触JAVA的新手来说,先不要管算法和数据结构,大多数简单的程序不需要用到算法和数据结构,所以当你真正需要时再去学习。编程一段时间以后,你就会知道在哪些地方用到他们。这时知道算法的名字并了解它们的功能,然后动手去实践。当我们在去...

  • 回答 93

    2个都很好就业,更关键的是要学得到东西

  • 回答 12
    已采纳

    获取Map集合中所有的key可以通过map集合的keySet()方法获取例如:    Map map = new HashMap();    map.put(xx,xx); //存放数据    //.... 省略    Set set = map.keySet();    //可以通过迭代器进行测试    Iterator iter = set.iter...

  • 回答 56
    已采纳

    不同年龄,不同掌握程度,学历,找工作城市,面试能力这是一个多方面影响的结果,如果是平均值的话,全国平均薪资14k左右

  • 回答 38

    具体学多久,根据自己的学习力,自律性、解决问题能力来决定若系统性学习,跟着讲师的节奏走,大概半年左右,有专业的讲师把课程进行规划,尽心系统学习,有问题,讲师会帮忙解决,学习的效率很高,避免了自学中出现各种问题解决不了,而耽误很多时间,可能会...

  • 回答 23
    已采纳

    (1)idea启动时会有两个快捷方式,安装完后默认生成在桌面的是32位的idea的快捷方式,如果我们使用这个快捷方式运行大项目,一般都会很卡。解决方法是找到idea的安装目录,然后进入bin文件夹,找到名称为idea64的应用程序,右键他生成桌面快捷方式。以后每次...

  • BIO与NIO、AIO的区别2020-05-19 15:59
    回答 4
    已采纳

    IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。一、BIO     在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要...

  • Java方法的命名规则2021-04-06 19:07
    回答 31

    ava是一种区分字母的大小写的语言,所以我们在定义变量名的时候应该注意区分大小写的使用和一些规范,接下来我们简单的来讲讲Java语言中包、类、变量等的命名规范。(一)Package(包)的命名Package的名字应该都是由一个小写单词组成,例如com、xuetang9、compan...

  • 回答 2

    public class Point {    private int x;    private int y;    public int getX() {        return x;    }    public void setX(int x) {        this.x = x;    }    public int getY() {        return y;    } ...

  • 回答 6

    经典版单例模式public class Singleton {        private static Singleton uniqueInstance;//利用一个静态常量来记录singleton类的唯一实例。     private Singleton() {     }     public static  Singleton getInstance()...

  • 回答 3

    哈希表的长度一般是定长的,在存储数据之前我们应该知道我们存储的数据规模是多大,应该尽可能地避免频繁地让哈希表扩容。但是如果设计的太大,那么就会浪费空间,因为我们跟不用不到那么大的空间来存储我们当前的数据规模;如果设计的太小,那么就会很容易发...

  • 回答 14

    1. DOM(Document Object Model)        DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才...

  • 回答 19

    1)作用不同: throw用于程序员自行产生并抛出异常; throws用于声明在该方法内抛出了异常2) 使用的位置不同: throw位于方法体内部,可以作为单独语句使用; throws必须跟在方法参数列表的后面,不能单独使用。3)内容不同: throw抛出一个异常对象,且只能是...

  • 回答 11

    基本执行过程如下:1)程序首先执行可能发生异常的try语句块。2)如果try语句没有出现异常则执行完后跳至finally语句块执行;3)如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。4)catch语句块可以有多个,分别捕获不同类型...

  • 回答 20

    100-199 用于指定客户端应相应的某些动作。 200-299 用于表示请求成功。 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 400-499 用于指出客户端的错误。 400 语义有误,当前请求无法被服务器理解。 401 当前请求需要用户验证...

  • 回答 16

    异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译...

没有解决我的问题,去提问