java8函数式编程详解

精通java8函数式编程

  • 示例源码
  • lamda表达式
  • Stream 流
    • 创建流
    • 中间操作
    • 终结操作
    • 并行流
  • Optional
    • 创建对象
    • 获取值
    • 过滤&判断&数据转换
  • 函数式接口
    • 常用接口
    • 默认方法
  • 方法引用
    • 示例


示例源码

示例源码
光看不练只能有个印象,自己手动写出的代码,才能加深学习深度。拿出你的小手敲出自己的示例代码。

lamda表达式

java的语法糖,本质是匿名内部类

  • 示例
public class LambdaDemo01 {
    public static void main(String[] args) {
        // 匿名内部类方式
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello Runnable...");
            }
        }).start();

        // lambda方式
        new Thread(() -> {
            System.out.println("Hello Runnable lambda...");
        }).start();
    }
}

public class LambdaDemo02 {
    public static void main(String[] args) {
        // 匿名内部类实现加法操作
        System.out.println(operator(10, 20, new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        }));

        // lambda实现加法操作
        System.out.println(operator(10, 20, (a, b) -> {
            return a + b;
        }));

		// 继续简化
        System.out.println(operator(10, 20, (a, b) -> a + b ));
    }

    /**
     * 定义一个操作方法
     *
     * @param a
     * @param b
     * @param operator
     * @return
     */
    public static int operator(int a, int b, IntBinaryOperator operator) {
        return operator.applyAsInt(a, b);
    }
}
public class LambdaDemo03 {
    public static void main(String[] args) {
        // 偶数才打印
        testPrint(value -> value % 2 == 0);
    }

    /**
     * 定义一个操作方法
     *
     * @param intPredicate
     * @return
     */
    public static void testPrint(IntPredicate intPredicate) {
        for (int i = 0; i < 10; i++) {
            if (intPredicate.test(i)) {
                System.out.println(i);
            }
        }
    }
}
public static void main(String[] args) {
        // 将字符串转Integer
        System.out.println(typeConvert((Function<String, Integer>) s -> Integer.valueOf(s), "10"));
    }

    /**
     * 类型转换,将T转换成R
     *
     * @param fun
     * @return
     */
    public static <T, R> R typeConvert(Function<T, R> fun, T src) {
        return fun.apply(src);
    }
public class LambdaDemo05 {
    public static void main(String[] args) {
        myConsumer(value -> System.out.println(value));
    }

    public static void myConsumer(IntConsumer intConsumer) {
        for (int i = 0; i < 10; i++) {
            intConsumer.accept(i);
        }
    }
}

Stream 流

java8 利用函数式编程,对集合或数组进行流式操作的类库

  • 惰性求值(没有终结操作,中间操作是不会被执行的)
  • 流是一次性的(流终结操作后,不能继续被使用)
  • 不会影响原数据(对集合元素的属性做set处理是会设置到原集合的)
public class StreamDemo01 {

    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();
        // 去重并打印年龄小于25的作者名称
        authors.stream().distinct().filter(author -> author.getAge() < 25).forEach(author -> System.out.println(author.getName()));
    }
}

创建流

public class StreamDemo02 {

    public static void main(String[] args) {
        // 创建流的方式
        // list
        List<Author> authors = MyUtil.getAuthorList();
        Stream<Author> stream = authors.stream();

        // 数组
        String[] arr = new String[1];
        Stream<String> stream1 = Arrays.stream(arr);
        Stream<String> arr1 = Stream.of(arr);

        // map
        Map<String, String> map = new HashMap<>();
        Stream stream2 = map.entrySet().stream();
    }
}

中间操作

返回流对象的方法,必须调用终结操作,中间操作才会执行

  • filter 过滤
  • map
  • distinct 去重
  • sorted 排序
  • limit 截取长度
  • skip 跳过
  • flagMap
