目录
接口中有且仅有一个抽方法
可以使用lambda表达式
可以使用@FunctionalInterface声明接口
在函数式接口中,可以定义多个默认的非抽象方法
jdk中给我们提供了一些常用的函数式接口
jdk1.8以前,就存在函数式特点接口 : Compartor ,Comparable
jdk1.8以后,提供了一些常用的函数式接口,其中有4个核心接口
消费型接口 ,传递参数,使用参数做一个处理。没有返回值 void accept(T t);
- Consumer
mc = (String s1)->{ - System.out.println(s1.length());
- };
- mc.accept(s);
- //-------------------------------------------
- Consumer
mc1 = (String s1)->{ - System.out.println(s1.length());
- };
- Consumer
mc2 = (String s1)->{ - System.out.println(s1.toUpperCase());
- };
- Consumer
mc3 = s1->{ - System.out.println(s1.substring(0,5));
- };
- //mc2.accept(s);
-
- //这是一个链式操作,先实现消费功能mc3,再实现消费功能mc2,最后实现消费功能mc1
- mc3.andThen(mc2.andThen(mc1)).accept(s);
供给型接口, 无需要传递参数,返回对象 T get();
- //需要产生一个随机数
- //创建了一个对象 Object obj = new Object()
- Supplier
s1 = ()->{ - Random r = new Random();
- return r.nextInt(10);
- };
- Integer num = s1.get() ;
功能型接口,需要传递参数,根据参数做处理,将处理结果返回 R apply(T t); Function
- String s = "dmc is good" ;
- //需要实现功能,将字符串转换成大小
- Function
f1 = (String s1)->{ - return s1.toUpperCase();
- };
- System.out.println( f1.apply(s) );
- //---------------------------------------------
- String s = "dmc is good" ;
- //需要实现功能,将字符串转换成大小
- Function
f1 = (String s1)->{ - System.out.println("1操作");
- return s1.toUpperCase();
- };
- //System.out.println( f1.apply(s) );
-
- Function
f2 = s1->{ - System.out.println("2操作");
- return s1.substring(0,3);
- };
-
- //f1处理后,再进行一次f2的处理
- //System.out.println( f1.andThen(f2).apply(s) );
- //f1处理前,先进行一次f2的处理
- System.out.println( f1.compose(f2).apply(s) );
断言型接口,传递参数,根据参数做判断,返回boolean boolean test(T t)
- //判断user登录信息是否正确
- Predicate
p1 = (User user1)->{ - return user1.uname.equals("dmc") && user1.upass.equals("123");
- };
- System.out.println(p1.test(user)?"登录成功":"登录失败");
- //----------------------------------------------
- User user = new User("dmc","1234") ;
- //判断user登录信息是否正确
- Predicate
p1 = (User user1)->{ - return user1.uname.equals("dmc") ;
- };
- Predicate
p2 = (User user1)->{ - return user1.upass.equals("123") ;
- };
-
- //函数式接口中的链式功能,基于的是一个对象
- System.out.println(p1.or(p2).test(user)?"登录成功":"登录失败");
- System.out.println(p1.negate().test(user));
R apply(T t,U u); BiFunction
- Num num = new Num(10,20);
- Function
f1 = (num1)->num.x + num.y ; - //------------------------------------------
- //二元操作功能
- BiFunction
b1 = (x , y)-> x+y ; - System.out.println(b1.apply(10,20));
stream操作分为2部分
如果没有终端操作,中间操作无法验证结果。
只有终端操作执行时,中间操作才开始执行。(在终端操作执行前,中间操作只是一个标记)

中间操作本身不会执行,只是一个标记,会在终端操作执行时才执行。
中间操作语法会返回一个Stream对象,可以以链式的方式增加多个中间操作(标记)
要么返回一个具体的数据,要么就执行遍历操作,什么都不返回(void)
整个流操作在执行终端操作方法时就结束了(如果有后续操作,也不是流操作,或者是一个新的流操作)
jdk1.8之后,为List , Set , Conllection 增加Stream()方法获得流对象
流对象中装载的就是集合中的数据
list.stream()
set.stream()
collection.stream()
- //上面我们通过集合获得流的时候是先把数据存到集合里,在获得流的时候将数据存到流里
- //下面的这种方法是直接将数据存到流里面
- Stream.of(1,2,3,4,5);
- //这种是通过传入一个Supplier,然后通过Supplier返回的对象存入到流中,通过limit的参数表示在流中存入多少个Supplier提供的对象
- Stream.generate(()->"dmc").limit(100);
- //这种是在流中存入数据1~100
- Stream.iterate(1,(i)->++i).limit(100)
- 参数是个Consumer 消费型接口
- //执行forEach方法时,底层就会遍历每一个元素,每次(底层)遍历获得一个元素,就会调用我们提供的消费功能进行处理(策略模式)
- List
cars = Arrays.asList( - new Car("宝马","蓝色",300000),
- new Car("奔驰","黑色",400000),
- new Car("奥迪","红色",450000),
- new Car("保时捷","蓝色",600000),
- new Car("本田","白色",2000000),
- new Car("比亚迪","白色",220000),
- new Car("理想","黑色",250000)
- );
- cars.stream()
- .forEach(System.out::println);
- Object obj = cars.stream()
- .filter(car->car.color.equals("白色"))
- .count();
- System.out.println(obj);
- //-------------------------------------------
- Object obj = cars.stream()
- .max((c1,c2)->c1.price - c2.price);
- System.out.println(obj);
- //汇总
- //collect终端方法执行时,会遍历所有的元素,会将每个元素的price属性值收集起来,求和
- Object obj = cars.stream()
- .collect(Collectors.summingInt(car->car.price));
- System.out.println(obj);
-
- //分组(汇总)
- Object obj = cars.stream()
- .collect(Collectors.groupingBy(car->car.color));
- System.out.println(obj);
-
- Object obj = cars.stream()
- .collect(Collectors.groupingBy(car->{
- if(car.price<=300000){
- return "便宜" ;
- }else{
- return "昂贵" ;
- }
- }));
- System.out.println(obj);
- 参数是个Predict 断言型接口
- cars.stream()
- .filter(car->"黑色".equals(car.color))
- .forEach(System.out::println);
- 参数是函数型接口 Function
- //map就是在所有的属性中,抽取出部分需要的属性
- //案例中就是在car的3个属性中,抽取出cname和price2个属性
- cars.stream()
- .map(car->{return new Car2(car.cname,car.price); })
- .forEach(System.out::println);
-
- List
---> List
- 可以没有参数,默认是按照升序排列的,还有一个带参数的方法Stream
sorted(Comparator super T> comparator); - 可以自定义排序规则
- //排序
- cars.stream()
- .sorted((c1,c2)->c1.price-c2.price)
- .forEach(System.out::println);
-
- //关于比较器,可以看TreeSet
- limit(long n1)表示从stream中取出n1的个数
- skip(long n2) 表示跳过stream中的前面n2个数
- //分页,从那条记录开始,取几条记录, 从0开始取3条(0,1,2),从3开始取3条(3,4,5),从6开始取3条(7,8,9)
- cars.stream()
- .sorted((c1,c2)->c1.price-c2.price)
- .skip(4) //跳过几个,因为时从0开始条,这个条过几个,也可以理解为从第几个开始
- .limit(3)
- .forEach(System.out::println);