Stream流
Stream流
Stream流的获取方法
单列集合
可以使用Collection接口中的默认方法stream?()生成流
default Stream<E> stream()
双列集合
间接的生成流
可以先通过keySet或者entrySet获取一个Set集合,再获取Stream流
数组
Arrays中的静态方法stream 生成流
同种数据类型的多个数据(1,2,3….或“aaa”,“bbb”,“ccc”….)
使用Stream.of(T…values)生成流
1 public static void main(String[] args) { 2 //单列集合 3 ArrayList<String> list = new ArrayList<>(); 4 list.add("aaa"); 5 list.add("bbb"); 6 list.add("ccc"); 7 8 //Stream<String> stream = list.stream(); 9 //stream.forEach(s-> System.out.println(s)); 10 list.stream().forEach(s-> System.out.println(s)); //aaa bbb ccc 11 12 //双列集合 13 HashMap<String,Integer> hm = new HashMap<>(); 14 hm.put("zhangsan",23); 15 hm.put("list",24); 16 hm.put("wangwu",25); 17 //双列集合不能直接获取Stream流 18 //keySet:先获取到所有的键;再把这个Set集合中所有的键放到Stream流中 19 hm.keySet().stream().forEach(s-> System.out.println(s)); //zhangsan wangwu list 20 21 //entrySet:先获取到所有的键值对对象;再把这个Set集合中所有的键值对对象放到Stream流中 22 hm.entrySet().stream().forEach(s-> System.out.println(s)); //zhangsan=23 wangwu=25 list=24 23 24 //数组 25 int [] arr = {1,2,3}; 26 Arrays.stream(arr).forEach(s-> System.out.println(s)); //1 2 3 27 28 //同种数据类型的多个数据 29 Stream.of(1,2,3).forEach(s-> System.out.println(s)); //1 2 3 30 }
Stream流的常见中间操作方法
Stream<T> filter(Predicate predicate):用于对流中的数据进行过滤
Predicate接口中的方法:boolean test(T t):对给定的参数进行判断,返回一个布尔值
1 public static void main(String[] args) { 2 ArrayList<String> list = new ArrayList<>(); 3 list.add("张三丰"); 4 list.add("张无忌"); 5 list.add("王二麻子"); 6 list.add("张良"); 7 list.add("谢广坤"); 8 //filter方法获取流中的每一个数据。而test方法中的s,就依次表示流中的每一个数据。我们只要在test方法中对s进行判断就可以了。 9 //如果判断的结果为true,则当前的数据留下 10 //如果判断的结果为false,则当前数据就不要 11 //list.stream().filter( 12 // new Predicate<String>() { 13 // @Override 14 // public boolean test(String s) { 15 // boolean result = s.startsWith("张"); 16 // return result; 17 // } 18 // } 19 //).forEach(s-> System.out.println(s)); 20 21 //因为Predicate接口中只有一个抽象方法test,所以我们可以使用lambda表达式来简化 22 //list.stream().filter( 23 // (String s)->{ 24 // boolean result = s.startsWith("张"); 25 // return result; 26 // } 27 //).forEach(s-> System.out.println(s)); 28 //最简版 29 list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s)); 30 }
Stream<T> limit(long maxSize):截取指定参数个数的数据
Stream<T> skip(long n):跳过指定参数个数的数据
static <T> Stream<T> concat(Stream a, Stream b):合并a和b两个流为一个流
Stream<T> distinct():去除流中重复的元素。依赖(hashCode和equals方法)
1 public static void main(String[] args) { 2 ArrayList<String> list = new ArrayList<>(); 3 list.add("张三丰"); 4 list.add("张无忌"); 5 list.add("谢广坤"); 6 list.add("谢广坤"); 7 //Stream<T> limit(long maxSize):截取指定参数个数的数据 8 //list.stream().limit(2).forEach(s-> System.out.println(s)); //张三丰 张无忌 9 10 //Stream<T> skip(long n):跳过指定参数个数的数据 11 //list.stream().skip(2).forEach(s-> System.out.println(s)); //谢广坤 谢广坤 12 13 //static <T> Stream<T> concat(Stream a, Stream b):合并a和b两个流为一个流 14 ArrayList<String> list2 = new ArrayList<>(); 15 list2.add("张三丰1"); 16 list2.add("张无忌1"); 17 list2.add("谢广坤1"); 18 19 //Stream<String> stream1 = list.stream(); 20 //Stream<String> stream2 = list2.stream(); 21 //Stream<String> stream3 = Stream.concat(stream1, stream2); 22 //stream3.forEach(s-> System.out.println(s)); 23 //简化版 24 //Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.println(s));//张三丰 张无忌 谢广坤 谢广坤 张三丰1 张无忌1 谢广坤1 25 26 //Stream<T> distinct():去除流中重复的元素。依赖(hashCode和equals方法) 27 list.stream().distinct().forEach(s-> System.out.println(s)); //张三丰 张无忌 谢广坤 28 }
Stream流的常见终结操作方法
void forEach(Consumer action):对此流的每个元素执行操作
Consumer接口中的方法 void accept(T t):对给定的参数执行此操作
long count():返回此流中的元素数
1 public static void main(String[] args) { 2 ArrayList<String> list = new ArrayList<>(); 3 list.add("张三丰"); 4 list.add("张无忌"); 5 list.add("张良"); 6 //void forEach(Consumer action):对此流的每个元素执行操作 7 //在forEach方法的底层,会循环获取到流中的每一个数据,并循环调用accept方法,并把每一个数据传递给accept方法,s就依次表示了流中的每一个数据.所以,只要在accept方法中,写上处理的业务逻辑就可以了. 8 list.stream().forEach( 9 new Consumer<String>() { 10 @Override 11 public void accept(String s) { 12 System.out.println(s); 13 } 14 } 15 ); 16 //lambda表达式的简化格式 17 //是因为Consumer接口中,只有一个accept方法 18 list.stream().forEach( 19 (String s)->{ 20 System.out.println(s); 21 } 22 ); 23 //lambda表达式进一步简化 24 list.stream().forEach(s->System.out.println(s)); 25 26 //long count():返回此流中的元素数 27 long count = list.stream().count(); 28 System.out.println(count); //3 29 }
Stream流的收集操作
在Stream流中无法直接修改集合、数组等数据源中的数据
R collect(Collector collector) 获取流中剩余的数据,但是不负责创建容器,也不负责把数据添加到容器中
工具类Collectors提供了具体的收集方式
public static <T> Collector toList() 把元素收集到List集合中
public static <T> Collector toSet() 把元素收集到Set集合中
1 //定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10。将集合中的奇数删除,只保留偶数。遍历集合得到2,4,6,8,10 2 public static void main(String[] args) { 3 ArrayList<Integer> list1 = new ArrayList<>(); 4 for (int i = 1; i <= 10; i++) { 5 list1.add(i); 6 } 7 list1.add(10); //加此句用于验证toList与toSet区别,toSet不可重复 8 9 //filter负责过滤数据 10 //collect负责收集数据 11 //Collectors.toList() :在底层会创建一个List集合.并把所有的数据添加到List集合中. 12 List<Integer> list = list1.stream().filter(number -> number % 2 == 0) 13 .collect(Collectors.toList()); 14 System.out.println(list); //[2, 4, 6, 8, 10, 10] 15 16 //Collectors.toSet() :在底层会创建一个Set集合.并把所有的数据添加到Set集合中. 17 Set<Integer> set = list1.stream().filter(number -> number % 2 == 0) 18 .collect(Collectors.toSet()); 19 System.out.println(set); //[2, 4, 6, 8, 10] 20 }
public static Collector toMap(Function keyMapper,Function valueMapper):把元素收集到Map集合中
1 /** 2 * 创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄 3 * "zhangsan,23" 4 * "lisi,24" 5 * "wangwu,25" 6 * 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值 7 */ 8 public static void main(String[] args) { 9 ArrayList<String> list = new ArrayList<>(); 10 list.add("zhangsan,23"); 11 list.add("lisi,24"); 12 list.add("wangwu,25"); 13 14 Map<String, Integer> map = list.stream().filter( 15 s -> { 16 String[] split = s.split(","); 17 int age = Integer.parseInt(split[1]); 18 return age >= 24; 19 } 20 //Collectors.toMap 创建一个map集合并将数据添加到集合当中 21 //第一个lambda表达式就是如何获取到Map中的键 22 //第二个lambda表达式就是如何获取Map中的值 23 ).collect(Collectors.toMap( 24 s -> s.split(",")[0], 25 s -> Integer.parseInt(s.split(",")[1]) 26 )); 27 System.out.println(map); //{lisi=24, wangwu=25} 28 }