java8新特性- lambda

  1. idea创建一个普通的Java project

  2. 需要给该项目一个junit包,按照如下操作后就可以使用第三方的jar
    在这里插入图片描述
    lambda是一个匿名函数 ,可以更简洁的表示一个行为或者传递代码; 大家可以先看第4点,回头看再看3

  3. lambda的基础语法:
    语法 : (参数,参数) -> expression 或 (参数,参数) ->{ statements; }

    java8 的新操作符号,也叫lambda操作符,就是 ->
    箭头的左侧是 lambda的参数列表
    箭头的右侧是lambda需要执行的功能
    语法1: 无参无返回值:


    @Test
    public void test1(){
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello runnable");
            }
        });
        t.start();

        Thread t2 = new Thread(() -> System.out.println("hello lambda")) ;
        t2.start();
        
        Runnable r = ()->System.out.println("hello lambda  runnable");
        r.run();
    }
    语法2: 有参无返回值:  若这里的参数只有一个,则可以省略小括号 
 @Test
    public void test2(){
        Consumer consumer = (x)->System.out.println(x);
        consumer.accept("hello");
    }
   语法3:有参数有返回值:
 @Test
    public void test3(){
        Comparator<Integer> com = (a,b)->{
            System.out.println("...");
            return Integer.compare(a,b);
        };

        //若有只有一条语句,可以省略{} 和return  这种更推荐,
        Comparator<Integer> com1 =(a,b)->Integer.compare(a,b);

//        以上没有写类型是因为jvm 可以根据上下文推断出类型,其实也可以写
//        数据类型推断,例如数组赋值,int a[] = {12,3,6,8,3}; List<StuInfo> list = new ArrayList<>();
        Comparator<Integer> com2 =(Integer a,Integer b)->Integer.compare(a,b);

    }

lambda需要函数式接口:
函数时表达式: 接口类中只有一个抽象方法
如何验证是否是函数式接口 @FunctionalInterface

  1. 使用lambda表达的好处:
    假设需要分别输出计算机专业的信息,分别输出学生的年龄大于18的信息:
    按照之前学过的实现方式: 定义两个方法,分别实现,但是大家会发现只有if中的条件不同,其他都相同,代码冗余
 public List<StuInfo> selectProfessionals(List<StuInfo> stu){
        List<StuInfo> list = new ArrayList<>();
        for (StuInfo item:stu) {
            if (item.getStuProfessional().equals("计算机")){
                list.add(item);
            }
        }
        return list ;
    }
    public List<StuInfo> selectAge(List<StuInfo> stu){
        List<StuInfo> list = new ArrayList<>();
        for (StuInfo item:stu) {
            if (item.getStuAge()>=18){
                list.add(item);
            }
        }
        return list ;
    }
      List<StuInfo> list = Arrays.asList(
          new StuInfo(1,"王五","男",8,"计算机"),
          new StuInfo(2,"赵六","男",20,"心理学"),
          new StuInfo(3,"钱五","女",25,"数学"),
          new StuInfo(4,"孙家","女",18,"计算机"),
          new StuInfo(5,"里尔","男",22,"数学")
  );
    @Test
    public void test1(){
        List<StuInfo> professional = selectProfessionals(list);
        for (StuInfo  item : professional){
            System.out.println(item);
        }
        System.out.println("-----------------------------");
       List<StuInfo> ages = selectAge(list);
       for (StuInfo  item : ages){
           System.out.println(item);
       }

    }
public class StuInfo {
    private int stuId ;
    private String stuName ;
    private String stuSex;
    private int stuAge ;
    private String stuProfessional ;
   
   setter...getter...
   constructor 全参数和无参数的
   重写toString方法

方式二:可以定义接口,两个类实现接口,然后根据传入不同的实现类,返回不同的结果,也叫策略模式

public interface Performer<T> {

     public boolean isTrue(T t);

}

public class SelectAge implements  Performer<StuInfo> {

    @Override
    public boolean isTrue(StuInfo stuInfo) {
        if (stuInfo.getStuAge() >=18)
            return true ;
        return false;
    }
}

public class SelectProfessional implements  Performer<StuInfo> {

        @Override
        public boolean isTrue(StuInfo stuInfo) {
                if (stuInfo.getStuProfessional().equals("计算机"))
                      return true ;

                return false;
        }
}

 public List<StuInfo> shows (List<StuInfo > stus, Performer performer){
        List<StuInfo> list = new ArrayList<>();
        for (StuInfo item: stus ) {
            if (performer.isTrue(item)){
                list.add(item);
            }
        }
        return list ;
    }

