Lambda表达式

Lambda表达式简介

什么是Lambda?
Lambda是JAVA 8添加的一个新的特性,Lambda就是一个匿名函数。

为什么要使用Lambda?
使用Lambda表达式可以对一个接口进行非常简洁的实现。

@FunctionalInterface
interface Comparator{
     int compare(int a, int a);
}

class MyComparator implements Comparator{
      public int compare(int a, int b){
           return a - b;
      }
}

public class Program{
    public static void main(String[] args){
             //1.使用接口实现类
             Comparator comparator = new MyComparator();
             
             //2.使用匿名内部类
              Comparator comparator1 = new MyComparator(){
                      public int compare(int a, int b){
                             return a - b;
                      }
              };
              
              //3.使用Lambda表达式来实现接口
              Comparator comparator2 = (a,b) -> a - b;
    }
}


Lambda对接口的要求?
虽然可以使用Lambda表达式对某些接口进行简单的实现,但是并不是所有的接口都可以用Lambda表达式来实现。要求接口中定义的必须要实现的抽象方法只能是一个。
注:在JAVA 8对接口加了一个新的特性:default。

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

Lambda基础语法

@FunctionalInterface
public interface LambdaNoneReturnNoneParameter{
        void test();
}

@FunctionalInterface
public interface LambdaNoneReturnSingleParameter{
        void test(int n);
}

@FunctionalInterface
public interface LambdaNoneReturnMutipleParameter{
        void test(int a, int b);
}

@FunctionalInterface
public interface LambdaSingleReturnNoneParameter{
        int test();
}

@FunctionalInterface
public interface LambdaSingleReturnSingleParameter{
        int  test(int a);
}

@FunctionalInterface
public interface LambdaSingleReturnMultipleParameter{
        int test(int a, int b);
}
public class Syntax1{
    public static void main(String[] args){
            //1.Lambda表达式的基础语法
            //Lambda是一个匿名函数
            // 参数列表    方法体
            
           // ():用来描述参数列表
           // {}:用来描述方法体
           // ->:Lambda运算符,读作goes to
           
           //无参无返回
           LambdaNoneReturnNoneParameter lambda1 = () -> {
                   System.out.println("hello world");
           };
           lambda1.test();
           
           //无返回值,单个参数
            LambdaNoneReturnSingleParameter lambda2 = (int a) -> {
                   System.out.println(a);
           };
           lambda2.test(10);
           
           //无返回值,多个参数
            LambdaNoneReturnMultipleParameter lambda3 = (int a, int b) -> {
                   System.out.println(a+b);
           };
           lambda3.test(10,20);
           
           //有返回值,无参数
            LambdaSingleReturnNoneParameter lambda4 = () -> {
                   System.out.println("lambda4")
                   return 100;
           };
           int ret = lambda4.test();
           System.out.println(ret);
           
           //有返回值,单个参数
            LambdaSingleReturnSingleParameter lambda5 = (int a) -> {
                   return a*2;
           };
           int ret2 = lambda5.test(10);
            System.out.println(ret2);
            
            //有返回值,多个参数
              LambdaSingleReturnMultiplrParameter lambda6 = (int a, int b) -> {
                   return a+b;
           };
           int ret3 = lambda6.test(20,30);
           System.out.println(ret3);
    }
}

Lambda语法精简

public class Syntax2{
    public static void main(String[] args){
         //语法精简
         //1.参数类型
         //由于在接口的抽象方法中,已经定义了参数的数量和类型,所以在Lambda表达式中,参数的类型可以省略
         //注:如果需要省略类型,则每一个参数的类型都要省略。千万不要出现省略一个参数类型,不省略一个参数类型
           LambdaNoneReturnMultipleParameter lambda1 = (a, b) -> {
                  System.out.println("hello world");
           };
           
           //2. 参数小括号
           //如果参数列表中,参数的数量只有一个,此时,小括号可以省略
          LambdaNoneReturnSingleParameter lambda12= a -> {
                  System.out.println("hello world");
           };
           
           //3. 方法打括号
           //如果方法体中只有一条语句,此时打括号可以省略
           LambdaNoneReturnSingleParameter lambda3 = a -> System.out.println("hello world");
    }
    
    //4.如果方法体中唯一的一条语句是一个返回语句,则在省略掉大括号的同时也必须省略掉return
    LambdaSingleReturnNoneParameter lambda4 = () -> 10;
    
    LambdaSingleReturnMultipleParameter lambda5 = (a, b) -> a + b;
}

Lambda语法进阶

public class Syntax3{
   public static void main(String[] args){
          //方法引用
          //可以快速的将一个Lambda表达式的实现指向一个已经实现的方法
          //语法:方法的隶属者::方法名
          //注:
          //1.参数数量和类型一定要和接口中定义的方法一致
          //2.返回值的类型一定要和接口中定义的方法一致
          LambdaSingleReturnSingleParameter lambda1 = a -> change(a);
          //方法引用:引用了change方法的实现
           LambdaSingleReturnSingleParameter lambda2 = Syntax3::change;
                 
   }
   
   private static int change(int a){
         return a*2;
   }
}

public class Person{
   public String name;
   public int age;
   
   public Person(){
       System.out.println("Person类的无参构造方法执行了");
   }
   
   public Person(String name, int age){
       this.name = name;
       this.age = age;
       System.out.println("Person类的有参构造方法执行了");
   }
   
   public String to String(){
      return "Person{"+
                 "name="+name+''\''+
                 ", age="+age+
                 '}';
   }
}

public class Syntax4{
     public static void main(String[] args){
           PersonCreater creater = () -> new Person();
           
           //构造方法的引用
           PersonCreater creater1 = Person::new;
           Person a = creater1.getPerson();
           
           PersonCreater2 creater2 = Person::new;
           Person b = creater2.getPerson("xiaoming", 10);
     }
}

