2020你还不会Java8新特性? (2)

在将函数座位一等公民的语言中,lambda表达式的类型是函数。但是在Java中,lambda表达式是对象,他们必须依附于一类特别的对象类型-函数式接口(function interface)

迭代的方式:

外部迭代:

内部迭代:

方法引用:

list.forEach(System.out::println);

接口中可以有默认方法和静态方法。

流: stream

/** * Returns a sequential {@code Stream} with this collection as its source. * * <p>This method should be overridden when the {@link #spliterator()} * method cannot return a spliterator that is {@code IMMUTABLE}, * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()} * for details.) * * @implSpec * The default implementation creates a sequential {@code Stream} from the * collection's {@code Spliterator}. * * @return a sequential {@code Stream} over the elements in this collection * @since 1.8 */ default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }

关于流方式实现的举例:

public static void main(String[] args) { //函数式接口的实现方式 MyInterface1 i1 = () -> {}; System.out.println(i1.getClass().getInterfaces()[0]); MyInterface2 i2 = () -> {}; System.out.println(i2.getClass().getInterfaces()[0]); // 没有上下文对象,一定会报错的. // () -> {}; //通过lambda来实现一个线程. new Thread(() -> System.out.println("hello world")).start(); //有一个list ,将内容中的首字母变大写输出. List<String> list = Arrays.asList("hello","world","hello world"); //通过lambda来实现所有字母编程大写输出. // list.forEach(item -> System.out.println(item.toUpperCase())); //把三个单词放入到新的集合里边. List<String> list1 = new ArrayList<>(); //diamond语法. 后边的<>不用再放类型 // list.forEach(item -> list1.add(item.toUpperCase())); // list1.forEach(System.out::println); //进一步的改进. 流的方式 // list.stream();//单线程 // list.parallelStream(); //多线程 list.stream().map(item -> item.toUpperCase()).forEach(System.out::println);//单线程 list.stream().map(String::toUpperCase).forEach(System.out::println); //上边的两种方法,都满足函数式接口的方式. }

lambda表达式的作

传递行为,而不仅仅是值

提升抽象层次

API重用性更好

更加灵活

lambda基本语法

(argument) -> (body)

如: (arg1,arg2...) -> (body)

Java lambda结构

一个Lambda表达式可以有0个或者多个参数

参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a) 与 (a) 效果相同

所有参数包含在圆括号内,参数之间用逗号相隔。

空圆括号代表参数集为空。

当只有一个参数,且类型可推倒时。圆括号()可省略。

lambda表达式的主体可以包含0条或多条语句。

如果lambda表达式的主体只有一条语句,花括号{}可以省略,匿名函数的返回类型与该主体表达式一致。

如果lambda表达式的主体包含一条以上语句,则表达式必须包含在花括号中。匿名函数的韩绘制类型与代码块的返回类型一致,诺没有反回则为空。

高阶函数:
如果一个函数接收一个函数作为参数,或者返回一个函数作为返回值,那么该函数就叫做高阶函数.

传递行为的举例:

public static void main(String[] args) { // 函数的测试 // 传递行为的一种方式. FunctionTest functionTest = new FunctionTest(); int compute = functionTest.compute(1, value -> 2 * value); System.out.println(compute); System.out.println(functionTest.compute(2,value -> 5+ value)); System.out.println(functionTest.compute(3,a -> a * a)); System.out.println(functionTest.convert(5, a -> a + "hello ")); /** * 高阶函数: * 如果一个函数接收一个函数作为参数,或者返回一个函数作为返回值,那么该函数就叫做高阶函数. */ } //使用lambda表达式的话,可以直觉预定义行为.用的时候传递. // 即 函数式编程. public int compute(int a, Function<Integer, Integer> function) { return function.apply(a); } public String convert(int a, Function<Integer, String> function) { return function.apply(a); } // 之前完成行为的做法. 提前把行为定义好,用的时候调用方法. 如: public int method1(int a ){ return a * 2 ; }

Function类中提供的默认方法的讲解:

/** * Returns a composed function that first applies the {@code before} * function to its input, and then applies this function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. 返回一个组合的函数。对应用完参数后的结果,再次运行apply * * @param <V> the type of input to the {@code before} function, and to the * composed function * @param before the function to apply before this function is applied * @return a composed function that first applies the {@code before} * function and then applies this function * @throws NullPointerException if before is null * * @see #andThen(Function) */ default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } /** * Returns a composed function that first applies this function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of output of the {@code after} function, and of the * composed function * @param after the function to apply after this function is applied * @return a composed function that first applies this function and then * applies the {@code after} function * @throws NullPointerException if after is null * * @see #compose(Function) */ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); }

compose : 组合function, 形成两个function的串联。 先执行参数

andThen :先应用当前的函数apply,然后再当做参数再次执行apply。 后执行参数。

identity:输入什么返回什么。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwgpf.html