     List<StuInfo> list = Arrays.asList(
          new StuInfo(1,"王五","男",8,"计算机"),
          new StuInfo(2,"赵六","男",20,"心理学"),
          new StuInfo(3,"钱五","女",25,"数学"),
          new StuInfo(4,"孙家","女",18,"计算机"),
          new StuInfo(5,"里尔","男",22,"数学")
  );
    @Test
    public void test2(){
        List<StuInfo> professional = shows(list,new SelectProfessional());
        for (StuInfo  item : professional){
            System.out.println(item);
        }
        System.out.println("---------------------------------");
        List<StuInfo> ages = shows(list,new SelectAge());
        for (StuInfo  item : ages){
            System.out.println(item);
        }

    }

方法三: 根据以上,可以使用匿名内部类实现,这样可以省略两个实现类

public interface Performer<T> {

     public boolean isTrue(T t);

}

  public List<StuInfo> shows (List<StuInfo > stus, Performer<StuInfo> performer){
        List<StuInfo> list = new ArrayList<>();
        for (StuInfo item: stus ) {
            if (performer.isTrue(item)){
                list.add(item);
            }
        }
        return list ;
    }

  List<StuInfo> list = Arrays.asList(
          new StuInfo(1,"王五","男",8,"计算机"),
          new StuInfo(2,"赵六","男",20,"心理学"),
          new StuInfo(3,"钱五","女",25,"数学"),
          new StuInfo(4,"孙家","女",18,"计算机"),
          new StuInfo(5,"里尔","男",22,"数学")
  );
@Test
    public void test3(){
        List<StuInfo> professional = shows(list, new Performer<StuInfo>() {
            @Override
            public boolean isTrue(StuInfo stuInfo) {
                return stuInfo.getStuAge()>22;
            }
        });

        for (StuInfo  item : professional){
            System.out.println(item);
        }
    }

方法四: lambda表达式,


public interface Performer<T> {

     public boolean isTrue(T t);

}

  public List<StuInfo> shows (List<StuInfo > stus, Performer<StuInfo> performer){
        List<StuInfo> list = new ArrayList<>();
        for (StuInfo item: stus ) {
            if (performer.isTrue(item)){
                list.add(item);
            }
        }
        return list ;
    }
  
    List<StuInfo> list = Arrays.asList(
          new StuInfo(1,"王五","男",8,"计算机"),
          new StuInfo(2,"赵六","男",20,"心理学"),
          new StuInfo(3,"钱五","女",25,"数学"),
          new StuInfo(4,"孙家","女",18,"计算机"),
          new StuInfo(5,"里尔","男",22,"数学")
  );
 @Test
    public void test4(){
        List<StuInfo> professional = shows(list,(e) -> e.getStuAge()>22 );

        professional.forEach(System.out::println);
    }

方法五:使用stream API

 List<StuInfo> list = Arrays.asList(
          new StuInfo(1,"王五","男",8,"计算机"),
          new StuInfo(2,"赵六","男",20,"心理学"),
          new StuInfo(3,"钱五","女",25,"数学"),
          new StuInfo(4,"孙家","女",18,"计算机"),
          new StuInfo(5,"里尔","男",22,"数学")
  );
      @Test
    public  void  test5(){
//        输出所有年龄大于22的学生信息
        list.stream().filter((e)->e.getStuAge()>22).forEach(System.out::println);
//       输出所有学生的姓名
        list.stream().map(StuInfo::getStuName).forEach(System.out::println);
    }
  1. 完成一个根据输入的数操作的案例
@FunctionalInterface
public interface Performer2<T> {

     public Integer getNum(Integer val);
}
public Integer getNums(Integer num ,Performer2 per){
       return  per.getNum(num );
    }

    @Test
    public void test4(){
        int res = getNums(200,(x)->x+x);
        int res1 = getNums(200,(x)->x*x);
        System.out.println(res);
        System.out.println(res1);
    }
  1. 对集合排序 (先专业,专业相同按年龄比)
    //对集合进行排序
    List<StuInfo> list = Arrays.asList(
            new StuInfo(1,"王五","男",58,"计算机"),
            new StuInfo(2,"赵六","男",20,"心理学"),
            new StuInfo(3,"钱五","女",25,"数学"),
            new StuInfo(4,"孙家","女",18,"计算机"),
            new StuInfo(5,"里尔","男",22,"数学")
    );

