1.Lambda表达式
是特殊的匿名内部类,方法更加简介,可以将函数作为方法的参数
注意:Lamdba表达式只能用于简化函数式接口的匿名内部类,并不是所有的匿名内部类
函数式接口:接口中只有一个抽象方法 。
lambad只能简化匿名内部类中的函数式接口。
使用@Functionalinterface修饰的接口就为函数式接口
(参数1,参数2...):抽象方法的参数
->:分隔符
{}:抽象方法的实现
1.无参无返回值的lambda表达式
案例:
public class Text02 {
public static void main(String[] args) {
run(new Swim() {
@Override
public void swimming() {
System.out.println("狗油的飞快");
}
});
//简化
run(()->{
System.out.println("狗油的飞快");
});
//再简化
run(()-> System.out.println("狗游的飞快"));
}
public static void run(Swim swim){
swim.swimming();
}
}
//函数式接口
interface Swim{
void swimming();
}
2.有参有返回值
class Person{
private String name;
private int age;
private int height;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Person(String name, int age, int height) {
this.name = name;
this.age = age;
this.height = height;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
public class Text03 {
public static void main(String[] args) {
ArrayList<Person> persons = new ArrayList<>();
persons.add(new Person("张三",20,170));
persons.add(new Person("李四",24,173));
persons.add(new Person("马五",23,175));
persons.add(new Person("赵六",22,180));
//对集合中元素排序,按照年龄升序
//使用比较器,自定义规则
/*Collections.sort(persons, new Comparator<Person>() {
//int 表示新加元素和集合中原来元素对比
//正整数 1 o1比o2大
//负整数 -1 o1比o2小
//相等 o1=o2
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});*/
//简化 参数的类型会自动推算 如果执行语句只有一句,且无返回值,{}可以省略,若有返回值,若想省去{},则必须同时省略return,且执行语句也保证只有一句
Collections.sort(persons,(o1,o2)-> o1.getAge()-o2.getAge());
for (Person person : persons) {
System.out.println(person);
}
}
}
输出结果:
-形参列表的数据类型会自动推断
-如果形参列表为空,只需保留()
-如果形参只有一个,()可以省略,只需要参数的名称即可
-如果执行语句只有一句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有一句
-lambda不会生成一个单独的内部类文件
3.内置函数式接口的由来
public class Text04 {
public static void main(String[] args) {
run(new Summation() {
@Override
public void getsum(int[] arr) {
int sum=0;
for (int i : arr) {
sum+=i;
}
System.out.println(sum);
}
});
}
public static void run(Summation summation){
int [] arr={2,4,6,8,10};
summation.getsum(arr);
}
}
interface Summation{
void getsum(int[] arr);
}
我们知道使用Lambda表达式的前提是具有函数式接口,而Lambda使用时不关心接口名。抽象方法名,只关心抽象方法的参数列表和返回值类型,因此为了让我们使用Lambda方便,JDK提供了大量常用的函数式接口。
4.常用的函数式接口:
在java.util.function
4.1消费型接口
有参数、无返回值
public class Text05 {
public static void main(String[] args) {
/*fun(new Consumer() {
@Override
public void accept(Object o) {
System.out.println("洗脚花费了"+o);
}
},200.00);*/
//简化
fun(o-> System.out.println("洗脚花费了"+o),200.00);
}
//调用某个方法时,该方法需要的参数为接口类型,这时就应该想到lambda
public static void fun(Consumer consumer, Double money) {
consumer.accept(money);
}
}
4.2供给型接口
无参数,有返回值
public class Text05 {
public static void main(String[] args) {
// fun(new Supplier() {
// @Override
// public Object get() {
// return "sadasd";
// }
// });
//简化
fun(()->"返回了一个hhhh");
}
public static void fun(Supplier supplier) {
Object o = supplier.get();
System.out.println(o);
}
}
4.3函数型接口
T:参数类型的泛型
R:函数返回结果的泛型
有参,有返回值时
public static void main(String[] args) {
//输出字符串返回长度
/*fun(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
},"hello word");*/
//简化
fun(o-> o.length(),"hello word");
}
//调用某个方法时,该方法需要的参数为接口类型,这时就应该想到lambda
public static void fun(Function<String,Integer> function,String msg) {
Integer apply = function.apply(msg);
System.out.println("结果为"+apply);
}
}
4.4断言型接口
T:参数的泛型
当传入一个参数时,需要对该参数进行判断时,则需要这种函数。
public static void main(String[] args) {
/*fun(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length()>5;
}
},"hello word");*/
//简化
fun(o->o.length()>5,"hello word");
}
public static void fun(Predicate<String> predicate, String msg){
boolean test = predicate.test(msg);
System.out.println("输入的长度是否大于5:"+test);
}
}