第四章 函数式编程(Lambda表达式&Stream流)

一、Lambda表达式

特点:是匿名函数 2是可传递

         匿名函数:需要一个函数,但又不想命名一个函数的场景下使用lambda表达式,使用lambda表达式时函数内容应该简单

         可传递:将lambda表达式传递给其他的函数,它当做参数,lambda作为一种更紧凑的代码风格,使java语言表达能力增强

语法:

Lambda表达式在java语言中引入一个新的语法元素和操作符,这个操作符为“->",该操作符被称为Lambda操作符或箭头操作符,它将Lambda分为两个部分:

         左侧:指定了Lambda表达式所需要的所有参数:

         右侧:指定了Lambda体,即Lambda表达式所要执行的功能。

常见语法格式:

有参:lambda表达式的基本格式为(x1,x2)->{表达式}

           参数类型可以省略,两边的括号不能省略

           如果表达式只有一行,那么表达式两边的花括号可以省略

           如果只有一个参数,参数的括号可以省略

  无参:无参时,参数的括号不能省略,参数类型可以省略

           基本格式为()->{表达式}

示例:

语法格式一:无参,无返回值,Lambda体只需要一条语句:
           Runnable r=() ->System.out.println("hello lambda“);
语法格式二:Lambda需要一个参数:
           Consumer<String> con =(x) ->System.out.println(x);
语法格式三:Lambda只需要一个参数时,参数的小括号可以省略:
           Consumer<String> con=x -> System.out.println(x);
语法格式四:Lambda需要两个参数,并且有返回值:
           Comparator<Integer> com=(x,y) ->{
                System.out.println("函数式接口“);
                return Integer.compare(x,y);
          }
语法格式五:当Lambda体只有一条语句是,return与大括号可以省略:
           Comparator<Integer> com =(x,y)->Integer.compare(x,y);

二、Stream 流使用

Stream创建方法:

Stream stream= Stream.empty();  //创建空的Stream对象:
List<String> list=Arrays.asList(‘a’,’b’,’c’); //通过集合类中的stream或者parallelStream方法创建:
Stream listStream=list.stream();         
Stream paralelListStream=list.parallelStream();
Stream s = Stream.of(“a”,”b”,”c”); //通过Stream的of方法创建:

Stream常用方法:

准备数据

Person p1 = new Person("1","张三","123",18,new BigDecimal(61.5));
Person p2 = new Person("2","李四","123",20,new BigDecimal(81.5));
Person p3 = new Person("3","王五","123",20,new BigDecimal(34.5));
Person p4 = new Person("4","赵六","123",17,new BigDecimal(34.5));
Person p5 = new Person("5","赵六","123",18,new BigDecimal(54.4));

List<Person> list  = new ArrayList<>();
list.add(p1); list.add(p2); list.add(p3); list.add(p4); list.add(p5);
Stream<String> stream = Stream.of("T1", "T2", "T3", "T1", "T4", "5");

两类:中间操作,终端操作 || 惰性求值,及早求值

filter    :对stream中元素进行过滤
distinct  :去重
sorted    :排序
limit     :限制个数:获得前几个
skip      :限制个数:去掉前几个
map       :元素一对一转换
close     :关闭stream   

1. filter :元素过滤:

list.stream().filter(person -> person.getAge() >= 18) .collect(Collectors.toList());

2 distinct 去重:

list.stream().filter(st -> st.contains("T")).distlist.inct()
             .collect(Collectors.toList());

3 sorted 排序:

list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
             .collect(Collectors.toList());

sorted 排序 有null值:

list.stream().sorted(Comparator.comparing(Person::getGrade,Comparator.nullsFirst(BigDecimal::compareTo)).reversed())
             .collect(Collectors.toList());

4.limit :类似sql 里 limit ,返回包含前n个元素的流

list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).limit(3)
             .collect(Collectors.toList());

5.skip:skip操作与limit相反,是跳过前n个元素,排序在2个之后的:

list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).skip(3)
             .collect(Collectors.toList());

6.map() 元素1对1 转换:

