java8——Lambda表达式


1.简介:

jdk1.8中引入Lambda表达式,其作用是使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面这个例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。

eg:摘自百度百科:
没有使用Lambda的老方法:

button.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent actionEvent){
        System.out.println("Action detected");
    }
});

使用lambda后:

button.addActionListener( actionEvent -> { 
    System.out.println("Action detected");
});

Lambda表达式中,在Thread多线程的使用过程中较为频繁:如:
使用匿名内部类的时候重写run方法:

Runnable runnable1=new Runnable(){
@Override
public void run(){
    System.out.println("Running without Lambda");
}
};

使用Lambda后:

Runnable runnable2=()->System.out.println("Running from Lambda");

lambda表达式的标准格式:
  有三部分
  一些参数
   一个箭头
   一段代码
  格式:
       (参数列表)->{一些重写方法的代码}
       解释说明格式:
   ()接口中抽象方法的参数列表:没有参数空,有就写,多个用,分割
   ->传递的意思,把参数传递给方法体{}
   {}重写接口的抽象方法的方法体

2,函数式编程思想概述

2.1 区别:
面向对象的思想:	
	·做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:
	·只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程

3. 讲述

例如:在多线程中:创建一个实现类,用于实现RUnnable接口,重写了run方法

public class RunnableImpl implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
    }
}
创建主类,用于实现
public class Demo1Runnable {
    public static void main(String[] args) {
        RunnableImpl runnable=new RunnableImpl();
        Thread t=new Thread(runnable);
        t.start();
        //简化代码,匿名内部类
       Runnable runnable1= new Runnable(){

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            }
        };
		new Thread(runnable1).start();//调用线程的启动。
}

这是存在冗余的程序代码块,

简化一:
public class Demo1Runnable {
    public static void main(String[] args) {
        RunnableImpl runnable=new RunnableImpl();
        Thread t=new Thread(runnable);
        t.start();
        //简化代码,匿名内部类
       Runnable runnable1= new Runnable(){

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            }
        };
       new Thread(runnable1).start();
       //继续简化
        new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            }
        }).start();
    }

}
采用匿名内部类,实现线程。

总结:

简化该线程的方法:
1. 
	 Runnable runnable1= new Runnable(){

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            }
        };
       new Thread(runnable1).start();

2.  这段代码是1中的综合
	 new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            }
        }).start();
3. 使用lambda进行简化codes
	lambda表达式的标准格式:
*   有三部分
*   一些参数
*   一个箭头
*   一段代码
*  格式:
*       (参数列表)->{一些重写方法的代码}
*       解释说明格式:
*   ()接口中抽象方法的参数列表:没有参数空,有就写,多个用,分割
*   ->传递的意思,把参数传递给方法体{}
*   {}重写接口的抽象方法的方法体

codes:

	public class Demo02Lambda {
    	public static void main(String[] args) {
        //使用匿名内部类的方式实现多线程
        new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            }
        }).start();
        //使用lambda表达式实现多线程
        new Thread(()-> {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            }
        ) .start();
        //优化省略lambda
        new Thread(()->System.out.println(Thread.currentThread().getName()+"新的线程创建了---")
        ) .start();
    	}

	}

案例二(无参无返回值):

给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:

public interface Cook {
    public abstract void makeFood();
}

在下面的代码中,请使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”字样:

解答:

	public class Demo1Cook {
    public static void main(String[] args) {
        invokeCook(new Cook() {
            @Override
            public void makeFood() {
                System.out.println("吃放了");
            }
        });
       // 使用lambda表达式
        invokeCook(()->{
            System.out.println("吃饭了");
        });
        //省略lambda
        invokeCook(()->System.out.println("吃饭了"));
    }
    //定义方法,参数传递cook接口,方法内部调用cook接口中的方法makeFood
    public static void invokeCook(Cook cook){
        cook.makeFood();
    }

	}

案例三(参数和返回值):

需求:
使用数组存储多个Person对象
对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
1.创建Person类

package com.lambdaDemo;
public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

传统的排序:

