Lambda表达式和函数式编程的简单使用

  1. lambda表达式是JDK8新特性的一种;可以对某些匿名内部类进行简写;

核心原则:可推导可省略

基本格式:(参数列表)-> {代码}

lambda表达式例一:

new Thread(new Runnable() {
           public void run() {
               System.out.println("简单线程调用");
           }
       }).start();

改写成lambda表达是形式为:

new Thread(()-> {
           System.out.println("lambda表达式第一次应用");
       }).start();

原则就是一个匿名内部类实现的是一个接口,且里面只有一个方法是抽象方法

lambda表达式例二:

 public static void main(String[] args) {
        int i = calculateNum(new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        });
        //System.out.println(i);
    }
    public static int calculateNum(IntBinaryOperator operator){
        int a = 10;
        int b = 120;
        return operator.applyAsInt(a,b);
    }

转换成lambda表达式的形式为:

public static void main(String[] args) {
        int i = calculateNum((left, right) ->{
                return left + right;
        });
        System.out.println(i);
    }
    public static int calculateNum(IntBinaryOperator operator){
        int a = 101;
        int b = 120;
        return operator.applyAsInt(a,b);
    }

lambda表达式例三:

public static void main(String[] args) {
      PrintNum(new IntPredicate() {
          @Override
          public boolean test(int value) {
              return value % 2==0;
          }
      });
    }
    public static void PrintNum(IntPredicate predicate){
      int arr[] = {1,2,3,4,5,6,7,8,9,10};
        for (int i : arr) {
           if(predicate.test(i)){
               System.out.println(i);
           }
        }

转换成lambda表达式代码为:

public class LambdaTest {
    public static void main(String[] args) {
      PrintNum((value) ->{
              return value % 2!=0;
          });
    }

lambda表达式例四:

 Integer integer = typeConver(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.valueOf(s);
            }
        });
        System.out.println(integer);
    }
    public static <R> R typeConver(Function<String,R> function){
    String str = "12345";
    R result = function.apply(str);
    return result;
    }

转换成lambda表达式形式为:

   Integer integer = typeConver((String s)-> Integer.valueOf(s)
        );
        System.out.println(integer);
    }

lambda表达式例五:

public static void main(String[] args) {
        forEachArr((value) -> System.out.println(value));
    }
    public static void forEachArr(IntConsumer consumer){
     int[] arr = {1,2,3,4,5,6,7,8,9,10};
        for (int i :arr) {
            consumer.accept(i);
        }
    }

上述lambda表达式可以省略,省略规则可不记;

  1. Stream流概念:

对集合和数组进行操作:

Stream例一:打印list集合中所有年龄小于18岁的作家的名字,并去重;

 List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
                .distinct() //对几个去重
                 .filter(author -> author.getAge()<18) //筛选出年龄小于18岁的作者集合
                 .forEach(author -> System.out.println(author.getName()));  //这边foreach是终结操作,打印出作者姓名
    }

常见操作:

(1)创建流:

①单例集合: 集合对象.stream()

②数组集合:Arrays.stram(数组名)或者stream.of(数组名)进行创建

③双列集合:转换成单例对象再创建 如 map.entrySet().stream()

(2)中间操作:

①filter:对流中进行过滤操作

例如:打印所有姓名长度大于1的作家的姓名

 public static void main(String[] args) {
        List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
                .filter(author -> author.getName().length()>1)
                .forEach(author -> System.out.println(author.getName()));
    }

②map:将流中的对象进行转化或者计算,这边是转换成字符串进行操作

例如:输出所有作家的姓名

 public static void main(String[] args) {
        List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
              .map(author -> author.getName())
                .forEach(string-> System.out.println(string));
    }

③distinct:可以去除流中的重复元素:实体类中必须重写equal()方法

④sorted:对流中的元素进行排序,这边实体类需要实现Comparable<>接口

例如:对流中的元素按照年龄进行降序排列,并且要求不能有重复元素;

第一种情况,sorted()不带参数,需实现Comparable方法

public class Author implements Comparable<Author>
 @Override
    public int compareTo(Author o) {
        return o.getAge()-this.getAge(); //这边表示按年龄进行降序排序
    }
   List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
              .distinct()
                .sorted()
                .forEach(author -> System.out.println(author));
    }

第二次方式:sorted()方法带参数,将年龄进行升序排列

 List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
              .distinct()
                .sorted((o1, o2) -> o1.getAge()-o2.getAge())
                .forEach(author -> System.out.println(author));
    }

⑤limit:设置流的最大长度

例如:对流中元素按照年龄进行降序排列,并且要求不能有重复元素,然后打印其中年龄最大的两个作家的姓名;

 List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
              .distinct()    //将流中的元素进行去重
                .sorted((o1, o2) -> o2.getAge()-o1.getAge())
                .limit(2)
                .forEach(author -> System.out.println(author.getName()));

⑥skip:跳过流中某些元素

例如:对流中元素按照年龄进行降序排列,并且要求不能有重复元素,然后打印除了年龄最大的作家的姓名;

List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
              .distinct()    //将流中的元素进行去重
                .sorted((o1, o2) -> o2.getAge()-o1.getAge())
                .skip(1)
                .forEach(author -> System.out.println(author.getName()));

⑦flatMap:可以把流中的一个对象转换成多个对象作为流的元素

例一:打印所有书籍的名字(书籍和作家的名字是多对一,书籍在作家表中是list集合),要求对重复元素进行去重;

 List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
             .flatMap(author -> author.getBooks().stream())         //转换成book流对象
                .distinct()                                         //这边是对book集合进行去重;
                .forEach(book -> System.out.println(book.getName()));

