java8之lambda表达式-基本语法

Posted 寻梦撑一支长蒿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8之lambda表达式-基本语法相关的知识,希望对你有一定的参考价值。

参考:http://www.cnblogs.com/andywithu/p/7344507.html

lambda表达式,即带有参数的表达式,为更清晰地理解lambda表达式,先看如下例子:
(1)
复制代码
class Student{
    private String name;
    private Double score;
 
    public Student(String name, Double score) {
        this.name = name;
        this.score = score;
    }
 
    public String getName() {
        return name;
    }
 
    public Double getScore() {
        return score;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public void setScore(Double score) {
        this.score = score;
    }
 
    @Override
    public String toString() {
        return "{"
                + "\\"name\\":\\"" + name + "\\""
                + ", \\"score\\":\\"" + score + "\\""
                + "}";
    }
}
 
@Test
public void test1(){
    List<Student> studentList = new ArrayList<Student>(){
        {
            add(new Student("stu1",100.0));
            add(new Student("stu2",97.0));
            add(new Student("stu3",96.0));
            add(new Student("stu4",95.0));
        }
    };
    Collections.sort(studentList, new Comparator<Student>() {
        @Override
        public int compare(Student o1, Student o2) {
            return Double.compare(o1.getScore(),o2.getScore());
        }
    });
    System.out.println(studentList);
}
复制代码
(1)中代码调用Collections.sort方法对集合进行排序,其中第二个参数是一个类,准确地说是一个匿名内部类,sort方法调用内部类中的compare方法对list进行位置交换,因为java中的参数类型只能是类或者基本数据类型,所以虽然传入的是一个Comparator类,但是实际上需要传递的仅仅是compare方法,lambda表达式专门针对只有一个方法的接口(即函数式接口),Comparator就是一个函数式接口
 
@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}
@FunctionalInterface的作用就是标识一个接口为函数式接口,此时Comparator里只能有一个抽象方法。
使用lambda表达式之后(1)中的代码改造如下
(2)
复制代码
public void test1_(){
        List<Student> studentList = new ArrayList<Student>(){
            {
                add(new Student("stu1",100.0));
                add(new Student("stu2",97.0));
                add(new Student("stu3",96.0));
                add(new Student("stu4",95.0));
            }
        };
        Collections.sort(studentList,(s1,s2)-> Double.compare(s1.getScore(),s2.getScore()));
        System.out.println(studentList);
    }
复制代码
对于有多个参数的情况,语法:
     1. ambda表达式的基本格式为(x1,x2)->{表达式...};
     2. 在上式中,lambda表达式带有两个参数,因此两边的括号不能省略,而参数类型可以省略
     3. 如果表达式只有一行,那么表达式两边的花括号可以省略
另外一个常见的例子是新建一个线程,不使用lambda表达式的写法为
(3)
复制代码
public void testThread(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello, i am thread!");
            }
        }).start();
    }
复制代码
其中Runnable接口也是一个函数式接口,源码如下
复制代码
@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object\'s
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}
复制代码
将其转换为lambda表达式的写法为
(4)
public void testThread_(){
    new Thread(()-> System.out.println("hello, i am thread!")).start();
}
对于没有参数的情况 ,语法:
     1.参数的括号不能省略,如果只有一句的表达式则可省略花括号和语句结尾的分号
我们构造一个只有一个参数的函数式接口
复制代码
@FunctionalInterface
public interface MyFunctionalInterface {
    public void single(String msg);
}
 
/**
 * 需要单个参数
 */
public static void testOnePar(MyFunctionalInterface myFunctionalInterface){
    myFunctionalInterface.single("msg");
}
 
/**
     * 一个参数,可以省略参数的括号
     */
    @Test
    public void testOneParameter(){
        testOnePar(x-> System.out.println(x));
    }
复制代码
对于只有一个参数的情况 ,语法:
     1.参数的括号可以省略
在这里我们为了演示只有一个参数的情况自己创建了一个函数式接口,其实java8中已经为我们提供了很多常见的函数式接口
常见的有
Function:提供任意一种类型的参数,返回另外一个任意类型返回值。 R apply(T t);
Consumer:提供任意一种类型的参数,返回空值。 void accept(T t);
Supplier:参数为空,得到任意一种类型的返回值。T get();
Predicate:提供任意一种类型的参数,返回boolean返回值。boolean test(T t);
因此针对上面的情况,我们可以直接使用Consumer类,
/**
     * 需要单个参数
     */
    public static void testOnePar1(Consumer unaryOperator){
        unaryOperator.accept("msg");
    }

以上是关于java8之lambda表达式-基本语法的主要内容,如果未能解决你的问题,请参考以下文章

java8之lambda表达式-基本语法

java8新特性之——lambda表达式的使用

java8之lambda表达式看这一篇就够了

Java8新特性-Lambda表达式

Java8新特性之lambda表达式

Java8新特性之lambda表达式