Lamda表达式

Lamda表达式

1.什么是Lamda?

Lamda 是JAV 8 添加的一个新的特性,说白了Lamda 就是一个匿名函数。

为什么要使用Lamda?

使用Lamda表达式可以对一个接口实现非常简洁的实现。

比如说我们要实现一个比较大小的接口:

方式一:接口的实现类来完成此功能。
public class Program {
    public static void main(String[] args) {
        MyComparator myComparator = new MyComparator();
        myComparator.compar(4, 6);
    }
}
​
interface Comparator {
    int compar(int a, int b);
}
class MyComparator implements Comparator {
    @Override
    public int compar(int a,int b) {
        return a-b;
    }
}
​
​
方式二:匿名内部类
​
    public class Program {
    public static void main(String[] args) {
        Comparator comparator = new Comparator() {
            @Override
            public int compar(int a, int b) {
                return a-b;
            }
        };
         int compar = comparator.compar(4, 6);
         System.out.println(compar);
    }
}
​
interface Comparator {
    int compar(int a, int b);
}
​
方式三:Lamda 表达式
    
public class Program {
    public static void main(String[] args) {
        Comparator comparator =  (a,b)->a-b;
         int compar = comparator.compar(4, 6);
         System.out.println(compar);
    }
}
​
interface Comparator {
    int compar(int a, int b);
}

Lamda对接口的要求是什么?

虽然可以使用Lamda 表达式对某些接口进行简单的实现,但并不是所有的接口都可以用Lamda表达式来实现。要求接口中定义的必须是要实现的抽象方法只能是一个

*JAVA 8 对接口家里一个新的特性:default*

 

@FunctionalInterface修饰函数式接口的,接口中的抽象方法只有一个。

 

如果有多个抽象方法就会报错

 

2.Lamda基本语法

首先需要注意的是 Lamda 是一个匿名函数那么有以下几个关注点

  1. 参数列表名

  2. 方法体

  3. 返回值类型 (在Lamda 中返回值不用显示的写出)

  4. 方法名(匿名不用关注)

 

符号 含义
() 用来描述参数列表
{} 用来表示方法体
-> Lamda运算符 读作 goes to
1.无参无返回值
@FunctionalInterface
public interface LamdaNoneReturnNoneParamter {
    void test();
}
​
class imTest{
    public static void main(String[] args) {
        LamdaNoneReturnNoneParamter lamdaNoneReturnNoneParamter = ()->{
            System.out.print("无参无返回值");
        } ;
    }
}
​
2.无返回值单个参
@FunctionalInterface
public interface LamdaNoneReturnNoneParamter {
    void test(int i);
}
​
class imTest{
    public static void main(String[] args) {
        LamdaNoneReturnNoneParamter lamda1 = (int c)->{
            System.out.print(c);
            System.out.print("无返回值单个参");
        } ;
        lamda1.test(10);
    }
}
​
3.无返回值多个参
@FunctionalInterface
public interface LamdaNoneReturnMutipleParamter {
    void test(int a, int b);
}
​
class imTest3{
    public static void main(String[] args) {
        LamdaNoneReturnMutipleParamter lamda3 = (int c,int d)->{
            System.out.println(c+"--------"+d);
            System.out.println("无返回值多个参");
        };
        lamda3.test(11, 33);
    }
}
​
4.有返回值没有参
@FunctionalInterface
public interface LamdaSingleReturnNoneParam {
    int test(); 
}
class imTest4{
    public static void main(String[] args) {
        LamdaSingleReturnNoneParam lamda4 = ()->{
            System.out.println("有返回值没有参");
            return 10;
        };
        int demo = lamda4.test();
        System.out.println(demo);
    }
}
5.有返回值单个参数
​
@FunctionalInterface
public interface LamdaSingleReturnSingleParamter {
    int test(int d);
}
​
class imTest5{
    public static void main(String[] args) {
        LamdaSingleReturnSingleParamter lamda5 = (int a)->{
            System.out.println("有返回值单个参数");
            return a*10;
        };
        int demo = lamda5.test(10);
        System.out.println(demo);
    }
}
6.有返回值多个参数
​
@FunctionalInterface
public interface LamdaSingleReturnMultipleParamter {
    int test(int a, int b, int c);
}
​
class imTest6{
    public static void main(String[] args) {
        LamdaSingleReturnMultipleParamter lamda6 = (int a,int b,int c)->{
            System.out.println("有返回值单个参数");
            return a*b*c;
        };
        int demo = lamda6.test(10,2,3);
        System.out.println(demo);
    }
}