    @Test
    public void test5(){
        Collections.sort(list,(x,y)->{
            if(x.getStuProfessional().equals(y.getStuProfessional())){
//                return  Integer.compare(x.getStuAge(),y.getStuAge());  // 按照年龄从小到大排序
                return  -Integer.compare(x.getStuAge(),y.getStuAge());  // 按照年龄从大到小排序
            }else{
                return x.getStuProfessional().compareTo(y.getStuProfessional());
            }
        });

        for (StuInfo item : list){
            System.out.println(item);
        }
    }

8.定义一个接口,里面有一个抽象方法public String getValue(String str);
实现将给定字符串全部转换位大写

public interface Performer {

    public  String getValue(String str);
}
public class TestLamda {
    public String  aa ( String str , Performer per){
        return per.getValue(str);
    }

    @Test
    public void test01(){
        String str="hello";
       String bb =  aa(str, (x)-> x.toUpperCase());
        System.out.println("bb="+bb);
        String cc = aa(str,(x)->x.substring(2,4));
        System.out.println("cc="+cc);
    }
}
  1. 定义一个接口,传入两个泛型<T,R>, T是类型 R是返回值, 定义相应的抽象方法; 实现两个数的和
public interface Performer<T,R> {
    public R show(T t,T t1);
}

public class TestLamda {
    public Long  aa (Long a,Long b, Performer<Long,Long> per){
        return per.show(a,b);
    }

    @Test
    public void test01(){
        Long  value = aa(12l,14l,(x,y)-> x+y);
        System.out.println(value);
    }
}
  1. 四大内置函数式接口
    Consumer 消费型接口 void accept(T t)
    public void aa(int num , Consumer con){ con.accept(num)}
    public void test(){ aa(10),(x) ->System.out.println(“购买数量是:”+num) }
    Supplier 供给型接口 T get()
    public List aa (int num , Supplier sup){
    List list = new ArrayList<>();
    for (int i = 0 ; i < num ; i ++){
    list.add(sup.get())
    }
    return list ;
    }
    public void test(){ List list = aa(3, ()->(int)Math.Random()*10) ;}
    Function<T,R> 函数型接口 R apply(T t)
    public String aa(String str,Function<String,String> fun){
    return fun.apply(str);
    }

      public void test(){  String ss = aa("hello ",(x)->x.substring(2,4)) ; }
    

    Predicate 断言型接口 boolean test (T t)
    public boolean aa(List list , Predicate pre){
    List alsit = new ArrayList<>();
    for (String item :list){
    if(pre.test(item)){
    alist.add(item)
    }
    }
    return alist ;
    }
    public void test(){
    List list = Arrays.asList(“zhang”,“wang”,“li”,“he”);
    List blist = aa(list,(x)->x.length>2)
    }

    除了以上4中还有其对应的子类
    在这里插入图片描述

  2. 方法引用: lambda的另一种表示形式
    语法: 对象:: 实例方法名 【非static修饰的一般方法就是实例方法】
    以前:Comsumer con = (x)->System.out.println(x)
    现在:Consumer con = System.out:println;
    con.accept(“aaa”);

                             以前:StuInfo stu = new StuInfo()
                                       Supplier<String> con = ()->stu.getStuName()
                             现在: Supplier<String> con = stu::getStuName;
                                      String str = con.get();    
                     
                类::静态方法名
                            以前:Comparator<Integer> con = (x,y)->Integer.compare(x,y)
                             现在: Comparator<Integer> con = Integer::compare;
                                      
          以上 要求:调用的方法参数列表与返回值类型,要与函数式接口中的抽象方法的函数列表和返回值类型一致
                类::实例方法名
                             以前: BiPredicate<String ,String > bp = (x,y) ->x.equals(y);
                             现在: BiPredicate<String ,String > bp =String:equals;
                          要求: 若lambda参数列表中第一个参数式实例方法的调用者,而第二个参数式实例方法的参数,使用 **类名::方法名**
    
  3. 构造器引用: 类名::new
    需要调用的构造器参数列表要与函数式接口抽象方法的参数列表保持一致
    以下匹配无参数构造方法:
    Supplier stu = ()->new StuInfo();
    Supplier stu1 = StuInfo::new

             调用1个参数构造方法:
             Function<Integer,StuInfo> fun = (x)->new StuInfo()
             Function<Integer,StuInfo> fun1 = StuInfo::new 
             
             调用两个参数的构造方法
             BiFunction<Integer,Integer,StuInfo>  bifun = StuInfo::new ;
    
  4. 数组引用 数据类型[] :: new
    Function<Integer,String [] > fun= (x) -> new String[x];
    String ss []= fun.apply(10);

     Function<Integer,String[]> fun1 = String[]:: new 
      String ss1 []=  fun1.apply(10);
    

lambda表达式可以使代码看起来简洁,但一定程度上增加了代码的可读性以及调试的复杂性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值