zoukankan      html  css  js  c++  java
  • Java的Lambda表达式

    Java的Lambda表达式

    1. 什么是Lambda表达式

    简单的说,Lambda表达式就是匿名方法。Lambda表达式让程序员能够使用更加简洁的代码,但是同样也使代码的可读性比较差。

    Lambda表达式也叫做匿名方法或者闭包。

    2. 和匿名内部类做对比

    Lambda是匿名方法,这个时候我们会想想到匿名内部类,我们来回想一下匿名内部类的用法,比如下面的代码就是使用匿名内部类实现了一个线程。

    public class Test {
      public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
          @Override
          public void run() {
            System.out.println("线程:" + Thread.currentThread().getName());
          }
        });
        t.start();
      }
    }
    

    我们一般的做法是写一个Runnable接口的实现类,然后new一个实现类再传给Thread的构造器。如下:

    public class Test {
    
      public static void main(String[] args) {
        MyThread myThread = new MyThread();
        Thread t = new Thread(myThread);
        t.start();
      }
    
      static class MyThread implements Runnable {
        @Override
        public void run() {
          System.out.println("线程:" + Thread.currentThread().getName());
        }
      }
      
    }
    

    可以看到使用匿名内部类的话就省略了新建Runnable接口的实现类这一步骤。

    3. 使用Lambda表达式

    上面使用匿名内部类的写法,如果使用Lambda表达式可以写成下面这样:

    public class Test {
      public static void main(String[] args) {
        Thread t = new Thread(() ->  {
          System.out.println("线程:" + Thread.currentThread().getName());
        });
        t.start();
      }
    }
    

    这样有一个问题,如果接口里面有多个方法,那么Lambda表达式怎么知道实现的是哪个方法呢?我们通过代码测试一下:

    package com.wangjun.othersOfJava;
    
    public class LambdaTest {
    
    	public static void main(String[] args) {
    		Animal a = () -> {  // 编译报错:The target type of this expression must be a functional interface
    			System.out.println("狗狗吃饭");
    		};
    		a.eat();
    	}
    	interface Animal {
    		public void eat();
    		public void duty();
    	}
    }
    

    可以看到编译报错,这个提到一个functional interface,就是函数式接口。函数式接口就是只有一个抽象方法的接口。这样,就不难理解了,原来Lambda表达式只支持函数式接口。

    4. Lambda表达式使用的几种方式

    package com.wangjun.othersOfJava;
    
    public class LambdaTest {
    	
    	public static void main(String[] args) {
    		
    		// 带类型
    		Animal a1 = (String str) -> {
    			System.out.println("狗狗吃饭:" + str);
    		};
    		// 不带类型
    		Animal a2 = (str) -> {
    			System.out.println("狗狗吃饭:" + str);
    		};
    		// 不带括号
    		Animal a3 = str -> {
    			System.out.println("狗狗吃饭:" + str);
    		};
    		// 不带大括号
    		Animal a4 = str -> System.out.println("狗狗吃饭:" + str);
    		a1.eat("火腿肠");
    		a2.eat("牛肉");
    		a3.eat("面条");
    		a4.eat("米饭");
    		
    		// 使用return返回
    		Person p1 = () -> {
    			return "老师的职责:教书育人!";
    		};
    		// 直接返回
    		Person p2 = () -> "医生的职责:救死扶伤!";
    		System.out.println(p1.duty());
    		System.out.println(p2.duty());
    	}
    	
    	// 没有返回值
    	interface Animal {
    		public void eat(String str);
    	}
    	// 有返回值
    	interface Person {
    		public String duty();
    	}
    }
    

    4. Java的双冒号表达式

    JDK8中有双冒号的用法,就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下。下面通过遍历一个List来说明一下双冒号和Lambda表达式使用方式的不同。

    package com.wangjun.othersOfJava;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Consumer;
    
    public class LambdaTest {
    	
      public static void printStr(String str) {
        System.out.println(str);
      }
    
      public static void main(String[] args) {
    
        List<String> list = Arrays.asList("aaa","bbb","ccc");
        // 1.通常的遍历方式
        for(String str: list) {
          LambdaTest.printStr(str);
        }
        // 2.使用Lambda表达式遍历
        list.forEach(str -> {
          LambdaTest.printStr(str);
        });
        // 3.使用::遍历
        list.forEach(LambdaTest::printStr);
        // 下面的方法和上面等价,使用的是函数式编程
        Consumer<String> methodParam = LambdaTest::printStr; //方法参数
        list.forEach(x -> methodParam.accept(x));//方法执行accept
      }
    }
    
  • 相关阅读:
    SQLServer 2008 附加数据库出现问题
    Window8下遇到的一些问题
    SqlServer中bit类型的性别的一些问题
    Sql server 2008 的MSSQLSERVER启动不起来
    GridView的 使用
    hibernate连接Mysql中文乱码处理
    windows部署tomcat到MyEclipse
    MyEclipse Eclipse下配置各种插件的方法
    android获取手机的网络状态
    android为HttpClient和HttpURLConnection添加中国移动代理
  • 原文地址:https://www.cnblogs.com/scuwangjun/p/9191226.html
Copyright © 2011-2022 走看看