一:Lambda 表达式
为什么使用 :使用 Lambda 表达式可以使代码变的更加简洁紧凑。
表达了什么?: 匿名内部类的新写法;
语法 :(parameters) -> expression 或 (parameters) ->{ statements; }
parameters 对应接口的参数例如
expression或statements : 对应接口的实现
假设需求:一个类的方法参数是一个接口类型的,而又没有相关的该接口的实现。
接口如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public interface MyInterface { void toDo(); }
1): 最不简洁的写法
public class Java8Lambda { private void toDo(MyInterface myInterface) { myInterface.toDo(); } public static void main(String[] args) { Java8Lambda lambda = new Java8Lambda(); MyInterfaceImpl interfaceImpl = new Java8Lambda().new MyInterfaceImpl(); lambda.toDo(interfaceImpl); } class MyInterfaceImpl implements MyInterface{ @Override public void toDo() { System.out.println("我仅是打印一句话,但要写一个类出来,好麻烦!!!"); } } }
2):java8之前的写法(匿名内部类)
public static void main(String[] args) { Java8Lambda java8Lambda = new Java8Lambda(); java8Lambda.toDo(new MyInterface() { @Override public void toDo() { System.out.println("我是匿名内部类的写法,虽然简洁,但还不比lambda表达式简介"); } }); // Java8Lambda lambda = new Java8Lambda(); // MyInterfaceImpl interfaceImpl = new Java8Lambda().new MyInterfaceImpl(); // lambda.toDo(interfaceImpl); }
3): lambda表达式(是不是很简洁^_^)
public static void main(String[] args) { Java8Lambda java8Lambda = new Java8Lambda(); java8Lambda.toDo(() -> {System.out.println("我是lambda表达式写法");}); }
备注:
二:Stream (流:新的api)
简洁:类似io流中的流概念(个人理解:这个流是对外部资源的读取操作如网络资源或文件),而新的流Stream主要是对内部数据建立流(主要是集合数据),并进行读取操作。主要是利用lambda表达式对集合数据进行操作,相比以前操作集合这种写法代码更简洁。
1): 通过集合生成Stream 对象
在java8新版本中对接口(interface)特性添加了一些新的特性(这些特性有的与之前我们的认识可能不同),例如接口中的方法可以有具体实现(之前是的能的),但必须通过关键字default修饰,而且该方法不用被子类实现。
好处:这样我们可以给之前定义的接口添加新的方法,而不必修改继承他的所有子类(以前如果我们给一个接口添加新的方法,就必须给所有继承该接口的所有子类添加该方法)。可以很容易扩展之前定义接口的方法。
用例:在java8中,给Collection接口定义了一个新的实现方法 stream() ,该方法可以生产Stream 对象。
List<String> list = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
Stream<String> stream2 = list.stream();
备注:用Stream对象很大一部分用处也是为支持lambda,写出更简洁的代码而设计的,当然用stream对象对操作集合(list)有时比传统方法更高效。比如遍历集合中的数据,就比for()遍历更高效。
2) : 常用接口
* forEach 参数(Consumer<? super String> action)
遍历流对象并打印所有结果
* map (Function)
用于映射集合中的每个数据
* filter(Predicate)
顾名思义用于过滤集合中符合条件的数据
* limit(int )
用于获取指定数量的流
* sorted (Comparator) 和sorted () 无参数
顾名思义对集合中的数据排序
备注:以上操作都不会影响原始集合中的数据。即他们返回一个新的集合
备注:java8,定义了一个新的接口类型叫@FunctionalInterface函数接口,即该接口中只能有一个抽象方法(可以有实现的方法)
以上集合中的参数都是函数接口(除limit方法)
三:举例
主要是想演示使用stream对象api的与lambda表达式结合使用,以及验证我前面说的Lambda 表达式是匿名内部类的新写法。(我们知道内部类通过javac编译后会生成以外部类和内部类结合的文件,其实lambda表达式也会生成响应的文件)。
public static void main(String[] args) { List<String> list = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); Stream<String> stream = list.stream(); //通过匿名内部类写法 过滤集合中的空值 Stream<String> filter = stream.filter(new Predicate<String>() { public boolean test(String t) { return !t.isEmpty(); } }); //通过匿名内部类写法 遍历集合中的数据 filter.forEach(new Consumer<String>() { public void accept(String t) { System.out.println(t); } }); //////////////////////////////////////////////////////////////////////////////////////////// //lambda写法 List<String> list2 = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); Stream<String> stream2 = list2.stream(); // 对比匿名内部 过滤集合 Stream<String> stream3 = stream2.filter(string -> !string.isEmpty()); // 对比匿名内部 遍历集合 stream3.forEach( t -> System.out.println(t)); }