3.Lamda语法精简

  1. 由于在接口的抽象方法中,已经定义了参数的数量和类型,所以 可以将参数的类型可以省略(如果需要省略参数类型,则每个参数的类型都要省略)。

  2. 如果参数列表中,参数的数量只有一个,此时小括号可以省略。

  3. 方法大括号:如果方法体中只有一条语句时,大括号可以省略。

  4. 如果方法体中唯一的一条语句是一个返回语句,return也可以省略。

4.语法进阶

方法引用:可以快速的将一个Lamda表达式的实现指向一个已经实现的方法。

语法:方法的隶属者::方法名,需要注意参数类型和类型一定要和接口一致。

@FunctionalInterface
public interface LamdaSingleReturnSingleParamter {
    int test(int d);
}
​
import faces.LamdaSingleReturnSingleParamter;
​
class Syntax2 {
    public static void main(String[] args) {
        LamdaSingleReturnSingleParamter lamda = a -> change(a);
        //简化为:
        LamdaSingleReturnSingleParamter lamda2 = Syntax2::change;
    }
​
    private static int change(int a) {
        return a * 2;
    }
}

构造方法的引用:

无参
class syntax3 {
    public static void main(String[] args) {
        PersonCreate person =  ()-> new Person("zs","ls");
        System.out.println(person);
​
        //构造函数的引用
        PersonCreate person2 =  Person::new;
        Person  zs  = person2.getPerson();
        System.out.println(zs);
​
    }
​
​
}
 interface PersonCreate {
     Person getPerson();
 }
​
有参
    class syntax3 {
    public static void main(String[] args) {
​
        //构造函数的引用
        PersonCreate person2 =  Person::new;
        Person  zs  = person2.getPerson("zs","ls");
        System.out.println(zs);
​
    }
​
​
}
 interface PersonCreate {
     Person getPerson(String name,String sex);
 }

综合练习:

package syntax;
​
import java.util.ArrayList;
​
class syntax3 {
    public static void main(String[] args) {
        ArrayList<Person> personList = new ArrayList<>();
        personList.add(new Person("zs",12 ));
        personList.add(new Person("we",142 ));
        personList.add(new Person("ee",52 ));
        personList.add(new Person("ww",3 ));
        personList.add(new Person("ee",122 ));
        personList.add(new Person("qew",2 ));
        personList.add(new Person("ss",7 ));
        personList.sort((o1,o2)->o2.age-o1.age);
        System.out.println(personList);
    }
​
}
​

 

换成TreeSet

package syntax;
​
import java.util.TreeSet;
​
class syntax3 {
    public static void main(String[] args) {
        TreeSet<Person> set = new TreeSet<>();
        set.add(new Person("zs",12 ));
        set.add(new Person("we",142 ));
        set.add(new Person("ee",52 ));
        set.add(new Person("ww",3 ));
        set.add(new Person("ee",122 ));
        set.add(new Person("qew",2 ));
        set.add(new Person("ss",7 ));
        System.out.println(set);
    }
}
​

 

 

person对象不能转型为Comparable ,因为set集合是自带排序,但是如果是person对象的话,就无法判断其大小,

 

根据源码可知,需要有一个Comparator 对象的实现类来提供对象的比较规则。因此代码如下:

