p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解
目录
- Stream流的使用步骤
- 获取Stream流
- Stream流的中间方法
- Stream中的终结方法
- 收集方法collect
Stream流可以比作工厂的流水线
Stream流的概念
Stream流的使用步骤
- 先得到一条Stream流(可以比作一条流水线),并把数据放上去
- 利用Stream流中的API进行各种操作,如过滤、转换、统计、打印等。其中前两种称为中间方法(方法调用完毕之后,还可以调用其他方法),后两者称为终结方法(最后一步,方法调用完毕之后不能再调用其他方法)
所以Stream流的使用步骤为
- 先得到一条Stream流(可以比作一条流水线),并把数据放上去
.- 使用中间方法对流水线上的数据进行操作
.- 使用终结方法对流水线上的数据进行操作
获取Stream流
双列集合keySet()或者entrySet()只能先转成Set单列集合在使用Stream流
举例说明
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;public class Demo1 {public static void main(String[] args) {//单列集合获取Stream流ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"a","b","c","a");//取一条Stream流,并把list集合里的数据放在Stream流上Stream<String> stream = list.stream();//使用终结方法打印Stream流上的所有数据stream.forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});System.out.println();//其上可以简化成如下代码list.stream().forEach(s -> System.out.println(s));//================================================System.out.println("================================================");//双列集合获取Stream流HashMap<String,Integer> hm = new HashMap<>();hm.put("张三",18);hm.put("李四",20);hm.put("王五",19);//第一种获取Stream流hm.keySet().stream().forEach(s -> System.out.println(s));//第二种获取Stream流hm.entrySet().stream().forEach(stringIntegerEntry -> System.out.println(stringIntegerEntry));//================================================System.out.println("================================================");//数组获取Stream流int []arr = {1,2,3,4,5,6,7,8,};String []arr1 = {"张三","李四"};//获取Stream流Arrays.stream(arr).forEach(s-> System.out.println(s));Arrays.stream(arr1).forEach(s-> System.out.println(s));//================================================System.out.println("================================================");//一堆零散的数据获取Stream流// !!前提:数据类型必须相同!!Stream.of(1,2,3,4,5).forEach(s-> System.out.println(s));Stream.of("张三","李四").forEach(s-> System.out.println(s));//Stream接口中静态方法of的注意事项//方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组//但是数组必须是引用数据类型的,如果传递的是引用数据类型,是会把整个数组当作一个元素,放到Stream流中//若此时打印该数组,则会输出数组的地址值}
}
Stream流的中间方法
举例说明
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;public class Demo2 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"张三","李四","张旺财","张二","李四五","王五");ArrayList<String> list2 = new ArrayList<>();Collections.addAll(list2,"李四","张军","张军","王五");ArrayList<String> list3 = new ArrayList<>();Collections.addAll(list3,"李四-18","张军-20","张军-19","王五-22");//filter 过滤/* list.stream().filter(new Predicate<String>() {@Overridepublic boolean test(String s) {//如果返回值为true,表示当前数据留下。反之舍去return s.startsWith("张");}}).forEach(s -> System.out.println(s));*///filter 过滤list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(s -> System.out.println(s));System.out.println("==============================");//limit 获取前几个元素list.stream().limit(3).forEach(s -> System.out.println(s));System.out.println("==============================");//skip 跳过前几个元素list.stream().skip(3).forEach(s -> System.out.println(s));System.out.println("==============================");//distinct 元素去重(依赖hashcode和equals方法)list2.stream().distinct().forEach(s -> System.out.println(s));System.out.println("==============================");//concat 合并a和b两个流为一个流Stream.concat(list.stream(),list2.stream()).forEach(s -> System.out.println(s));System.out.println("==============================");//map 转换流中的数据类型//String -> int//第一个数据类型:流中原本的数据类型//第二个数据类型:要转换成的数据类型list3.stream().map(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {//返回值:表示转换之后的数据String[] arr = s.split("-");String ageString = arr[1];int age = Integer.parseInt(ageString);return age;}}).forEach(s-> System.out.println(s));System.out.println("==============================");list3.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));}
}
Stream中的终结方法
前三个方法举例说明如下
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.IntFunction;public class Demo3 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"张三","李四","张旺财","张二","李四五","王五");//foreach 遍历list.stream().forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});System.out.println("==============================");//foreach 遍历list.stream().forEach(s-> System.out.println(s));System.out.println("==============================");//count 统计long count = list.stream().count();System.out.println(count);System.out.println("==============================");//toArray 收集数据并放到数组当中Object[] array = list.stream().toArray();System.out.println(Arrays.toString(array));System.out.println("==============================");//toArray 收集数据并放到数组当中//<? extends Object[]>:具体类型的数组//apply的形参:流中数组的个数,要跟数组的长度保持一致//apply的返回值:具体类型的数组//方法体:创建数组String[] array1 = list.stream().toArray(new IntFunction<String[]>() {@Overridepublic String[] apply(int value) {return new String[value];}});System.out.println(Arrays.toString(array1));//toArray方法的参数:负责创建一个指定类型的数组//toArray方法的底层:会依次得到流里面的每一个数据,并把数据放到数组当中//toArray方法的返回值:是一个装着流里面所有数据的数组System.out.println("==============================");//toArray 收集数据并放到数组当中String[] array2 = list.stream().toArray(value -> new String[value]);System.out.println(Arrays.toString(array2));System.out.println("==============================");}
}
收集方法collect
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;public class DEMO4 {public static void main(String[] args) {//collect(Collector collector) 收集流中的数据,放到集合中(List、Set、Map)//注意点:如果我们要收集到Map集合中,键不能重复,否则会报错ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"李四-男-18","张军-男-20","张军-男-20","王五-女-22");ArrayList<String> list2 = new ArrayList<>();Collections.addAll(list2,"李四-男-18","张军-男-20","王五-女-22");//收集所有男性并放在list集合里List<String> newList = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());System.out.println(newList);System.out.println("==============================");//收集所有男性并放在Set集合里Set<String> newSet = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());System.out.println(newSet);System.out.println("==============================");//收集所有男性并放在Map集合里//键为姓名,值为年龄Map<String, Integer> newMap = list2.stream().filter(s -> "男".equals(s.split("-")[1]))//第一个数据类型:流里面的数据类型//第二个数据类型:键的数据类型.collect(Collectors.toMap(new Function<String, String>() {@Overridepublic String apply(String s) {return s.split("-")[0];}}, //第一个数据类型:流里面的数据类型//第二个数据类型:值的数据类型new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return Integer.parseInt(s.split("-")[2]);}}));System.out.println(newMap);System.out.println("==============================");/*总结:toMap:参数一表示键的生成规则参数二表示值的生成规则参数一:Function泛型一:表示流中每一个数据的类型泛型二:表示Map集合中键的数据类型方法apply形参:依次表示流里面的每一个数据方法体:生成键的代码返回值:已经生成的键参数二:Function泛型一:表示流中每一个数据的类型泛型二:表示Map集合中值的数据类型方法apply形参:依次表示流里面的每一个数据方法体:生成值的代码返回值:已经生成的值*///收集所有男性并放在Map集合里//键为姓名,值为年龄//简化Map<String, Integer> newMap2 = list2.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toMap(s -> s.split("-")[0],s ->Integer.parseInt(s.split("-")[2])));}
}