1 lambda表达式
Lambda
表达式本质是一个匿名函数,用于把函数作为参数,传入方法中,实现函数式编程风格。使用
Lambda
表达式可以使代码变的更加简洁紧凑。
语法格式:
(parameters)-> expression
或 (parameters)->{ statements;}
示例:
public class Demo01 {public static void main(String[] args) {Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("子线程1开始执行任务");}});t1.start();//lambda表达式写法Thread t2 = new Thread(()-> System.out.println("子线程2开始执行任务"));t2.start();}
}
使用匿名内部类
1.定义了一个没有名字的类
2.这个类实现了Runnable接口
3.重写了run方法,实例化这个匿名内部类对象
冗余
其实最关注的是run方法里面要执行的代码
lambda表达式体现的是函数式编程思想,只需要将需要执行的代码放到函数中
lambda表达式是一个匿名函数
public class Demo02 {public static void main(String[] args) {swim(new ISwim(){@Overridepublic void swimming() {System.out.println("Forg游泳");}});System.out.println("----------------------------");//lambda相当于对接口抽象方法的重写swim(()->System.out.println("Hello World"));}public static void swim(ISwim s) {System.out.println("进入swim方法中");s.swimming();System.out.println("结束swim方法");}
}//无参,无返回值
interface ISwim{void swimming();
}
lambda可以创建函数式接口
函数式接口:@FunctionalInterface
接口中的有且仅有一个抽象方法的接口,称为函数式接口(静态方法,默认方法,抽象方法只有一个)
语法格式:
接口名 对象名 = (参数类型1 参数名1,...参数类型n 参数名n) ->{方法体;}
参数类型n 参数名n:接口中抽象方法的参数项
->:表示连接操作
{}:存放重写的方法体内容,可以理解为对抽象方法的覆盖。
简写:
1.参数类型可以简写
2.小括号,当参数只有1个时,可以省略
3.{}、return:同时进行省略,方法体语句只有一条时
public class Demo03 {public static void main(String[] args) {List<Integer> list = Arrays.asList(2,6,4,7,5,1,9,0,8,3);
// list.sort(new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o1 - o2;
// }
// });//lambda表达式
// list.sort((Integer i1, Integer i2) ->{return i2-i1;});//删除了全部的参数类型
// list.sort((o1, o2) -> {return o1 - o2;});//删除了{} return ;list.sort((o1, o2) -> o1 - o2);System.out.println(list);}
}
2 函数式接口Functional Interface
只有一个抽象方法的接口(可以定义多个非抽象方法)。可以使用@FunctionalInterface
接口定义,强化语义规范。
函数式接口,也被称为SAM
接口(Single Abstract Method Interfaces
)
作用
基于函数式接口,可以使用Lambda
表达式进行实现,实现函数式编程。
目标:
- 了解内置函数式接口由来
- 了解常用内置函数式接口
常用内置函数式接口介绍
在 Java 8
中专门有一个包放函数式接口java.util.function
,该包下的所有接口都有 @FunctionalInterface
注解,提供函数式编程方式。下面是最常用的几个接口。
1 Supplier接口 -- 供给型接口
java.util.function.Supplier<T> 接口 - 方法没有参数,有返回值--供给型接口。
它意味着"供给" , 对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。
供给型接口,通过Supplier接口中的get方法可以得到一个值,无参有返回的接口。
public class Demo01 {public static void main(String[] args) {System.out.println("进入到了man方法");printMax(()->{System.out.println("进入到get方法中了");Integer[] arrays={1,2,3,4,5};Integer num=Collections.max(Arrays.asList(arrays));System.out.println("在get中找到最大值:"+num);return num;});int n=number(()->{Random random=new Random();int num;while(((num=random.nextInt(11,20)) & 1)!=0){}return num;});System.out.println("随机整数为:"+n);}public static void printMax(Supplier<Integer> supplier){System.out.println("进入到printMax方法中了");Integer max = supplier.get();System.out.println("printMax返回值为:"+max);}public static Integer number(Supplier<Integer> supplier){return supplier.get();}
}
2 Consumer接口 --消费型接口
java.util.function.Consumer<T> 接口则正好相反 --方法有参数,没有返回值,它不是生产一个数据,而是消费一个数据,其数据类型由泛型参数决定。 --消费型接口
Consumer消费型接口,可以拿到accept方法参数传递过来的数据进行处理, 有参无返回的接口。
public class Demo02 {public static void main(String[] args) {//转小写caseLetter(t-> System.out.println(t.toLowerCase()),"HelloWorld");//转大写caseLetter(t-> System.out.println(t.toUpperCase()),"HelloWorld");//先转小写,再转大写caseLetters(t-> System.out.println(t.toLowerCase()),t-> System.out.println(t.toUpperCase()),"HelloWorld");}public static void caseLetter(Consumer<String> consumer,String str){consumer.accept(str);}public static void caseLetters(Consumer<String> consumer1,Consumer<String> consumer2,String str){consumer1.andThen(consumer2).accept(str);}}
3 Function接口 --转换型接口
java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件, 后者称为后置条件。有参数有返回值。----- 此方法接收一个参数,加工处理成另一种,称为转换型接口
Function转换型接口,对apply方法传入的T类型数据进行处理,返回R类型的结果,有参有返回的接口。使用的场景 例如:将 String类型转换为 Integer类型。
public class Demo03 {public static void main(String[] args) {//1.获取字符串的长度Function<String, Integer> f = s -> s.length();test(f,"1234abc");//2.截取字符串的前三位,将其转换为数字test(string -> Integer.parseInt(string.substring(0,3)),"1234abc");//3.test(string -> string.length(),len->new int[len],"abcde");}public static void test(Function<String,Integer> function,String str) {Integer num = function.apply(str);System.out.println(num);}/*function1 获取字符串长度的方法function2 获取指定长度的int类型的数组*/public static void test(Function<String,Integer> function1,Function<Integer,int[]> function2,String str) {
// Integer num = function1.apply(str);
// int[] ints = function2.apply(num);
// System.out.println(num);
// System.out.println(Arrays.toString(ints));int[] arr=function1.andThen(function2).apply(str);System.out.println(Arrays.toString(arr));}
}
4 Predicate接口--断言型接口
有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用
java.util.function.Predicate<T> 接口。------接收一个参数,返回一个boolean类型的值,称为判断型接口
public class Demo04 {public static void main(String[] args) {int number=new Random().nextInt(200);//1.判断此数字是否大于等于100method(num->num>=100,number);//2.判断此数字是否为偶数method(num->(num&1)==0,number);method(num->num>=0,num->(num&1)==0,number);}public static void method(Predicate<Integer> predicate,Integer num) {boolean result = predicate.test(num);System.out.println("数字num:"+num+" 判断后的结果为:"+result);}public static void method(Predicate<Integer> predicate1,Predicate<Integer> predicate2,Integer num) {boolean result1 = predicate1.and(predicate2).test(num);System.out.println("数字num:"+num+" 是否大于100并且为偶数?"+result1);boolean result2 = predicate1.or(predicate2).test(num);System.out.println("数字num:"+num+" 是否大于100或者为偶数?"+result2);boolean result3 = predicate1.negate().test(num);System.out.println("数字num:"+num+" 是否不大于100?"+result3);boolean result4 = predicate2.negate().test(num);System.out.println("数字num:"+num+" 是否不为偶数?"+result4);}
}
5 Comparator接口--比较器接口
比较器接口,用于比较指定元素值的大小。Java
8版本中,添加了多个新的default
方法,用于比较器合并、反转等操作。
// 案例数据
List<String> langList = Arrays.asList("Basic", "QBasic","HTML", "c", "c++", "PowerBuilder", "go", "Visual Basic", "c#","java");// 按照ASCII码比较
Comparator<String> comparator1 = (s1, s2) -> {return s1.compareTo(s2);
};// 按照长度比较
Comparator<String> comparator2 = (s1, s2) -> {return s1.length() - s2.length();
};// 先比较长度,再比较ASCII码
Comparator<String> comparator3 = comparator2.thenComparing(comparator1);// 在comparator3的基础上,反转条件
Comparator<String> comparator4 = comparator2.reversed();// 按照指定Comparator,进行排序
langList.sort(comparator2);