import java.util.Arrays;
import java.util.Comparator;
public class Demo06Comparator {
public static void main(String[] args) {
	// 本来年龄乱序的对象数组
	Person[] array = {
	new Person("古力娜扎", 19),
	new Person("迪丽热巴", 18),
	new Person("马尔扎哈", 20) };
	// 匿名内部类
		Comparator<Person> comp = new Comparator<Person>({
				@Override
				public int compare(Person o1, Person o2) {
				return o1.getAge() ‐ o2.getAge();
			}
		};
		Arrays.sort(array, comp); // 第二个参数为排序规则,即	Comparator接口实例
		for (Person person : array) {
			System.out.println(person);
		}
	}
}

知识点:创建对象数组:

对象名[] 数组名称={new 对象名(),new 对象名(),new 对象名(),	}

排序:
使用Comparator

Comparator<Person> comp = new Comparator<Person>({
				@Override
				public int compare(Person o1, Person o2) {
				return o1.getAge() ‐ o2.getAge();
			}
		};
升序是参数1-参数2,降序是参数2-参数1.
记得使用Arrays.sort(array, comp);进行排序,然后遍历数组即可

使用Lambda的排序:

public class Demo1Arrays {
    public static void main(String[] args) {
        Person[] arr={
                new Person("cym",11),
                new Person("yyh",221),
                new Person("jhj",13),
        };
        Arrays.sort(arr, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });
        for (Person p : arr) {
            System.out.println(p);
        }
        //使用lambda表达式简化匿名内部类
        System.out.println("------------使用lambda表达式");
        Arrays.sort(arr,(Person o1,Person o2)->{
            return o2.getAge()-o1.getAge();

        });
        Arrays.sort(arr,(o1,o2)->o2.getAge()-o1.getAge());
        for (Person p : arr) {
            System.out.println(p);
        }
    }
}

案例三:有参有返回

public interface Calculate {
    //定义两个int和方法
    public abstract int calc(int a,int b);
}

使用lambda

package com.lambdaDemo1;


public class Demo1Calculator {
    public static void main(String[] args) {
        //调用invakeCalc方法,参数是接口,可以使用匿名内部类

        invokeCalc(10, 20, new Calculate() {
            @Override
            public int calc(int a, int b) {
                return  a+b;
            }
        });
        //使用lambda表达式简化匿名内部类的书写
       invokeCalc(10,20,(int a,int b)->{
           return a+b;
       });



       //省略
        invokeCalc(10,20,(a,b)-> a+b);
    }
    //定义一个方法,参数传递两个int类型的整数,参数cdCalculator接口,
    // 方法内部电泳Calculator中的方法calc计算和
    public static void invokeCalc(int a,int b ,Calculate calculate){
        int sum= calculate.calc(a,b);
        System.out.println(sum);
    }
}

Lambda的省略《规则》:

/*可推到可省略
* 凡是根据上下文推到出来的内容,都可以省略书写
* 可以省略的内容:
*   1,(参数列表):括号中参数列表的数据类型,可以省略不写
*   2,(参数列表):括号中的参数如果只有一个,那么类型和()都可以省略
*   3.{代码}ruguo {}的代码只有一行,无论是否有返回值,都可以省略{}return 和分号
*   ·要省略都一起省略

1.  省略前:
	new Thread(()-> {
            System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
        }
    ) .start();
	省略后:
	new Thread(()->System.out.println(Thread.currentThread().getName()+"新的线程创建了---")
    ) .start();
explanation:如果{代码块}中只有一行代码,则可以省去{},和;
2. 省略前:
	 invokeCook(()->{
        System.out.println("吃饭了");
    });
	省略后:
	invokeCook(()->System.out.println("吃饭了"));
	explanation:省略了{}和; 因为代码块就一句;
3. 省略前:
	 Arrays.sort(arr,(Person o1,Person o2)->{
        return o2.getAge()-o1.getAge();});
	省略后:
	Arrays.sort(arr,(o1,o2)->o2.getAge()-o1.getAge());
	explanation:变量名一样可以省略,代码块就一句话,可以省略return和{} ;
4.	省略前:
	invokeCalc(10,20,(int a,int b)->{
       return a+b;
   });
	省略后:
	invokeCalc(10,20,(a,b)-> a+b);
	explanation:同上

github-----》》》"lambda"

 posted on 2019-07-24 21:58  ben跑的换行符  阅读(741)  评论(0编辑  收藏  举报