//需求:
interface PersonCreater{
   Person getPerson();
}

interface PersonCreater{
   Person getPerson(String name, int age);
}

Lambda综合案例

public class Exercise1{
      //集合排序
      //ArrayList<>
      public static void main(String[] args){
           //需求:已知在一个ArrayList中有若干个Person对象,将这些Person对象按照年龄进行降序排序
           ArrayList<Person> list = new ArrayList<>();
           
           list.add(new Person("xiaoming",10));
           list.add(new Person("lilei",11));
           list.add(new Person("hanmeimei",12));
           list.add(new Person("lily",9));
           list.add(new Person("lucy",9));
           list.add(new Person("polly",3));
           list.add(new Person("uncle wang",40));
           
           //排序
           list.sort((o1,o2) -> o2.age - o1.age);
           System.out.println(list);
          

      }
}

public class Exercise2{
     public static void main(String[] args){
          //TreeSet自带排序使用Lambda表达式来实现Comparator接口,并实例化一个TreeSet对象,使用Comparator如果返回0,则默认这两个元素相同,就会去重
          
         // TreeSet<Person> set = new TreeSet<>((o1,o2)  -> o2.age-o1.age);
         TreeSet<Person> set = new TreeSet<>((o1,o2)  ->
               if(o1.age>=o2.age){
                   return -1;
               }else{
                   return 1;
               }
         });
          
          set.add(new Person("xiaoming",10));
           set.add(new Person("lilei",11));
           set.add(new Person("hanmeimei",12));
           set.add(new Person("lily",9));
           set.add(new Person("lucy",9));
           set.add(new Person("polly",3));
           set.add(new Person("uncle wang",40));
           
           System.out.println(set);
     }
}

public class Exercise3{
      public static void main(String[] args){
          //集合遍历
          ArrayList<Integer> list = new ArrayList<>();
          
          Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
          //将集合中的每一个元素都带入到方法accept中
         // list.forEach(System.out::println);
         
         //输出集合中所有的偶数
         list.forEach(ele -> {
             if(ele%2==0){
                  System.out.println(ele);
             }
         });
      }

}

public class Exercise4{
    public static void main(String[] args){
        //需求:删除集合中满足条件的元素
        ArrayList<Person> list = new ArrayList<>();
        
          list.add(new Person("xiaoming",10));
           list.add(new Person("lilei",11));
           list.add(new Person("hanmeimei",12));
           list.add(new Person("lily",9));
           list.add(new Person("lucy",9));
           list.add(new Person("polly",3));
           list.add(new Person("uncle wang",40));
           
           //删除集合中年龄大于10岁的元素
          /* ListIterator<Person> it = list.listIterator();
           while(it.hasNext()){
               Person ele = it.next();
               if(ele.age>10){
                 it.remove;
               }
           }*/
           
           //Lambda实现
           //将集合中的每一个元素都带入到test方法中,如果返回值是true,则删除这个元素
           list.removeIf(ele -> ele.age > 10);
           
           System.out.println(list);
    }
}

public class Exercise5{
     public static void main(String[] args){
         //需求:开辟一条线程,做一个数字的输出
         Thread = new Thread(() ->{
              for(int i=0;i<100;i++){
                  System.out.println(i);
              }
         });
         t.start();
     }
}

系统内置函数式接口

import java.util.function.*;

public class FunctionalInterface{
     public static void main(String[] args){
             //系统内置的一些函数式接口
             
             //Predicate<T>  :参数T  返回值boolean
             //IntePredicate:int -> boolean
             //LongPredicate:long -> boolean
             //DoublePredicate:double -> boolean
             
             //Consumer<T>:参数T  返回值void
             //IntConsumer:int -> void
             //LongConsumer:long -> void
             //DoubleConsumer: double -> void
             
             //Function<T,R>:参数T   返回值R
             //IntFunction<R>:int -> R
             //LongFunction<R>:long -> R
             //DoubleFunction<R>:double ->R
             //IntToLongFunction:int->long
             //IntToDoubleFunction:int -> double
             //LongToIntFunction: long -> int
             //LongToDoubleFunction:long -> double
             //DoubleToIntFucntion:double -> int
             //DoubleToLongFunction:double -> long
             
             //Supplier<T>:参数无  返回值T
             //UnaryOperator<T>:参数T  返回值T
             //BinaryOperator<T>:参数T,T  返回值T
             //BiFunction<T,U,R>:参数T,U 返回值R
             //BiPredicate<T,U>:参数T,U 返回值boolean
             //BiConsumer<T,U>:参数T,U 返回值void
             
     }
}

闭包问题

public class ClosureDemo{
    public static void main(String[] args){
           int n = getNumber().get(); //可以拿到返回值
           System.out.println(n);
    }
    
    private static Supplier<Integer> getNumber(){
          int num = 10;
          return () ->{   //引用了getNumber()里面的局部变量num,用这个方法把num这个变量包围起来,这就是闭包
                return num;  
          };
    }
}

//方法中的局部变量在这个方法执行之后就应该被销毁,但闭包会提升保卫变量的生命周期,num在getNumber()执行结束之后不会销毁,因为num在其他地方多了一个引用,所以不会销毁,这样就可以获取到某一个方法中的局部变量
public class ClosureDemo2{
    public static void main(String[] args){
        int a = 10;
        Consumer<Integer> c = ele -> {
           System.out.println(a); //变成a+1可以运行,变成a++会报错,就算在大括号下面写a++也会报错
        };
        c.accept(a);
    }

}
//Lambda表达式中如果想要引用某一个局部变量,首先要保证它必须是一个常量,虽然没有对a进行final修饰,但是在编译的时候还是会自动加上,所以a此时就是一个常量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值