前置概念了解
-
函数式接口(Functional Interface):有且仅有一个抽象方法。(SAM,single abstract method,单一抽象方法)
-
接口中可以添加
default
关键字修饰的非抽象方法(默认方法)。 -
接口里可以声明静态方法,并且可以实现。
-
如果接口重写了
java.lang.Object
类中的public方法,也能满足规则,并不会增加抽象方法个数。 -
只要满足函数式接口的规则,即使不加
@FunctionalInterface
注解也是一个函数式接口。(如果加了注解但不满足规则,则会报错) -
函数式接口的实例可以通过Lambda表达式、方法引用,构造方法引用来创建。
-
Lambda简化了语法,并为代码编译提供了类型推断。
-
Java中,Lambda表达式是对象,依附于函数式接口。
入门案例1
遍历
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
// 外部迭代
for (Integer num : list) {
System.out.print(num);
}
// 内部迭代
list.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.print(integer);
}
});
// lambda表达式
list.forEach(i -> System.out.print(i));
// 方法引用 method reference
list.forEach(System.out::print);
forEach
Iterable<T>
接口中的默认方法:
对这个接口的每个元素执行给定的操作,直到所有的元素都被处理完毕,或者说操作抛出了一个异常。
如果没有被实现类所指定的话,动作会被按照迭代的顺序来执行。
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
Consumer<T>
接收单个输入参数,不返回结果。
参数为操作输入的类型。
具有副作用,可能修改接收的单个参数。
@FunctionalInterface
public interface Consumer<T> {
/**
* 对于给定的参数执行操作
*/
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
入门案例2
应用于线程
new Thread(() -> System.out.println("hi")).start();
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
入门案例3
将字符串集合转换成大写
List<String> words = Arrays.asList("orcas", "fish", "future");
words.stream().map(e -> e.toUpperCase()).forEach(e -> System.out.println(e));
// 方法引用
words.stream().map(String::toUpperCase).forEach(System.out::println);
public interface Collection<E> extends Iterable<E> {
....
/**
* 返回一个串行流,目标数据(当前集合)作为元
* 分割迭代器对流所对应的数据进行分割
* parallel: false
*/
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
...
}
public interface Stream<T> extends BaseStream<T, Stream<T>> {
...
/**
* 返回一个新的流, 由给定的Function应用于该流的元素所得到的结果组成
* 是一个中间操作
*
* @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
void forEach(Consumer<? super T> action);
...
}
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
...
}
入门案例4
排序
List<String> words = Arrays.asList("orcas", "fish", "future", "wait");
Collections.sort(words, (o1, o2) -> o2.compareTo(o1));
System.out.println(words);