day33_Stream(JDK1.8后的接口,本身不是函数式接口)
今日内容
-
Stream流
主要是方法的调用:forEach(终结方法) fiter(过滤),map(映射),skip(跳过),count(组合).
1.Stream流
JDK1.8引入的新特性。用于解决已有集合类库既有的一些弊端,需要依赖于Lambda表达式
在学习Stream流之前,获取集合中的元素是这样的(需要不断地循环遍历)
public class Demo01Stream{ public static void main(String[] args){ //构建一个集合 List<String>list =new ArrayList<String>(); list.add("abc123"); list.add("aaa22"); list.add("bcd125"); list.add("abcd120"); list.add("bbb230"); //需要字符串中包含数字1的元素取出来 List<String> list2=new ArrayList<String>();// 已经取出 abc123 bcd125 abcd120 for(String str:list){ if(Str.contains("1")){ list2.add(str); } } //需要集合当中字符串不能超过6个的元素取出来 List<String> list3 = new ArrayList<String>(); for(String str:list2){ if(str.length() <=6){ list3.add(str); } } //遍历查看最终想要的元素集合 for(String str : list3){ System.out.println(str); } } }
Stream流的更加方法:(更加简洁)
public class Demo01Stream{ public static void main(String[] args){ //构建一个集合 of("abc123","aaa22") List<String>list =new ArrayList<String>(); list.add("abc123"); list.add("aaa22"); list.add("bcd125"); list.add("abcd120"); list.add("bbb230"); //需要字符串中包含数字1的元素取出来 //需要集合当中字符串不能超过6个的元素取出来 //遍历查看最终想要的元素集合 //Stream<T>filter(Predicate< ? super T> predicate)返回由榆次给定为此匹配的 Stream<String> stream = list.strream(); Stream<String> stream02=stream.filter(str ->.contains("1"));//子集合A Stream<String> stream03=stream02.filter(str ->str.length()-> 6);//子集合B stream03.forEach(str-> System.out.println(ste)); //再次优化 list. strean(). filer(str -> str. contains("1")). filter(str -> str.length() <= 6). forEach(str-> System. out . printIn(str)); } }
流式思想概述:
流式思想类似于工厂中的生产流水线
方案中的操作的每一个步骤我们称之为“流”,调用指定的api方法,从一个流中转换为另一个流。
当我们使用一个流的时候,通常需要包含三个基本步骤,1.获取一个数据源--->2.数据转换-->3.执行操作获取想要的操作结果。每次转换都是原有的Stream返回一个新的Stream对象。这样我们就可以像链条一样进行操作。
Stream流 其实是一个集合元素的函数模型它并不是集合,也不是数据结构。其本身并不存储任何元素(地址值)。
-
元素是特定类型的对象,形成一个队列,Java当中的Stream并不会存储元素,而是按需计算。
-
2.获取流对象
2.1
3.Stream流中的常用方法
流模型中的操作很多,大致上可以把其中的api方法分成两部分:
1.延迟方法:返回值类型都是Stream接口自身,因此可以支持链式操作。
2.终结方法:返回值就不是Stream接口自身,因此不能再进行链式操作。count方法和forEach
forEach方法:
void forEach(Comsumer<T> consumer);//借助于该函数式接口中的方法accept方法 //Consumer<T> 是一个消费型接口 用来消费一个指定泛型的数据。
代码:
public class TestForEach{ public static void main(String[] args){ //1.获取一个数据源 Stream<String> stream = Stream.of("abc","aaa","abd","bcd","ddd"); //2.转换数据 //3.执行操作获取想要的结果 stream.forEach(str ->{ if(str.contains("a")){ System.out.println(str); } }); } } //展示的结果 abc aaa abd
过滤:filter
Stream<T> filter(Predicate<? super T> predicate) 返回有与此给定谓词匹配的此流的元素组成的流。 //借助于Predicate函数是借口当中的抽象方法 test(T t) 对数据进行过滤
该方法接收一个函数式接口Predicate,可以使用Lambda表达式进行条件的筛选
java.util.stream.Predicate函数式接口。其中唯一的抽象方法
映射:map
如果你需要将流中的数据映射到另外一个流中,可以使用map中方法。
<R> Stream<R> map(Function<? super T,? extends R> mapper)返回由给定函数应用于此流的元素的结果组成的流。
该方法接收一个函数式接口Function作为方法参数,可以将当前流中的T数据转换成另外一种R类型的数据。
Function接口
java.util.stream.Function函数式接口。其中唯一的抽象方法:
R apply(T t) //可以将一种T类型的数据转换为R类型的数据,那么这种转换的动作,我们称之为"映射"
统计个数:count
可以向Collection集合当中的size()一样,统计流中的元素个数,通过count方法来实现。
//返回此流中的元素数。 long count();
该方法返回一个long类型的值代表值中元素的个数(区别于size()返回值int值)
代码如下:
public class Demo01Count{ public static void main(String[] args){ Stream<Integer> stream = Stream.of(1,2,3,4,5,6); //统计个数 long count = stream.count(); System.out.println(count);//6 } }
取用流中前几个:limit(限制)
limit()方法可以对流中的数据进行限制--->截取操作,需要一个参数,设定取用流中前max个数。
Stream<T> limit(long maxSize)//返回由此流的元素组成的流,截取长度不能超过 maxSize。
参数是一个long类型的,截取的长度不能超过流中最大元素个数;否则不进行操作,
代码:
public class Demo02Limit{ public static void main(String[] args){ //准备一个数据源 //获取数据源 Stream<Intefer> stream =Stream.of(12,13,14,15,16,20,30); //想要截取流中的前五个元素 Stream<Integer> stream02 = stream.limit(5); //查看流中的元素个数 System.out.pritnln(stream02.count);//5 } }
跳过:skip
跳过前几个元素,取用后几个元素,可以使用skip方法来实现。
Stream<T> skip(long n)//在丢弃流的第一个n元素后返回由该留的n元素组成的流。
如果流中的当前个数小于n,你将会得到一个长度为0的空流,反之流中的个数大于n,则会跳过前n个元素
public static void main(String[] args) { //1. String[] source = {"123","124","125","abc","abd","abe"}; Stream<String>stream = Stream.of(source); //2.跳过前3个元素 Stream<String> stream2 = stream.skip(source.length);//长度为0的空流 //3. //stream2.forEach(str -> System.out.println(str)); long count = stream2.count(); System.out.println(count);//0 }
组合:concat
如果有两个流,希望合并成一个流,那么可以使用concat静态方法
//创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。 static<T> Stream<T> concat(Stream<? extends T> a,Stream?<? extends T> b)
代码:
public class Demo04Concat{ public static void main(String[] args){ //准备两个数据源 //获取两次数据源 Stream<Integer> stream =Stream.of(12,13,14,15,16,20,30,); Stream<Integer> stream02 = Stream.of(1,2,3,4,5,6,7); //把两个六合并到一起 Stream<Integer> stream03=Stream.concat(Stream.stream02); Stream03.forEach(num -> System.out.print(num+"")); //展示结果:12,13,14,15,16,20,30,1,2,3,4,5,6,7 } }