- 1、体验Stream流
- 2、Stream流的生成方式
- 3、Stream流常见中间操作方法
- 4、Stream流的常见终结操作方法
- 4、Stream综合案例
- 5、Stream流的收集操作
1、体验Stream流
需求:
- 创建一个集合,存储多个字符串元素。
- 把集合中所有以“张”开头的元素存储到一个新的集合。
- 把“张开头的集合中的长度为3的元素存储到一个新的集合
- 遍历上一步得到的集合
package com.test15;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList list=new ArrayList();
list.add("张三丰");
list.add("张无忌");
list.add("张敏");
list.add("宋远桥");
ArrayList zhangList=new ArrayList();
for(String str:list){
if(str.startsWith("张")){
zhangList.add(str);
}
}
ArrayList threeList=new ArrayList();
for(String str:zhangList){
if(str.length()==3){
threeList.add(str);
}
}
for(String str:threeList){
System.out.println(str);
}
System.out.println("*******************");
//使用Stream流的方式完成过滤操作
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
//生成流、过滤张、过滤长度为3、逐一打印
//Stream流把真正的函数式编程风格引入到Java中
}
}
2、Stream流的生成方式
Stream流的使用
- 生成流
通过数据源(集合,数组等)生成流
list.stream() - 中间操作
一个流后面可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用。
filter() - 终结操作
一个流只能有一个终结操作,当这个操作执行后,流就被使用完了,无法再被操作。所以这必定是流的最后一个操作。
forEach()
Stream流的常见生成方式:
- Collection体系的集合可以使用默认方法stream()生成流
default Stream stream() - Map体系的集合间接的生成流。
- 数组可以通过Stream接口的静态方法of(T… values)生成流。
package com.test16;
import java.util.*;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
//Collection体系的集合可以使用默认方法stream()生成流
List list=new ArrayList();
Stream listStream=list.stream();
Set set=new HashSet();
Stream setStream=set.stream();
//Map体系的集合间接的生成流
Map map=new HashMap();
Stream keyStream=map.keySet().stream();
Stream valueStream=map.values().stream();
Stream> entryStream=map.entrySet().stream();
//数组可以通过Stream接口的静态方法of(T... values)生成流
String[] strArray={"hello","world","java"};
Stream strArrayStream=Stream.of(strArray);
Stream strArrayStream2=Stream.of("hello","world","java");
Stream intStream=Stream.of(1,2,3);
}
}
3、Stream流常见中间操作方法
- Stream
filter(Predicate predicate):用于对流中的数据进行过滤 - Predicate接口中的方法 :
boolean test(T t):对指定的参数进行判断,返回一个布尔值。
- Predicate接口中的方法 :
- Stream
limit(long maxSize):返回此流中的元素组成的流,截取前指定参数个数的数据。 - Stream
skip(long n):跳过指定参数个数的数据,返回由该流的剩余元素组成的流。 - static
Stream concat(Stream extends T> a, Stream extends T> b):合并a和b两个流 - Stream
distinct():返回由该流的不同元素(根据Object.equals(Object))组成的流。 - Stream
sorted():返回由此流的元素组成的流,根据自然顺序排序。 - Stream
sorted(Comparator super T> comparator):返回由该流的元素组成的流,根据提供的Comparator进行排序。 Stream map(Function super T,? extends R> mapper):返回由给定函数应用于此流的元素的结果组成的流。 - IntStream mapToInt(ToIntFunction super T> mapper):返回一个IntStream其中包含将给定函数应用于此流的元素的结果。
- IntStream:表示原始int流
- ToIntFunction接口中的方法:
int applyAsInt(T value)
案例一:
package com.test;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
ArrayList list=new ArrayList();
list.add("张三丰");
list.add("张无忌");
list.add("张敏");
list.add("唐青枫");
list.add("曲无忆");
test1(list);
System.out.println("*****************");
test2(list);
System.out.println("*****************");
test3(list);
System.out.println("*****************");
test4(list);
System.out.println("*****************");
test5(list);
System.out.println("*****************");
test6(list);
System.out.println("*****************");
test7(list);
}
//输出list集合中以张开头的字符串
private static void test1(List list){
// list.stream().filter((String s)->s.startsWith("张")).forEach(System.out::println);
list.stream().filter(s->s.startsWith("张")).forEach(System.out::println);
}
//输出list集合中字符长度为3的字符串
private static void test2(List list){
list.stream().filter(s->s.length()==3).forEach(System.out::println);
}
//输出list集合中以张开头且字符长度为3的字符串
private static void test3(List list){
list.stream().filter(s->s.startsWith("张")).filter(s->3==s.length()).forEach(System.out::println);
}
//输出前3个元素
private static void test4(List list){
list.stream().limit(3).forEach(System.out::println);
}
//跳过前3个元素,输出剩余的元素
private static void test5(List list){
list.stream().skip(3).forEach(System.out::println);
}
//跳过2个元素,把剩余的元素的前2个元素输出
private static void test6(List list){
list.stream().skip(2).limit(2).forEach(System.out::println);
}
//
private static void test7(List list){
Stream a=list.stream().limit(4);//取前4个数据组成流
Stream b=list.stream().skip(2);//跳过前2个数据组成流
//合并a、b
Stream.concat(a,b).forEach(System.out::println);//此时a、b流已关闭
System.out.println("-------------");
//合并a、b,且不重复
a=list.stream().limit(4);//取前4个数据组成流
b=list.stream().skip(2);//跳过前2个数据组成流
Stream.concat(a,b).distinct().forEach(System.out::println);
}
}
案例二:
package com.test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
ArrayList list=new ArrayList();
list.add("dddd");
list.add("ddda");
list.add("aaaa");
list.add("ccc");
list.add("bbbbb");
test1(list);
}
private static void test1(List list){
//按自然顺序排序
list.stream().sorted().forEach(System.out::println);
System.out.println("----------");
//根据提供的Comparator排序
//按字母长度排序
list.stream().sorted((s1,s2)->s1.length()-s2.length()).forEach(System.out::println);
System.out.println("----------");
//根据提供的Comparator排序
//按字母长度排序,字母长度相同,按字母顺序排
list.stream().sorted((s1,s2)->{
int num1=s1.length()-s2.length();
int num=0==num1?s1.compareTo(s2):num1;
return num;
}).forEach(System.out::println);
}
}
案例三:
package com.test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
ArrayList list=new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
test1(list);
}
private static void test1(List list){
//将集合中的字符串转换成整数,输出
list.stream().map(s->Integer.parseInt(s)).forEach(System.out::println);
System.out.println("************");
list.stream().map(Integer::parseInt).forEach(System.out::println);
System.out.println("************");
//将集合中的字符串转换成整数,再求和
//mapToInt返回IntStream流,可调用sum
int result=list.stream().mapToInt(Integer::parseInt).sum();
System.out.println(result);
}
}
4、Stream流的常见终结操作方法
Stream流的常见终结操作方法
- void forEach(Consumer super T> action):对此流的每个元素执行操作。
- Consumer接口中的方法:
- void accept(T t):对给定的参数执行操作。
- long count():返回此流中的元素数。
package com.test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
ArrayList list=new ArrayList();
list.add("张三丰");
list.add("张无忌");
list.add("张敏");
list.add("唐青枫");
list.add("曲无忆");
test1(list);
}
private static void test1(List list){
//输出集合中的所有元素经
list.stream().forEach(System.out::println);
//统计集合中有几个以张开头的元素
long num=list.stream().filter(s->s.startsWith("张")).count();
System.out.println(num);
}
}
4、Stream综合案例
package com.test1;
public class Actor {
private String name;
public Actor(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.test1;
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
ArrayList manList=new ArrayList();
manList.add("张三丰");
manList.add("张无忌");
manList.add("唐青枫");
manList.add("离玉堂");
ArrayList womanList=new ArrayList();
womanList.add("曲无忆");
womanList.add("慕双");
womanList.add("慕晴");
womanList.add("唐蓝");
womanList.add("明月心");
//男演员只要名字为3个字的前三人
Stream a=manList.stream().filter(s->(3==s.length())).limit(3);
//女演员只要姓慕的,并且不要第一个
Stream b=womanList.stream().filter(s->s.startsWith("慕")).skip(1);
Stream.concat(a,b).map(Actor::new).forEach(actor->System.out.println(actor.getName()));
}
}
5、Stream流的收集操作
数据使用Stream流的方式操作完毕后,如流中的数据收集到集合中,如何处理?
Stream流的收集方法:
- R collect(Collector collector)
- 但是这个收集方法的参数是一个Collector接口
工具类Collectors提供了具体的收集方式:
- public static
Collector toList():把元素收集到List集合中。 - public static
Collector toSet():把元素收集到Set集合中。 - public static Collector toMap(Function keyMapper,Function valueMapper):把元素收集到Map集合中。
package com.test2;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
test1();
test2();
test3();
}
private static void test1(){
List list=new ArrayList();
list.add("张三丰");
list.add("张无忌");
list.add("慕晴");
list.add("唐青枫");
list.add("曲无忆");
//得到名字为三个字的流
Stream listStream=list.stream().filter(s->(3==s.length()));
//把Stream流操作完毕的数据收集到List集合中,并遍历
List names=listStream.collect(Collectors.toList());
for(String name:names){
System.out.println(name);
}
}
private static void test2(){
Set set=new HashSet();
set.add(10);
set.add(20);
set.add(21);
set.add(22);
set.add(23);
//得到年龄>20的流
Stream setStream=set.stream().filter(age->age>20);
//把Stream流操作完毕的数据收集到Set集合中,并遍历
Set ages=setStream.collect(Collectors.toSet());
//遍历
for(int age:ages){
System.out.println(age);
}
}
private static void test3(){
String[] strArray={"唐青枫,20","曲无忆,21","慕情,19","离玉堂,22"};
//得到字符串中年龄大于19的Stream流
Stream arrayStream=Stream.of(strArray).filter(s->Integer.parseInt(s.split(",")[1])>19);
//把Stream流操作完毕的数据收集到map集合中,并遍历
Map map=arrayStream.collect(Collectors.toMap(s->s.split(",")[0], s->Integer.parseInt(s.split(",")[1])));
Set keySet=map.keySet();
for(String key:keySet){
int value=map.get(key);
System.out.println(key+","+value);
}
}
}



