JAVA函数式编程值lambda表达式的使用

Java中的lambda是在Java 8 之后加入的一个重要的新特征,之前在python中使用过lambda,感觉非常的简洁方便,一直没有对java中的lambda进行细致的了解和学习,这里记录下一些lambda的基础知识和简单的实例。

如果还没有安装Java 8,那么你应该先安装才能使用lambda和stream(建议在虚拟机中安装,测试使用)。

lambda 的实质是一个语法糖,使用匿名方法,解决了匿名内部类中的冗余的语法问题,使代码变的更加简洁紧凑。

语法糖:是指在没有给计算机语言添加新功能而是提供了更使用的编码方式,有益于更好的编码风格,更易读的语言方式。


Lambda表达式的语法:

基本语法: (parameters) -> expression
或:      (parameters) ->{ statements;}

下面是lambda一些重要的特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

下面通过三个简单lambda表达式介绍下lambda的结构:

(int x, int y) -> x+ y;
() -> 42;
(String s) -> {System.out.println(s);}

第一个表达式接受了x和y两个整形参数并返回它们的和
第二个表达式不接受参数,返回整数42
第三个表达式接受一个字符串并把它们打印到控制台,不返回值

lambda 表达式的语法由参数列表、箭头符号->和函数体组成,函数体可以是一个表达式,也可以是一个语句块:

  • 表达式:表达式会被执行然后返回执行结果
  • 语句块:语句块中的语句会被一次执行就像方法中的语句一样
    • return 语句会把控制权交给匿名方法的调用者
    • break 和continue 只能在循环中使用
    • 如果有返回值,那么函数体内部的每一条路径都必须放回值

表达式函数体适合小型lambda表达式,它消除了return关键字,使得语法更加简洁。

使用 Lambda 表达式需要注意以下两点:

  • Lambda表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
  • Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。

如果要熟练的使用lambda还是要多在平时多去重构为lambda表达式的方式,其中有很多的便捷的方法都需要仔细的阅读lambda的文档:https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html


下面是一些简单的列子,配有注解:

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;

import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;


/**
 * Created by gray- on 2017/11/5.
 */
public class lambdaTest {


    public static class Person{


        private  String firstName, lastName, job, gender;
        private  int salary, age;

        public Person(String firstName, String lastName, String job,
                      String gender, int age, int salary)       {
            this.firstName = firstName;
            this.lastName = lastName;
            this.gender = gender;
            this.age = age;
            this.job = job;
            this.salary = salary;
        }

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        public String getJob() {
            return job;
        }

        public void setJob(String job) {
            this.job = job;
        }

        public String getGender() {
            return gender;
        }

        public void setGender(String gender) {
            this.gender = gender;
        }

        public int getSalary() {
            return salary;
        }

        public void setSalary(int salary) {
            this.salary = salary;
        }

        public int getAge() {
            return age;
        }

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

        @Override
        public String toString() {
            return "Person{" +
                    "firstName='" + firstName + '\'' +
                    ", lastName='" + lastName + '\'' +
                    ", gender='" + gender + '\'' +
                    ", salary=" + salary +
                    ", age=" + age +
                    '}';
        }
    }





    public static void main(String[] args)
    {

        MathOperation mathOperation = (int a, int b) -> a + b;

        System.out.println(mathOperation.operation(2,3));



        //使用lambda表达式实现Runnable

        new Thread(() -> System.out.println("beganing is 狗狗狗!")).start();

        //使用lambda表达式进行迭代

        List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");

        features.forEach(n -> System.out.println("使用lambda:" + n));

        //下面为java8 的方法引用

        features.forEach(System.out :: println);


        System.out.println("--------------使用匿名内部类实现Comparator(有很多的比较器)----------------------");

        //使用lambda排序集合
        String[] players = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka", "David Ferrer",
                "Roger Federer", "Andy Murray",
                "Tomas Berdych", "Juan Martin Del Potro",
                "Richard Gasquet", "John Isner"};

        Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
        Arrays.sort(players, sortByName);