List<String> list5 = Stream.of("a","b","C").map(string->string.toUpperCase()).collect(Collectors.toList());
List<String> list6 = list.stream().map(Person::getUsername).collect(Collectors.toList());

终端操作:

reduce     :规约,对数据进行操作,返回一个结果
collect    :根据参数做操作
anyMatch   :只要有一个满足返回true,否则false
allMatch   :全部满足返回true,否则false
noneMatch  :全部不满足返回true,否则false    
forEach    :对所有对象进行迭代处理,无返回值
iterator   :返回Stream中所有对象的迭代器
toArray    :返回元素数组   
count      :元素数量
max       :最大元素
min       :最小元素
findFirst :返回第一个对象
findAny   :返回任意一个对象

reduce()规约:对经过参数化操作后的集合进行进一步的运算,可用对集合实施归约操作

// BigDecimal类型:
BigDecimal big1 = list.stream().map(p -> p.getGrade()).reduce(BigDecimal::add).get();
BigDecimal big2 = list.stream().filter(p->p.getGrade()!=null).map(Person::getGrade).reduce(BigDecimal.ZERO,BigDecimal::add);
// int
int i1  = list.stream().map(p -> p.getAge()).reduce(0,(a,b)->a+b);
int i2  = list.stream().map(Person::getAge).reduce(0,Integer::sum);

collect收集:

// collect(toList())方法由Stream里的值生成一个列表,是一个及早求值操作,可以理解为由Stream向Collection的转换
list.stream().filter(p->p.getAge()>=18).collect(Collectors.toList()); 

list转换为map:

Map<String, Person> collect = list.stream().collect(Collectors.toMap(Person::getId, p -> p));
 //使用Collectors.toMap()时 key 不能重复:
 //解决办法:toMap()重载方法:
Map<String, Person> collect1 = list.stream().collect(Collectors.toMap(Person::getUsername, Function.identity(),(k1,k2)->k2));

分组:Collectors.groupingBy

Map<Integer, List<Person>> collect2 = list.stream().collect(Collectors.groupingBy(Person::getAge));

anyMatch allMatch noneMatch (筛选判断)

Stream.of("1", "2", "3", "4", "5").anyMatch(p -> p.equals("7")); //有一个满足为true
Stream.of("1", "2", "3", "4", "5").allMatch(p -> "6".compareTo(p)>0); //全部满足为true
Stream.of("1", "2", "3", "4", "5").noneMatch(p -> "6".compareTo(p) < 0);//全部不满足为true
String ids = "1,2,3,4,5";
List<Object> listIds = Arrays.asList(ids.split(",")).stream().collect(Collectors.toList());
boolean result = listIds.stream().anyMatch(p -> p.equals("2"));
System.out.println(result);

forEach:

list.stream().filter(p -> p.getAge() > 20).forEach(System.out::println);
list.stream().filter(p -> p.getAge() > 20).forEach(person -> System.out.println(person.getUsername()));

count:

long count = list.stream().count();

toArray:

Object[] objects = list.stream().toArray();

Collectors 说明:Collectors是java.util.stream.Collectors类,提供了对流的操作:分组,排序(支持多字段排序),最大值,最小值,平均值。即数据可以在数据库中完成的操作,在Collectors也可以

Collectors.groupingBy(); //分组
Collectors.toList() //流转换
Collectors.toMap()

 

三、方法引用

方法引用用来替换函数式接口,使用方法引用可以是代码更加简洁

使用条件:方法的参数和返回值类型与函数式接口中抽象方法的参数和返回值类型一致

        使用方法:方法引用主要有如下三种使用情况:

                         类::实例方法

                         类::静态方法

                         对象::实例方法

                         其中后两种情况等同于提供方法参数的lambda表达式

例如:System.out::println等同于(x) ->System.out.println(x) Math::pow 等同于(x,y) ->Math.pow(x,y)

第一种,第一个参数会成为执行方法的对象,String::compareToIgncCase等同于(x,y)->x.compareToIgnoreCase(y)

此外,方法引用还可以使用this::methodName及super::methodName表示该对象方法或者父类对象的方法

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值