这篇文章主要介绍了Java8的Stream如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java8的Stream如何使用文章都会有所收获,下面我们一起来看看吧。

一:什么是 Stream?

Stream(流)是一个来自数据源的元素队列并支持聚合操作

Java中的Stream并不会存储元素,而是按需计算。 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。

聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。 和以前的Collection操作不同,Stream操作还有两个基础的特征如下:

Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格。 这样做可以对操作进行优化, 比如延迟执行和短路。

内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫>做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

二:Stream API 使用1:使用Stream步骤:

(1)先产生一个流(Stream)一个数据源,获取一个流。

(2)中间链式操作 一个中间的操作链,对数据源的数据进行处理。

(3)产生一个新流:一个终止操作,执行中间操作,产生结果。

注意:Stream操作是延迟执行,他们会等需要结果的时候才会执行。

总结:

中间操作常用方法有:筛选:filter 映射:map 排序:sorted提取与组合 收集:collect。

终止操作:遍历:foreach 匹配:find、match 规约:reduce 聚合:max、min、count。

2:创建Stream的方法的4种方式

【1】Collection接口中的方法:defaultStream<E>stream()获取串行流defaultStream<E>parallelStream()获取并行流案例:

//方式1:Collection接口的方法Collectioncollection=newArrayList();Streamstream=collection.stream();Streamstream1=collection.parallelStream();//方式2:通过Arrays中的Stream方法数组IntStreamstream2=Arrays.stream(newint[]{1,2,3,4,5});//方式3:Stream中的of方法Stream<String>stream3=Stream.of("111","222","333");//方法4:Stream中的方法创建无限流(结果是无线个)Stream<Integer>iterate=Stream.iterate(2,(x)->x+2);3:中间操作

1:筛选与切片

① Stream filter(Predicate<?super T> predicate)返回由与此给定谓词匹配的此流的元素组成的流。 --->接收Lambda,从流中排除某些元素。

//1:创建Stream;Stream<Student>stream=list.stream();//2:filter方法(找到年龄大于等于18岁的学生)Stream<Student>studentStream=stream.filter((student)->student.getAge()>=18);//3:终止操作;如果没有终止操作的话,上面的第二步中间操作不执行studentStream.forEach(System.out::println);/***注意:如果值执行1,2操作的话,不会有任何结果。*验证出Steam操作是延迟的,只有进行了终止操作,才会执行中间操作!这就是所谓的延迟加载*/

②Stream limit(Long maxSize) 返回由该流的元素组成的流,截断长度不能超过maxSize. 只有找到maxSize个满足条件的即可。 ---->截断流,使其元素不超过给定的数量。