        //可以简化为   Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
        //                                    其中可以根据字符串的长度   s1.length() - s2.length()

        for (String player : players) {
            System.out.println(player);
        }


        System.out.println("--------------使用Streams------------------------");

        List<Person> javaProgrammers = new ArrayList<Person>() {
            {
                add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));
                add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23, 1500));
                add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));
                add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
                add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
                add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));
                add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
                add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
                add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
                add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));
            }
        };



        //输出所有员工的姓名

        javaProgrammers.forEach((p) -> System.out.printf("%s %s: \n", p.getFirstName(), p.getLastName()));


        //使用forEach方法增加程序员工资加5块钱
        Consumer<Person> giveRaise = e -> e.setSalary((e.getSalary() + 5));
        javaProgrammers.forEach(giveRaise);

        //使用过滤器filter(),显示月薪超过1400

        javaProgrammers.stream()
                .filter((p) -> (p.getSalary()) >1400)
                .forEach((p) -> System.out.printf(" 工资大于1400 %s \n",p.getFirstName()));


        //可以自己定义过滤器 然后重用来执行其他的操作,定义后的过滤器也可以运用到其他的类中

        Predicate<Person> ageFilter = (p) -> (p.getAge() > 25);
        Predicate salaFilter = (p) -> (p.getSalary() > 1400);
        Predicate genderFilter = (p) -> ("female".equals(p.getGender()));

        System.out.println("下面显示的年龄大于24岁,而且月薪在1400上的女性程序员");

        javaProgrammers.stream()
                .filter(ageFilter)
                .filter(salaFilter)
                .filter(genderFilter)
                .forEach((p) -> System.out.printf("%s \n" , p.getFirstName()));

        //使用limit方法限制结果集的个数

        System.out.println("显示最前面的java程序员");

        javaProgrammers.stream()
                .limit(3)
                .forEach((p) -> System.out.println(p));


        //在stream 中使用排序,java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值

        List<Person> sortedJavaProgrammers =
                javaProgrammers.stream()
                        .sorted((p1 , p2) -> (p1.getFirstName().compareTo(p2.getFirstName())))
                        .limit(5)
                        .collect(toList());


        sortedJavaProgrammers.forEach((p) -> System.out.println(p));


        //使用其中的 minmax 方法

        System.out.println("其中工资最低的是:");

        Person person = javaProgrammers.stream()
                //求工资最高的是
                //max((p1, p2) -> (p1.getSalary() - p2.getSalary()))
                .min((p1 ,p2) -> (p1.getSalary() - p2.getSalary()))
                .get();

        System.out.println(person);


        //可以结合map方法使用collect方法将结果集放到一个字符串中或者是一个set或者是treeset中


        //将结果中name放入到字符串中
        String javaDeveloers = javaProgrammers.stream()
                .map(Person :: getFirstName)
                .collect(joining(" ; "));
                //放入到set中
                // .map(Person::getFirstName)
                // .collect(toSet());
                //放入到treeset中
                // .collect(TreeSet::new);

        //Stream还可以是并行的(parallel),计算所有人的工资

        int totalSalary = javaProgrammers
                .parallelStream()
                .mapToInt(p -> p.getSalary())
                .sum();



        //使用summaryStatistics方法获得stream中元素的各种汇总数据,然后通过方法进行获得

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        IntSummaryStatistics stats = numbers.stream()
                .mapToInt((x) -> x)
                .summaryStatistics();

        System.out.println("max number is :" + stats.getMax());
        System.out.println("min number is : " + stats.getMin());
        System.out.println("the sum is :" + stats.getSum());
        System.out.println("the average is :" + stats.getAverage());




    }


    public static void  filter(List names, Predicate condition){

        for(Object name : names){
            if(condition.test(name)){
                System.out.println(name + " ");
            }
        }

    }


    interface MathOperation {
        int operation(int a, int b);
    }

}

更多的例子请看下这篇博客:http://www.importnew.com/16436.html

你可能感兴趣的:(java)