Java 8学习之旅1---Lambda表达式
2014-11-10 16:58
295 查看
Java 8的新特性中,最著名的可能就是Lambda表达式了,基于此才能Java 8下面的函数式编程。虽然Lambda表达式说的很神奇,其实它并不能做任何新东西,只是能以比以前更简洁的方式来实现一些功能而已。Lambda的一个典型场景就是在处理不断变化的需求时,将函数做为方法的参数,这样满足不断变化的需求。
举例来说,比说我们做一个在线书籍查询应用,假设我们需要按照书名(模糊查询)、类别、价格区间进行查询,我们需要写这样一个查询方法,在Java 8之前,由于我们希望我们的方法可以适应未来需求的变化,如比将来可能增加按出版社查询,因此我们可以采用策略设计模式,每一种查询条件做成一种策略。
采用策略设计模式
首先定义一个查找条件接口,如下所求:
定义接口的好处是当查询条件增加时,我们只需要实现新增的查询条件,而无需修改之前的代码。
下面是对书名模糊查询的实现和调用,在这里,我们没有像通常的那样,定义一个类来实现BookFinder这个接口,因为我们想要尽量做到代码简洁,所以我们采用匿名类的方式来实现:
表2
选择书籍具体的实现函数:
这样我们就比较完美地实现按书名模糊查询功能,但是在Java 8中,由于有了Lambda表达式,我们就有了更简洁的实现方式。
使用Lambda表达式,我们第一步也是定义一个函数式接口:
如上代码所示,我们声明的接口是函数式接口,其只能有一个公共抽象接口,由注解@FunctionalInterface来表示。另外,我们利用Generic机制,对方法的参数进行参数化,这样使这个接口不仅可以处理书籍,可以处理其他事务的查询。
下面是对函数接口的调用:
方式一:直接初始化函数式接口并作为方法调用的参数
方式二:声明函数式接口变量,然后作为参数传入
具体的函数实现如下所示:
综上所述,Lambda表达式的引入,确实对程序适应不同的需求变化,提供了一种比之前更加简洁的实现方式,同时Java 8将函数提升到了与类机同的高度,可以做为参数进行传递,提供了更大的灵活性。
举例来说,比说我们做一个在线书籍查询应用,假设我们需要按照书名(模糊查询)、类别、价格区间进行查询,我们需要写这样一个查询方法,在Java 8之前,由于我们希望我们的方法可以适应未来需求的变化,如比将来可能增加按出版社查询,因此我们可以采用策略设计模式,每一种查询条件做成一种策略。
采用策略设计模式
首先定义一个查找条件接口,如下所求:
public interface BookFinder { public boolean checkBook(BookVo bookVo); }表1
定义接口的好处是当查询条件增加时,我们只需要实现新增的查询条件,而无需修改之前的代码。
下面是对书名模糊查询的实现和调用,在这里,我们没有像通常的那样,定义一个类来实现BookFinder这个接口,因为我们想要尽量做到代码简洁,所以我们采用匿名类的方式来实现:
public void startup() { List<BookVo> books = prepareBooks(); String name = "Java"; List<BookVo> result = findBooks(books, new BookFinder() { @Override public boolean checkBook(BookVo bookVo) { if (bookVo.getBookName().indexOf(name) >= 0) { return true; } return false; } }); for (BookVo book: result) { System.out.println("##:" + book.getBookName() + ":" + book.getPrice() + "!"); } }
表2
选择书籍具体的实现函数:
public List<BookVo> findBooks(List<BookVo> books, BookFinder finder) { List<BookVo> result = new ArrayList<BookVo>(); for (BookVo book:books) { if (finder.checkBook(book)) { result.add(book); } } return result; }表2.1
这样我们就比较完美地实现按书名模糊查询功能,但是在Java 8中,由于有了Lambda表达式,我们就有了更简洁的实现方式。
使用Lambda表达式,我们第一步也是定义一个函数式接口:
@FunctionalInterface public interface FBookFinder<T> { public boolean checkBook(T t); }表3
如上代码所示,我们声明的接口是函数式接口,其只能有一个公共抽象接口,由注解@FunctionalInterface来表示。另外,我们利用Generic机制,对方法的参数进行参数化,这样使这个接口不仅可以处理书籍,可以处理其他事务的查询。
下面是对函数接口的调用:
方式一:直接初始化函数式接口并作为方法调用的参数
public void testLambda() { List<BookVo> books = prepareBooks(); List<BookVo> result = findBookByName(books, (BookVo bookVo) -> {if (bookVo.getBookName().indexOf("Java")>=0) {return true;} else {return false;}}); for (BookVo book: result) { System.out.println("Lambda:" + book.getBookName() + ":" + book.getPrice() + "!"); } }表4
方式二:声明函数式接口变量,然后作为参数传入
public void testLambda() { List<BookVo> books = prepareBooks(); String bookName = "Java"; FBookFinder<BookVo> fbf = (BookVo bookVo) -> {if (bookVo.getBookName().indexOf(bookName)>=0) {return true;} else {return false;}}; List<BookVo> result = findBookByName(books, fbf); for (BookVo book: result) { System.out.println("Lambda:" + book.getBookName() + ":" + book.getPrice() + "!"); } }表5
具体的函数实现如下所示:
public <T> List<T> findBookByName(List<T> books, FBookFinder<T> finder) { List<T> result = new ArrayList<T>(); for (T book : books) { if (finder.checkBook(book)) { result.add(book); } } return result; }表6
综上所述,Lambda表达式的引入,确实对程序适应不同的需求变化,提供了一种比之前更加简洁的实现方式,同时Java 8将函数提升到了与类机同的高度,可以做为参数进行传递,提供了更大的灵活性。
相关文章推荐
- java 8 lambda 表达式 学习
- JAVA 1.8 新特性学习(2) lambda表达式
- Java8学习笔记 — 【Lambda表达式】
- Java学习笔记-Lambda表达式及內建函数式接口
- Java8学习笔记(一)-初步认识Lambda表达式
- 学习Java8中Lambda表达式的10个例子
- 30分钟入门Java8之lambda表达式学习
- 一、JAVA8学习笔记 Lambda表达式快速入门
- Java8 学习笔记--函数式接口与lambda表达式的关系
- 【Java学习笔记之三十一】详解Java8 lambda表达式
- Java 8 Lambda 表达式学习心得总结
- java8新特性学习笔记(一) Lambda表达式
- java lambda表达式学习笔记
- Java8学习(3)- Lambda 表达式
- Java8学习:Lambda表达式、Stream API和功能性接口 — 教程、资源、书籍和实例
- Java 8 学习--lambda表达式的月之暗面
- java8 Lambda表达式的学习与测试
- Java 8学习之Lambda表达式
- Java8学习(3)- Lambda 表达式