public class StreamDemo03 {

    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();
        authors.stream()
                // 获取书籍的流
                .flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream())
                .forEach(book -> System.out.println(book.getName()));

        authors.stream()
                // 一个作者搞成两个
                .flatMap((Function<Author, Stream<Author>>) author -> Stream.of(new Author[]{author, author}))
                .forEach(author -> System.out.println(author.getName()));
    }
}

终结操作

不返回流对象的方法,必须调用终结操作,中间操作才会执行

  • forEach
  • count
  • min/max
public class StreamDemo04 {

    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();
        // 计数
        System.out.println(authors.stream().count());

        // 最大年龄
        System.out.println(authors.stream().max(Comparator.comparingInt(Author::getAge)).get().getAge());

        // 最小年龄
        System.out.println(authors.stream().min(Comparator.comparingInt(Author::getAge)).get().getAge());
    }
}
  • collect 把当前流转成集合
public class StreamDemo05 {

    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();

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

        // collect 转回set
        Set<String> set = authors.stream().map(author -> author.getName()).collect(Collectors.toSet());
        System.out.println(set);

        // collect 转回map
        Map<String, Integer> map = authors.stream().collect(Collectors.toMap(author -> author.getName(), author -> author.getAge()));
        System.out.println(map);
    }
}
  • anyMatch
  • allMatch
  • noneMatch
public class StreamDemo06 {

    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();

        // 集合中匹配任何一个都返回true
        boolean anyMatch = authors.stream().anyMatch(author -> author.getAge() > 10);
        System.out.println(anyMatch);

        // 集合中全部匹配才返回true
        boolean allMatch = authors.stream().allMatch(author -> author.getAge() > 30);
        System.out.println(allMatch);

        // 集合中全部不匹配才返回true
        boolean noneMatch = authors.stream().noneMatch(author -> author.getAge() > 130);
        System.out.println(noneMatch);
    }
}
  • findAny
  • findFirst
public class StreamDemo07 {
    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();

        // 返回集合中的一个
        Optional<Author> any = authors.stream().findAny();
        any.ifPresent(author -> System.out.println(author.getName()));

        // 查找第一个
        authors.stream().findFirst().ifPresent(author -> System.out.println(author.getName()));
    }
}
  • reduce
public class StreamDemo08 {
    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();

        // reduce 示例 查找年龄最大的
        authors.stream().reduce((author, author2) -> author.getAge() > author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));

        // reduce 示例 查找年龄最小的
        authors.stream().reduce((author, author2) -> author.getAge() < author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));

        // reduce 示例 计算年龄合计
        System.out.println(authors.stream().map(author -> author.getAge()).reduce(0, (result, age) -> result + age));

        System.out.println(authors.stream().reduce(new Author(0, 0, "", null), (author, author2) -> {
            author.setAge(author.getAge() + author2.getAge());
            return author;
        }).getAge());
    }
}

并行流

public class StreamDemo09 {
    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();

        // 创建并行流1 stream().parallel()
        authors.stream().parallel().reduce((author, author2) -> author.getAge() > author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));

        // 创建并行流2 parallelStream()
        authors.parallelStream().reduce((author, author2) -> author.getAge() < author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));

    }
}

Optional

创建对象

public class OptionalDemo01 {
    public static void main(String[] args) {
        Author author = new Author();
        // ofNullable 可以为空
        Optional<Author> authorOptional1 = Optional.ofNullable(author);

        // of 不能为空,将报空指针
        Optional<Author> authorOptional2 = Optional.of(author);

        // empty 创建一个空对象的
        Optional<Object> empty = Optional.empty();
    }
}

获取值

public class OptionalDemo02 {
    public static void main(String[] args) {
        Author authorNull = null;
        Author author = new Author(1, 28, "东山", null);

        Optional<Author> authorNullOptional = Optional.ofNullable(authorNull);
        Optional<Author> authorOptional = Optional.ofNullable(author);

        // get
        // 东山
        System.out.println(authorOptional.get().getName());

        // orElseGet 为空将返回默认值 否则使用原值
        // 默认
        System.out.println(authorNullOptional.orElseGet(() -> new Author(0, 0, "默认", null)).getName());
        // 东山
        System.out.println(authorOptional.orElseGet(() -> new Author(0, 0, "默认", null)).getName());

        // orElseThrow 为空抛出异常
        authorNullOptional.orElseThrow(() -> new RuntimeException("数据不能为空")) ;
    }
}

