Java高级学习-Stream+方法引用
Stream流
优化集合循环遍历,关注的时做什么 ,而不是怎么做
思想:类似生产线
filter,map,skip都在在对函数模型进行操作,集合元素没有真正被处理,当终结方法count执行的时候,这个模型才会按照指定策略执行,–即Lambda的延迟执行的特性
Stream流是一个来自数据源的元素队列,Stream流不会存储元素,而是按需计算
数据源:集合,数组等
特征:
Pipelining:中间操作都会返回流对象本身,将多个操作串联成管道,可以对操作进行优化:延迟执行(laziness)和短路(short-circuiting)
内部迭代:以前都是通过Iterator或者增强for进行集合遍历,这是外部迭代。Stream提供了内部迭代方式,流可以直接调用遍历方法。
获取流
java.util.stream.Stream 是java8加入的流接口(不是函数式接口)
方式:
-
所有的Collection集合都可以提供stream默认方法获取流;
default Stream stream()
-
Stream接口的静态方法of可以获取数组对应的流
static Stream of ( T…values )
集合转换:
List<String> list = new ArrayList<>()
Stream<String> stream1 = list.stream()
- 1
- 2
Map<String, String> map = new HashMap<>()
//获取键,存储到Set集合中
set<String> keyset = map.keyset();
Stream<String> stream3 = kayset.stream();
//获取值,存储到Collection集合中
Collection<String> values= map.values();
Stream<String> stream4 = values.stream();
//获取键值对(键与值的映射关系)
Set<Map.Entry<String,String>> entrys = map.entrySet();
Stream<Map.Entry<String,String>> stream4 = entrys.stream();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
//数组转换为Stream流
Stream<Integer> stream6 = Stream.of(1, 2, 3, 4, 5);
Integer[ ] arr = {1, 2, 3, 4, 5} ;
Stream<Integer> stream7 = Stream.of (arr);
- 1
- 2
- 3
- 4
方法
延迟方法:返回值类型仍然是Stream接口自身类型的方法,支持链式调用
终结方法:返回值类型不是Stream接口自身类型的方法,因此不支持类似StringBuilder等的链式调用。例如:count,forEach
forEach
forEach ( Consumer <? super T> action );
该方法接收一个Consumer接口函数,会将每一个流元素交给该函数处理
Consumer接口:消费型的函数式接口,可以传递Lambda表达式
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
stream.forEach ( (Integer number) -> { Systrm.out.println(number) ;} );
//简单写法
stream.forEach (number -> Systrm.out.println(number));
- 1
- 2
- 3
- 4
过滤filter
Stream filter( Predicate <? super T> predicate );
Predicate接口:判断接口,返回boolean值
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream1 = stream.filter ( (Integer number) -> { return ( number == 1 );} )
- 1
- 2
Stream特点
Stream流属于管道流,只能被消费一次
第一个Stream流调用完毕方法,数据就会流到下一个Stream上
而第一个Stream流就会关闭,所以第一个Stream流不能进行调用方法。
map
Stream map(Function<? super T, ? extends R> mapper );
Function:将流中的T类型的数据转换为另一种R类型的流,这种转换的工作成为映射。
Stream<String> stream = Stream.of("1", "2", "3");
Stream<Integer> stream2 = stream.map ( (String s) -> { return Integer.parseInt(s) ;} )
stream2.forEach( i -> Systrm.out.println(i) )
- 1
- 2
- 3
统计个数count
统计Stream流中元素的个数,是一个终结方法,不能再继续调用stream流中的方法了
long count(); //返回long类型的整数
Stream
Stream<Integer> stream = list.stream();
long count = stream.count( );
- 1
- 2
取前几个limit
截取流中元素
Stream limit( long maxSize); //如果截取长度大于流长度则不进行操作
Stream<String> stream = Stream.of("1", "2", "3");
Stream<String> stream1 = Stream.limit(2);
- 1
- 2
跳过前几个skip
Stream skip( long n ); //如果流长度小于n,则返回一个长度为0的空流
组合concat
将两个流合并到一个流
static Stream concat( Steam< ? extends T> a , Stream< ? extends T> b);
Stream<String> concat = Stream.concat(stream1, stream2);
- 1
方法引用
简化Lambda表达式
例如:
printString ( (s) -> System.out.printIn(s) );
System.out 对象是存在的;printIn方法也是存在的
printString ( System.out :: printIn ); //直接让System.out 的printIn方法来取代Lambda。
双冒号**::为引用运算符,它所在的表达式被成为方法引用。如果Lambda要表达的函数方案已经存在于某个方法的实现中,则可以通过:😗*引用该方法作为Lambda的替代者。
通过对象名引用成员方法
如果对象名已经存在,成员方法也存在,则可以引用。
printString ( (s) -> {
MObject obj = new MObject (); obj.成员方法(); } );
MObject 对象是存在的;成员方法也是存在的
MObject obj = new MObject ();
printString (obj :: 成员方法 );
通过类名引用静态成员方法
类名::静态成员方法
通过super引用父类成员方法
super::父类成员方法
代替method ( () -> { super.父类成员方法( ); } );
通过this引用成员方法
this::成员方法
类的构造器引用
类名称:: new
定义一个Person类
定义一个接口
public interface PersonBuilder {
//根据传递姓名,创建Person对象返回
Person builderPerson(String name); }
- 1
- 2
- 3
定义一个方法
public void printName(String name , PersonBuilder pb ){
Person person = pb.builderPerson( name );
System.out.printin( person.getName() ); }
- 1
- 2
- 3
使用方法 printName( “xxx” , (String name) -> { return new Person( name ); } )
使用方法引用 printName(“xxx”, Person::new);
数组的构造器引用
数组类型[ ] :: new
文章来源: blog.csdn.net,作者:αβγθ,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/weixin_38022166/article/details/115538545
- 点赞
- 收藏
- 关注作者
评论(0)