1. lambda表达式中调用方法
使用 :: 关键字来传递方法(包括静态方法和非静态方法)
public class LambdaTest {
public static void main(String[] args) {
LambdaTest t = new LambdaTest();
//使用Lambda引用类的静态方法
//能引用Integer类中的静态方法toBinaryString的原因是:
//Action接口中只有一个方法且方法的参数类型和返回值类型
//与Integer类中的静态方法toBinaryString的参数类型、返回类型是一致的
Action a = Integer::toBinaryString;
System.out.println(a.run(4));
//使用Lambda引用对象的非静态方法
//能引用对象t中的非静态方法test的原因是和上面的描述是一致的
Action aa = t::test;
System.out.println(aa.run(4));
}
public String test(int i){
return "i="+i;
}
}
@FunctionalInterface
interface Action{
public String run(int Integer);
}
}
2. lambda表达式中的构造方法的访问
使用 :: 关键字来引用构造函数
public class LambdaTest1 {
public static void main(String[] args) {
//Lambda表达式引用构造函数
//根据构造器的参数来自动匹配使用哪一个构造器
Action1Creater creater = Action1::new;
Action1 a1 = creater.create("zhangsan");
a1.say();
}
}
class Action1{
private String name;
public Action1() {
}
public Action1(String name) {
this.name = name;
}
public void say(){
System.out.println("name = "+name);
}
}
interface Action1Creater{
public Action1 create(String name);
}
3. lambda访问变量
public class LambdaTest2 {
private static int j;
private int k;
public static void main(String[] args) {
LambdaTest2 t = new LambdaTest2();
t.test();
}
public void test(){
int num = 10;
j = 20;
k = 30;
//lambda表达式中可以访问成员变量也可以访问局部变量
Action2 a2 = (i)->System.out.println("操作后:i="+(i+num+j+k));
a5.run(1);
//但是这个被访问的变量默认变为final修饰的 不可再改变 否则编译不通过
//num = 60;
j = 50;
k = 70;
}
}
interface Action2{
public void run(int i);
}
4. Predicate接口
@Test
public void testPredicate() {
List<String> strings = Arrays.asList("Java", "Python", "Shell");
filter(strings,s->true);
}
public static void filter(List<String> list, java.util.function.Predicate<String> condition){
list.stream().filter(s -> condition.test(s)).forEach(s -> System.out.println(s));
}
5. Function接口
Function有一个参数并且返回一个结果,并附带了一些可以和其他函数组合的默认方法
compose方法表示在某个方法之前执行;andThen方法表示在某个方法之后执行
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
} 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}返回一个先执行before函数对象apply方法再执行当前函数对象apply方法的函数对象。
static <T> Function<T, T> identity() {
return t -> t;
}返回一个执行了apply()方法之后只会返回输入参数的函数对象。//传入什么则返回什么
6. Supplier 接口
Supplier接口返回一个任意范型的值,和Function接口不同的是该接口没有任何参数
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
@Test
public void testLambda() {
//生成一个八位的随机字符串
Supplier<String> f = ()->{
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 8; i++) {
//生成[0,base.length)之间的随机数
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
};
System.out.println(f.get());
}
7. Consumer接口
Consumer接口接收一个任意范型的值,和Function接口不同的是该接口没有任何值
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); };
}
}
public class testConsumer {
//静态内部类
private static class Student{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
Student s = new Student();
s.setName("tom");
Consumer<Student> c =
stu->System.out.println("hello!"+stu.getName());
c.accept(s);
}
}
8. 小结
Function<T, R> 接口 R apply(T t); 有参数有返回值
Supplier<T> 接口 T get(); 没参数有返回值
Consumer<T> 接口 void accept(T t); 有参数没返回值
其用法和上面介绍的接口使用方式类同
BinaryOperator<T>接口 T apply(T t, T t) 将两个T作为输入,返回一个T作为输出
BiFunction<T, U, R>接口 R apply(T t, U u) 将一个T和一个U输入,返回一个R作为输出
BinaryOperator接口继承了BiFunction接口
public interface BinaryOperator<T> extends BiFunction<T,T,T>
BiConsumer<T, U>接口 void accept(T t, U u) 将俩个参数传入,没有返回值