例二:对字符串进行分割

  List<Author> authors = getAuthors();
        authors.stream()     //把list集合转换成流;
             .flatMap(author -> author.getBooks().stream())         //转换成book流对象
                .distinct()                                         //这边是对book集合进行去重;
                .flatMap(book -> Arrays.stream(book.getCategory().split(","))) //因为分类是数组,所以需要转换
                .distinct()
                .forEach(category-> System.out.println(category));

(3)终结操作:

①forEach(),对流中的元素进行遍历操作

②count:可以获取流中元素个数

例如:

打印作家所出书籍的数量,注意去重;

 List<Author> authors = getAuthors();
        long count = authors.stream()     //把list集合转换成流;
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .count();
        System.out.println(count);

③min&max 取出流中的最大值 最小值

分别获取这些作家的所出书籍的最高分和最低分并打印

List<Author> authors = getAuthors();
        Optional<Integer> max = authors.stream()     //把list集合转换成流;
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max((score1, score2) -> score1 - score2);
        Optional<Integer> min = authors.stream()     //把list集合转换成流;
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max((score1, score2) -> score2 - score1);
                System.out.println(max.get());
                System.out.println(min.get());

④collect:把当前流转换成一个集合

例一:获取一个存放所有作者名字的list集合

List<String> collect = authors.stream()
                .distinct()
                .map(author -> author.getName())
                .collect(Collectors.toList());
        System.out.println(collect);

例二:获取一个所有书名的set集合

//获取一个所有书名的set集合
                .distinct()
                .map(author -> author.getName())
                .collect(Collectors.toSet());
        System.out.println(collect);

例三:获取一个map,map的可以为作者名,value为List<Book>,map集合必须指定key和value

 List<Author> authors = getAuthors();
        Map<String, List<Book>> map = authors.stream()
                .distinct()
                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
        System.out.println(map);

⑤anyMatch:可以用来判断是否有任意符合匹配条件的元素,结果为boolean类型

例:判断是否有年龄在29岁的作家

List<Author> authors = getAuthors();
        boolean b = authors.stream()
                .distinct()
                .anyMatch(author -> author.getAge() > 29);
        System.out.println(b);

⑥allMatch/noneMatch:可以用来判断是否全部符合/不符合匹配条件的元素

⑦findAny:获取流中的任意一个元素

例:获取一个年龄大于18的作家,如果存在则输出它的姓名

 List<Author> authors = getAuthors();
        Optional<Author> optional = authors.stream()
                .distinct()
                .filter(author -> author.getAge() > 18)
                .findAny();
        optional.ifPresent(author-> System.out.println(author.getName()));

⑧findFrist:获取流中的第一个元素

例:获取年龄最小的作家,并输出他的姓名

 List<Author> authors = getAuthors();
        Optional<Author> optional = authors.stream()
                .distinct()
                .sorted((o1, o2) -> o1.getAge()-o2.getAge())
                .findFirst();
        optional.ifPresent(author-> System.out.println(author.getName()));

⑨reduce:归并,对流中的数据按照你制定的计算方式计算出一个结果(缩减操作)

例一:使用reduce求所有作者年龄的和

 List<Author> authors = getAuthors();
        Integer reduce = authors.stream()
                .map(author -> author.getAge())
                .reduce(0, (result, element) -> result + element); //这边一个参数0表示初始值
                                                                       //result+element表示结果加上遍历的值
        System.out.println(reduce);

例二:使用reduce求所有作者中年龄最大的值

 List<Author> authors = getAuthors();
        Integer reduce = authors.stream()
                .map(author -> author.getAge())
                .reduce(0, (result, element) -> result > element ? result:element);
        System.out.println(reduce);

例三:使用reduce求所有作者中年龄最小的值;

List<Author> authors = getAuthors();
        Integer min = authors.stream()
                .map(author -> author.getAge())
                .reduce(Integer.MAX_VALUE, (result, element) -> result < element ? result:element);
        System.out.println(min);

Stream流的注意事项:

①惰性求值:必须要有终结操作,不然中间操作不会被执行;

②流是一次性的;

③不会影响原始数据:

  1. Optional概述

:主要是防止空指针异常;

3.1创建Optional对象

一般都是使用Optional的静态方法ofNullable()

List<Author> authors = getAuthors();
        Stream<Author> stream = authors.stream();
        Optional<List<Author>> optionalAuthors = Optional.ofNullable(authors);
        optionalAuthors.ifPresent(authors1 ->stream.forEach(author -> System.out.println(author.getName())));

使用方法二:

Optional<Author> authorOptional = getAuthorOptional();
authorOptional.ifPresent(author->system.out.println(author.getName()));

3.2 安全消费值: 使用ifPresent方法;

3.3安全获取值:不推荐使用get方法,里面有orElseGet方法可以设置默认值,orElseThrow可以抛出一个异常

List<Author> authors = getAuthors();
        Optional<List<Author>> optionalAuthors = Optional.ofNullable(authors);
        List<Author> authors1 = optionalAuthors.get();
        System.out.println(authors1);

3.4过滤数据:使用filter进行过滤;

3.5判断:IfPresent:返回boolean值;

3.6 数据转换:map方法

  1. 函数式接口的概述:接口中只有一个抽象方法;

@FunctionalInterface注解标识的都是函数式接口

4.1默认方法:包括and,or,negate(取反)等

5.方法引用:集合必须带上泛型 我觉得

alt+enter

基本格式:类名::方法名

5.1引用类的静态方法:

5.2引用对象的实例方法:类调成员方法

5.3引用类的成员方法:

5.4构造器引用

6.并行流

只需要在流对象后面加上parallel方法就可以实现并行流;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值