Strem流

1.1概述

说到Strem便容易想到I/O Strem,而实际上,谁规定“流”就一定是流呢?在Java8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端。
1.2传统集合遍历的弊端
需求:筛选出姓张且名字长度为3的人的名字并打印

List <String> list = new ArryList<> ();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("老邱");
list.add("张三丰");
List<String> list1 = new ArryList<>();
//筛选姓张的的人名
for (String name : list1) { 
if (name.startsWith("张")) {
 list1.add(name); 
     } 
 }
 List<String> list2 = new ArrayList<>(); 
 // 筛选长度为3的人名 
 for (String name : list1) { 
 if (3 == name.length()) { 
 list2.add(name); 
        } 
 }
 System.out.println(list2); 

通过以上代码发现,传统的for循环不仅要专注做什么,还要专注怎么做,Java 8的Lambda让我们可 以更加专注于做什么(What),而不是怎么做(How)


List<String> list = new ArrayList<>();
 list.add("张无忌");
 list.add("周芷若");
 list.add("赵敏"); 
 list.add("老邱"); 
 list.add("张三丰");
 list.stream()
 .filter((name)>name.startsWith("张"))
 .filter((name)>3 == name.length()) 
  .forEach((name)>System.out.println(name)); 

直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为 3、逐一打印。代码 中并没有体现使用线性循环或是其他任何算法进行遍历,我们真正要做的事情是内容被更好地体现在代码中

2.流式思想

2.1概述
整体来看,流式思想类似于工厂车间的“生产流水线”。Stream(流)是一个来自数据源的元 素队列 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计 算。 数据源 流的来源。 可以是集合,数组等。 备注:“Stream流”其实是一个集合元素的函 数模型,它并不是集合,也不是数据结构,其本身并不存储任何 元素(或其地址值)。
2.2流的获取
java.util.stream.Stream 是Java 8新加入的常用的流接口。(这并不是一个函数式接口。)
获取一个流非常简单,有以下两种常用的方式:
所有的 Collection 集合都可以通过 stream 默认方法获取流;
Stream 接口的静态方法 of 可以获取数组对应的流
2.3
,获取Collection对应的流
2.4获取Map对应流
将map拆分成键集合和值集合,再分别获取对应的流
2.5获取数组对应的流

3.Strem常用方法

3.1,概述 流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:
延迟方法:返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。(除了终 结方法外,其余方 法均为延迟方法。)
终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 String
3.2逐一处理:forEach

//语法 
void forEach(Consumer<? super T> action);
 //基本使用 
 List<String> list = new ArrayList<>(); 
 list.add("张无忌"); 
 list.add("周芷若"); 
 list.add("赵敏");
 list.add("老邱");
 list.add("张三丰"); 
 list.stream().forEach(name ‐> System.out.println(name)); 

3.3过滤filter

//语法
 Stream<T> filter(Predicate<? super T> predicate);
 //基本使用
  List<String> list = new ArrayList<>();
   list.add("张无忌"); 
   list.add("周芷若"); 
   list.add("赵敏"); 
   list.add("老邱"); 
   list.add("张三丰");
   list.stream().filter((name)>name.startsWith("张")); 

3.4统计个数:count

//语法 
long count(); 
//基本使用 
List<String> list = new ArrayList<>(); 
list.add("张无忌"); 
list.add("周芷若"); 
list.add("赵敏"); 
list.add("老邱"); 
list.add("张三丰"); 
long count = list.stream().filter((name)>name.startsWith("张")).count(); System.out.println(count); 

3.5取前几个;limit
limit 方法可以对流进行截取,只取用前n个。 参数是一个long型,如果集合当前长度大于参数 则进行截取;否则不进行操作

//语法
 Stream<T> limit(long maxSize);
  //基本使用
   List<String> list = new ArrayList<>(); 
   list.add("张无忌"); 
   list.add("周芷若"); 
   list.add("赵敏"); 
   list.add("老邱"); 
   list.add("张三丰"); 
   long count = list.stream().limit(2).count();                   System.out.println(count);

3.6跳过几个;skip
如果希望跳过前几个元素,可以使用 skip. 方法获取一个截取之后的新流. 如果流的当前长度大于 n,则跳过前n个;否则将会得到一个长度为0的空流


//语法 
Stream<T> skip(long n); 
//基本使用 
List<String> list = new ArrayList<>(); 
list.add("张无忌"); 
list.add("周芷若");
list.add("赵敏"); 
list.add("老邱"); 
list.add("张三丰"); 
long count = list.stream().skip(2).count(); 

3.7组合;hconcat

如果有两个流,希望合并成为一个流,那么可以使用 Stream 接口的静态方法 concat

Stream<String> s1 = Stream.of("老邱"); 
Stream<String> s2 = Stream.of("小邱"); S
tream<String> s3 = Stream.concat(s1, s2); s3.forEach((name)>System.out.println(name)); 

4Stream的综合案例
需求

a. 第一个队伍只要名字为3个字的成员姓名;
b. 第一个队伍筛选之后只要前3个人;
c. 第二个队伍只要姓张的成员姓名;
d. 第二个队伍筛选之后不要前2个人;
e. 将两个队伍合并为一个队伍;
f. 打印整个队伍的Person对象信息

Stream.concat(
 list.stream() 
 .filter((person)>person.getName().length() == 3) .limit(3), 
 list.stream()
  .filter((person)>person.getName().startsWith("张")) .skip(2) 
  )
  .forEach((person)>System.out.println(person.getName())
发布了17 篇原创文章 · 获赞 0 · 访问量 151

猜你喜欢

转载自blog.csdn.net/weixin_46101397/article/details/105168419