package syntax;
​
import java.util.TreeSet;
​
class syntax3 {
    public static void main(String[] args) {
        TreeSet<Person> set = new TreeSet<>((o1,o2)->o1.age-o2.age);
        set.add(new Person("zs",12 ));
        set.add(new Person("we",142 ));
        set.add(new Person("ee",52 ));
        set.add(new Person("ww",3 ));
        set.add(new Person("ee",122 ));
        set.add(new Person("qew",2 ));
        set.add(new Person("ss",7 ));
        System.out.println(set);
    }
}

 

集合遍历实现:

 

package syntax;
​
import java.util.ArrayList;
import java.util.Collections;
​
class syntax3 {
    public static void main(String[] args) {
        ArrayList<Integer> arry = new ArrayList<>();
        Collections.addAll(arry, 1,3,2,4,5,6,8,7,9,10);
        arry.forEach(element ->{
            if(element % 2 ==0) {
                System.out.println(element);
            }
        });
    }
}

 

实现判断删除

package syntax;
​
import java.util.ArrayList;
import java.util.ListIterator;
​
class syntax3 {
    public static void main(String[] args) {
        ArrayList<Person> personList = new ArrayList<>();
        personList.add(new Person("zs",12 ));
        personList.add(new Person("we",142 ));
        personList.add(new Person("ee",52 ));
        personList.add(new Person("ww",3 ));
        personList.add(new Person("ee",122 ));
        personList.add(new Person("qew",2 ));
        personList.add(new Person("ss",7 ));
        ListIterator<Person> iterator  = personList.listIterator();
        while (iterator.hasNext()) {
            Person person = (Person) iterator.next();
            if(person.age > 10) {
                iterator.remove();
            }
            
        }
        System.out.println(personList);
    }
​
}

 

使用Lamda 表达式实现

 

 

package syntax;
​
import java.util.ArrayList;
​
​
class syntax3 {
    public static void main(String[] args) {
        ArrayList<Person> personList = new ArrayList<>();
        personList.add(new Person("zs",12 ));
        personList.add(new Person("we",142 ));
        personList.add(new Person("ee",52 ));
        personList.add(new Person("ww",3 ));
        personList.add(new Person("ee",122 ));
        personList.add(new Person("qew",2 ));
        personList.add(new Person("ss",7 ));
        
        //将集合中的每个元素都带入到test方法中进行比较,如果返回true 则删除这个元素。
        personList.removeIf(element -> {
            if(element.age % 2== 0) {
                return true;
            }
            return false;
        });
        System.out.println(personList);
    }
​
}

 

 

使用lamda 实例化线程对象

 

5.Lamda系统内置

package syntax;
​
​
public class syntax3 {
    public static void main(String[] args) {
        //需求:实现runable 接口开启一个线程,做一个数字输出
        Thread thread = new Thread(()->{
            int i = 0;
            do {
                System.out.println(i++);
            } while (i<=10);
        });
        thread.start();
    }
​
}

 

6.系统内置的函数式接口

在java.util.function下面的所有接口都是系统内置的函数式接口

 

  • Predicate<T> 参数 : T 返回值 :boolean

实体 参数 返回值
IntPredicate int boolean
LongPredicate long boolean
DoublePredicate double boolean
  • Consumer<T>参数 : T 返回值 :void

实体 参数 返回值
IntConsumer Int void
LongConsumer Long void
DoubleConsumer Double void
  • Supplier<T> 参数 : 无 返回值 :T

  • UnaryOperator<T> 参数 : T返回值 :T

省略。。。。。。

7.闭包

 

package syntax;
​
import java.util.function.Supplier;
​
public class syntax3 {
    public static void main(String[] args) {
         Integer num = getNum().get();
         System.out.println(num);
    }
​
    private static Supplier<Integer> getNum() {
        int num = 10;
        return ()->{
            return num;
        };
    }
​
} 

//10

上一篇:Java8新特性之Stream--Stream方法


下一篇:Java8新特性Stream详细教程