publicvoidlimitTest02(){//Limit方法短路(效率增高),只要找到了2个满足条件的,后面的迭代操作就不在执行了!list.stream().filter(x->{System.out.println("正在过滤!!");returnx.getAge()>18;}).limit(2).forEach(System.out::println);}

③Stream skip(Long n) 在丢掉流的第一个n元素后,返回由该流的n元素组成的流,如果此流包含少于n元素,那么将返回一个空流。 ---->跳过元素,返回一个扔掉了前n个元素的流。 如果流中的元素不足n个,则返回一个空流,与limit(n)互补。

publicvoidskipTest03(){//skip方法跳过前2个满足条件的留下后面满足条件的结果!!list.stream().filter(x->{System.out.println("正在过滤后面满足条件的结果");returnx.getAge()>18;}).skip(2).forEach(System.out::println);}

④Stream distinct()

注意: 自定义的类在去重的过程中必须重新hashCode和equals方法,因为distinct实现的时候底层去找这两个方法。

publicvoiddistinctTest04(){//distinct去重操作!list.stream().distinct().forEach(System.out::println);}

⑤ map映射:

如果需要将流中的元素映射到另一个流中,可以使用map方法。方法签名: Stream map(Function<? super T, ? extends R> mapper); 该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。 Stream流中的map方法基本使用的代码如:

@TestpublicvoidtestMap(){Stream<String>original=Stream.of("11","22","33");Stream<Integer>result=original.map(Integer::parseInt);result.forEach(s->System.out.println(s+10));}//这段代码中,map方法的参数通过方法引用,将字符串类型转换成为了int类型(并自动装箱为Integer类对象)。

⑥ 排序 (两种方式)

(1)Stream sorted()返回此流元素组成的流,根据自然顺序排序。底层按照内部比较器进行排序,实现Comparable接口中的compareTo方法。

(2)Stream sorted(Comparator<?super T>comparator) 返回由此元素组成的流,根据挺的Comparator进行顺序排序。指定顺序。 指定排序策略:底层按照外部比较器进行排序 Comparator接口一定要重新Compare方法。

基本使用Stream流中的sorted方法基本使用的代码如:@TestpublicvoidtestSorted(){//sorted():根据元素的自然顺序排序//sorted(Comparator<?superT>comparator):根据比较器指定的规则排序Stream.of(33,22,11,55).sorted().sorted((o1,o2)->o2-o1).forEach(System.out::println);}这段代码中,sorted方法根据元素的自然顺序排序,也可以指定比较器排序。4:终止操作

①查找(find)和匹配(match)

如果需要找到某些数据,可以使用find相关方法。方法签名:

Optional findFirst();

Optional findAny();

Stream流中的find相关方法使用代码:

@TestpublicvoidtestFind(){Optional<Integer>first=Stream.of(5,3,6,1).findFirst();System.out.println("first="+first.get());Optional<Integer>any=Stream.of(5,3,6,1).findAny();System.out.println("any="+any.get());}

Stream流的match方法

如果需要判断数据是否匹配指定的条件,可以使用Match相关方法。方法签名:

boolean allMatch(Predicate<? super T> predicate);

boolean anyMatch(Predicate<? super T> predicate);

boolean noneMatch(Predicate<? super T> predicate);

基本使用 Stream流中的Match相关方法使用代码如:

@TestpublicvoidtestMatch(){booleanb=Stream.of(5,3,6,1)//.allMatch(e->e>0);//allMatch:元素是否全部满足条件//.anyMatch(e->e>5);//anyMatch:元素是否任意有一个满足条件.noneMatch(e->e<0);//noneMatch:元素是否全部不满足条件System.out.println("b="+b);}

②:遍历 foreach

//forEach用来遍历流中的数据@Testpublicvoidtest02(){//案例1、2下面两种写法等同list.stream().map((x)->x.getName()).forEach(System.out::println);list.stream().map(Student::getName).forEach(System.out::println);}

③Stream流的max、min

List<String>list13=Arrays.asList("zhangsan","lisi","wangwu","xuwujing");intmaxLines=list13.stream().mapToInt(String::length).max().getAsInt();intminLines=list13.stream().mapToInt(String::length).min().getAsInt();System.out.println("最长字符的长度:"+maxLines+",最短字符的长度:"+minLines);//最长字符的长度:8,最短字符的长度:4

④Stream流的count

//Stream流提供count方法来统计其中的元素个数:longcount();//该方法返回一个long值代表元素个数。基本使用:@TestpublicvoidtestCount(){List<String>strList=newArrayList<>();Collections.addAll(strList,"张无忌","周芷若","赵敏","小昭","杨不悔);System.out.println(strList.stream().count());}

⑤ 分组:groupingBy;

当我们使用Stream流处理数据后,可以根据某个属性将数据分组:

//案例:@TestpublicvoidtestGroup(){Stream<Student>studentStream=Stream.of(newStudent("赵丽颖",52,95),newStudent("杨颖",56,88),newStudent("迪丽热巴",56,55),newStudent("柳岩",52,33));//Map<Integer,List<Student>>map=studentStream.collect(Collectors.groupingBy(Student::getAge));//将分数大于60的分为一组,小于60分成另一组Map<String,List<Student>>map=studentStream.collect(Collectors.groupingBy((s)->{if(s.getSocre()>60){return"及格";}else{return"不及格";}}));map.forEach((k,v)->{System.out.println(k+"::"+v);});}

效果:不及格::[Student{name='迪丽热巴',age=56,socre=55},Student{name='柳岩',age=52,socre=33}]及格::[Student{name='赵丽颖',age=52,socre=95},Student{name='杨颖',age=56,socre=88}]

⑥拼接:joining

Collectors.joining会根据指定的连接符,将所有元素连接成一个字符串。//拼接@TestpublicvoidtestJoining(){Stream<Student>studentStream=Stream.of(newStudent("赵丽颖",52,95),newStudent("杨颖",56,88),newStudent("迪丽热巴",56,99),newStudent("柳岩",52,77));Stringcollect=studentStream.map(Student::getName).collect(Collectors.joining(">_<","^_^","^v^"));System.out.println(collect);}

效果:

^_^赵丽颖>_<杨颖>_<迪丽热巴>_<柳岩^v^

⑦聚合:toList,toSet,toMap;

Stream流提供collect方法,其参数需要一个java.util.stream.Collector<T,A, R>接口对象来指定收集到哪种集合中。

public static Collector<T, ?, List> toList():转换为List集合。

public static Collector<T, ?, Set> toSet():转换为Set集合。

public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper):转换为Map集合。

下面是这两个方法的基本使用代码:

//将流中数据收集到集合中@TestpublicvoidtestStreamToCollection(){Stream<String>stream=Stream.of("aa","bb","cc");//List<String>strList=stream.collect(Collectors.toList());//Set<String>strSet=stream.collect(Collectors.toSet());ArrayList<String>arrayList=stream.collect(Collectors.toCollection(ArrayList::new));HashSet<String>hashSet=stream.collect(Collectors.toCollection(HashSet::new));}

toMap

@TestpublicvoidtestCollectToMap(){//案例1List<Integer>list=Arrays.asList(1,2,3);Map<String,String>collect1=list.stream().map(i->i).collect(Collectors.toMap(key->"key"+key,value->"value:"+value));//实体list转化mapid作为主键,对象作为valueList<User>userList=newArrayList<User>();UserTaskuserTask=newUserTask();userTask.setId(1);userTask.setName("测试");userList.add(userTask);Map<Integer,UserTask>taskMap=userList.stream().collect(Collectors.toMap(UserTask::getId,entity->entity));System.out.println(collect1.toString());System.out.println(taskMap.toString());}

关于“Java8的Stream如何使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Java8的Stream如何使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。