过滤&判断&数据转换

public class OptionalDemo03 {
    public static void main(String[] args) {
        Author author = new Author(1, 28, "东山", null);

        Optional<Author> authorOptional = Optional.ofNullable(author);

        // filter 过滤 // 没得打印
        authorOptional.filter(author1 -> author1.getAge() > 28).ifPresent(author12 -> System.out.println(author12.getName()));

        // filter 过滤  // 打印东山
        authorOptional.filter(author1 -> author1.getAge() > 18).ifPresent(author12 -> System.out.println(author12.getName()));

        // isPresent 判断 // 打印东山
        if (authorOptional.isPresent()) {
            System.out.println(authorOptional.get().getName());
        }

        // map 数据转换 转成年龄 // 打印28
        System.out.println(authorOptional.map(author13 -> author13.getAge()).get());
    }
}

函数式接口

只有一个抽象方法的接口
一般加上@FunctionalInterface,不加该注解,也可以是函数式接口

常用接口

Consumer 消费接口
Function 转换接口
Predicate 判断接口
Supplier 生产接口

默认方法

public class FunctionDemo01 {
    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();
        // and
        authors.stream().filter(((Predicate<Author>) author -> author.getAge() > 11).and(author -> author.getAge() < 33)).forEach(author -> System.out.println(author.getName()));
        System.out.println("------------------------");
        // or
        authors.stream().filter(((Predicate<Author>) author -> author.getAge() > 11).or(author -> author.getAge() < 33)).forEach(author -> System.out.println(author.getName()));
        System.out.println("------------------------");
        // negate
        authors.stream().filter(((Predicate<Author>) author -> author.getAge() > 33).negate()).forEach(author -> System.out.println(author.getName()));
    }
}

方法引用

当我们使用lambda时,当方法体中只有一个方法调用的话,我们可以用方法引用进一步简化代码

  • 当我们写完lambda代码后,发现方法体中只有一个方法调用的话,再使用idea提供的快捷键来尝试方法引用
  • 用法:类名或对象名::方法名

示例

  • 引用类的静态方法
  • 引用对象的实例方法
  • 引用类的实例方法
public class FunctionDemo02 {
    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();
        final StringBuilder sb = new StringBuilder() ;
        // lambda 写法
        authors.stream().map(author -> author.getAge()).map(integer -> String.valueOf(integer)).forEach(s -> sb.append(s));
        System.out.println(sb.toString());

        final StringBuilder sb1 = new StringBuilder() ;
        // 方法引用写法
        // 引用类的实例方法 Author::getAge 满足方法体重只有一个方法调用,并且是第一个参数的实例方法,并且该方法按照顺序传入的抽象方法中的剩余参数(此处没有剩余参数)
        // 引用类的静态方法 String::valueOf 满足方法体中只有一个方法调用,并且是静态方法,抽象方法所有参数按照顺序传入静态方法
        // 引用对象的实例方法 sb::append 满足方法体中只有一个方法调用,并且是对象的实例方法,抽象方法所有参数按照顺序传入实例方法
        authors.stream().map(Author::getAge).map(String::valueOf).forEach(sb1::append);
        System.out.println(sb1.toString());
    }
}
  • 构造器引用
public class FunctionDemo03 {
    public static void main(String[] args) {
        List<Author> authors = MyUtil.getAuthorList();
        // lambda 写法
        authors.stream().map(author -> author.getName()).map(name -> new String(name)) ;

        // 方法引用写法
        // 构造器引用 String::new 满足方法体只有一个构造方法调用,并且抽象方法的所有参数都按照顺序传入该方法
        authors.stream().map(Author::getName).map(String::new) ;
    }
}

你可能感兴趣的:(java,java)