Jdk1.8新特性---Lambda表达式优势(策略模式改进实现)

 

Jdk1.8加入了诸多特性及语法改进,其中Labmda表达式是一个显著的语法改进,会使语法更加简洁。下面给两个例子来彰显他的优势,如果第一个例子还不能说服你的话,请看第二个例子。


目录

匿名内部类

Lambda表达式举例

举例一:标准的匿名内部类实现及改进

Jdk1.8以前写法:

修改为Lambda表达式写法:

举例二:体会这个例子的牛逼之处

 1、最普通实现方法

2、策略模式优化

3、匿名实现类优化

4、Lambda表达式优化


匿名内部类

出现的原因就是不想写多余的代码,不需要定义单独的实现类,只需要接口。我们可以直接通过实现接口的方式来实现其方法逻辑,因此这个匿名内部类是没有真正的类名的,所以就没有显示的构造方法,只有默认的无参构造方法。

Lambda表达式举例

举例一:标准的匿名内部类实现及改进

Jdk1.8以前写法:

先定义一个接口A,其中有一个get方法待实现

public interface A {
     void get(String param);
}

然后在主函数中去实现它,并将入参打印输出。可以看到A接口并没有真正的实现类定义,只是在我们要用到他的时候,new了一下接口转而实现其方法。

public static void main(String[] args) {
        A a = new A() {
            @Override
            public void get(String param) {
                System.out.println(param);
            }
        };

        String testParam = "test param";
        a.get(testParam);
    }

输出结果:

修改为Lambda表达式写法:

public static void main(String[] args) {
        A a = (param)-> System.out.println(param);// 此处把一坨改为了一句

        String testParam = "test param";
        a.get(testParam);
    }

 对比前后,jdk1.7的写法一大坨,其实我们关注的只是那个接口最终的实现而已;而Lambda表达式将那一坨没有用的东西剔除,简化为一行:A a = (param)-> System.out.println(param);当然语句多了要在->后面增加大括号,比如:

public static void main(String[] args) {
        A a = (param) -> {
            System.out.println(param);
        };

        String testParam = "test param";
        a.get(testParam);
    }

举例二:体会这个例子的牛逼之处

此时某个班级刚进行一场考试,考了语文和数学,共五个同学,成绩如下:

  • 小红:语文98 数学100
  • 小明:语文60 数学99
  • 小王:语文97 数学59
  • 豆豆:语文85 数学79
  • 小李:语文77 数学75

要求:方法1、筛选出语文成绩>=85的同学;方法2、筛选出数学成绩>=75的同学

此时构建Student类(Get、Set方法略)

public class Student {

    private String studentName;// 学生姓名

    private Integer chineseScore;// 语文成绩

    private Integer mathScore;// 数学成绩

    public Student(String studentName, Integer chineseScore, Integer mathScore) {
        this.studentName = studentName;
        this.chineseScore = chineseScore;
        this.mathScore = mathScore;
    }

    @Override
    public String toString() {
        return studentName+" "+chineseScore+" "+mathScore;
    }
}

 1、最普通实现方法

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小红", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================语文成绩>=85的同学================");
        System.out.println(getResult1(studentList));
        System.out.println("===================数学成绩>=75的同学================");
        System.out.println(getResult2(studentList));
    }

    /**
     * 筛选出语文成绩>=85的同学
     */
    public static List<Student> getResult1(List<Student> studentList) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (_student.getChineseScore() >= 85) {
                resultList.add(_student);
            }
        }
        return resultList;
    }

    /**
     * 筛选出数学成绩>=75的同学
     */
    public static List<Student> getResult2(List<Student> studentList) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (_student.getMathScore() >= 75) {
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

运行结果:

很显然上述两个方法,其实现算法完全一样,重复造轮子,这里使用策略模式对其进行优化。

2、策略模式优化

首先定义一个接口,并定义一个get方法,此方法用于实现各自的算法:

public interface Strategy<T> {

    boolean get(T t);
}

然后定义两个实现类,语文、数学,分别实现该接口及方法

/**
 * 语文
 */
public class ChineseStrategy implements Strategy<Student> {
    @Override
    public boolean get(Student student) {
        return student.getChineseScore()>=85;// 语文成绩>=85
    }
}
/**
 * 数学
 */
public class MathStrategy implements Strategy<Student> {

    @Override
    public boolean get(Student student) {
        return student.getMathScore()>=75;// 数学成绩>=75
    }
}

然后在最终调用类中,使用for循环写统一通用方法getResult,并增加入参Strategy,根据在main方法中的入参实现类不同,去调用不同的子类方法(策略模式)。

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小红", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================语文成绩>=85的同学================");
        System.out.println(getResult(studentList,new ChineseStrategy()));
        System.out.println("===================数学成绩>=75的同学================");
        System.out.println(getResult(studentList,new MathStrategy()));
    }

    /**
     * 筛选通用方法
     */
    public static List<Student> getResult(List<Student> studentList, Strategy<Student> strategy) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (strategy.get(_student)) {// 策略模式,根据入参实现类的不同 分别调用子类方法
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

上述方法省去了重复写for循环的问题,但依然感觉写两个实现类很麻烦,每个里面就一个方法一行代码,啰嗦。好!此处该匿名实现类登场!!!

3、匿名实现类优化

 在main方法中,直接调用两次匿名实现类实现算法即可!方便!nice!

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小红", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================语文成绩>=85的同学================");
        System.out.println(getResult(studentList, new Strategy<Student>() {
            @Override
            public boolean get(Student student) {
                return student.getChineseScore() >= 85;
            }
        }));
        System.out.println("===================数学成绩>=75的同学================");
        System.out.println(getResult(studentList, new Strategy<Student>() {
            @Override
            public boolean get(Student student) {
                return student.getMathScore() >= 75;
            }
        }));
    }

    /**
     * 筛选通用方法
     */
    public static List<Student> getResult(List<Student> studentList, Strategy<Student> strategy) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (strategy.get(_student)) {
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

4、Lambda表达式优化

看到了匿名实现类,那么 Lambda表达式又可将其简化!!

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小红", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================语文成绩>=85的同学================");
        System.out.println(getResult(studentList, (student -> student.getChineseScore() >= 85)));
        System.out.println("===================数学成绩>=75的同学================");
        System.out.println(getResult(studentList, (student -> student.getMathScore() >= 75)));
    }

    /**
     * 筛选通用方法
     */
    public static List<Student> getResult(List<Student> studentList, Strategy<Student> strategy) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (strategy.get(_student)) {
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

查看运行结果:

来吧!兄弟们!还!有!谁!~ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值