JDK 8新特性学习之Lambda表达式
来源:互联网 发布:兵棋推演软件 编辑:程序博客网 时间:2024/06/08 00:32
JDK8发布已经有很长的一段时间了,以前就简单了解就没继续了解,今天抽空整理了一下,欢迎更正补充。JDK8新特新之一:
Lambda(λ) -- 官网
Lamda实际上就是一个匿名方法, 实例:
@Testpublic void oldRunable() { new Thread(new Runnable() { @Override public void run() { System.out.println("The old runable now is using!"); } }).start();}
Lambda表达式:
@Testpublic void runable() { new Thread(() -> System.out.println("It's a lambda function!")).start();}
Lambda的类型叫做“目标类型(Target Type)”,它的目标是“函数接口(Functional Interface)”,这是JDK8引入的概念。它的定义是:一个接口,如果只有一个显式声明的抽象方法,那么他就是一个函数接口,一般用@FunctionalInterface标注出来(也可以不标)。示例:
@FunctionalInterfacepublic interface Runnable { void run(); }public interface Callable<V> { V call() throws Exception; }public interface ActionListener { void actionPerformed(ActionEvent e); }public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }注意上面Comparator接口虽然声明了2个接口,但他就是函数接口。这是因为equals方法时Object的,所有的接口都会声明Object的public方法(隐式)的,所以它还是一个函数接口。Lambda表达式分为了三个方面来阐述,官方地址:
- 方法引用:(Method Reference)
- 默认方法:(Default Method)
- 新的Lambda表达式和流的新增和增强API(New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams in Java SE 8)
方法引用,示例:
先建一个实体类:
class Person{ @Getter Integer age; @Getter String name; @Getter String firstName; Person(Integer age){ this.age = age; } Person(Integer age, String name){ this.age = age; this.name = name; } Person(String name, String firstName, Integer age){ this.name = name; this.firstName = firstName; this.age = age; } public static int compare(Person a, Person b){ return a.getAge().compareTo(b.getAge()); }}
示例:
@Test public void test(){ // list 排序 ArrayList<Person> list = new ArrayList<>(); list.add(new Person(30)); list.add(new Person(40)); list.add(new Person(10)); System.out.println(list); list.forEach(a->{System.out.println(a.getAge());});// list.sort((a,b)-> b.getAge().compareTo(a.getAge())); // 方法引用 list.sort(Comparator.comparing(Person::getAge)); // 对象方法引用 System.out.println(list); // 数组排序 Person[] people = new Person[]{ new Person("name1", "f1", 20), new Person("name2", "u2",30), new Person("name3", "p3",10), new Person("name4R", "r4",60), }; for(Person p : people){ System.out.println(p.getAge()); } System.out.println(" -- "); // 方法一// Arrays.sort(people, (a,b)-> a.getAge().compareTo(b.getAge())); // 方法引用 // 方法二// Arrays.sort(people, (a, b) -> Person.compare(a,b)); // 对象方法引用 // 方法三// Arrays.sort(people, Person::compare); // 静态对象方法引用(对象方法必须为静态)// for(Person p : people){// System.out.println(p.getAge());// } Arrays.sort(people, Comparator.comparing(Person::getFirstName)); // 对象方法引用 for (Person p: people){ System.out.println(p.getFirstName()); } }官方文档还写了一种构造器方法引用,示例:public class LambdaTest { // 构造器引用 public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>> DEST transfer( SOURCE source, Supplier<DEST> collectionFactory ){ DEST result = collectionFactory.get(); for (T t : source) { result.add(t); } return result; }}@Test public void test1(){ArrayList<Person> list = new ArrayList<>();list.add(new Person(40)); list.add(new Person(10)); System.out.println(list); list.forEach(a->{System.out.println(a.getAge());}); Set<Person> personSet = transfer(list, ()->new HashSet<>()); System.out.println(personSet); // 构造器引用转换-方法引用 personSet = transfer(list, HashSet::new); System.out.println(personSet); // 构造器引用转换-静态引用 list.add(new Person(99)); // 检验对象是否变化 personSet = transfer(list, HashSet<Person>::new); System.out.println(personSet); // 构造器引用转换-泛型静态引用 }另外附加一个lambda对象的创建方式:
new HashSet(); == HashSet::new == HashSet<Person>::new
默认方法引用,有两种方式:
- 引用实现,在引用一个方法时,需要对这个方法设定默认值,则需要在这个方法上加一个修饰符 default 并附加实现方法。或者创建一个接口实现原接口,然后实现新接口并实现接口方法。
- 静态共享(一个静态方法是一个与它定义的类相关联的方法,而不是与任何对象相关联,每个类的实例共享其静态方法)
详情请查看官网文档。
流的使用
Java8为集合类引入了另一个重要概念:流(stream)。一个流通常以一个集合类实例为其数据源,然后在其上定义各种操作。流的API设计使用了管道(pipelines)模式。对流的一次操作会返回另一个流。如同IO的API或者StringBuffer的append方法那样,从而多个不同的操作可以在一个语句里串起来。示例:
@Testpublic void test2(){ // list 排序 ArrayList<Person> list = new ArrayList<>(); list.add(new Person("name1", "f1", 20)); list.add(new Person("name2", "u2",30)); list.add(new Person("name3", "p3",10)); list.add(new Person("name4R", "r4",60)); System.out.println(list); list.forEach(a->{System.out.println(a.getAge());}); // 流的使用 List newL = list.stream().filter(a -> a.getFirstName().equals("test1")).distinct().collect(Collectors.toList()); System.out.println(newL); newL = list.stream().map(a -> Integer.valueOf(a.getAge())).filter(a -> a>20).collect(Collectors.toList()); System.out.println(newL); newL.forEach(a->{System.out.println(a);});}
个人流的使用小结:
.stream 转化为流的方式, 用法:list.stream
.map 遍历,用法:.map(m -> new Integer(m))
.filter 拦截器,用法:.filter(a -> a.getA == a)
.forEach 遍历,forEachordered较之比较稳定,顺序执行, 用法: .forEach(a -> System.out.println(a);)
.distinct 去重, 用法:list.stream.distinct()
.collect 收集结果, 用法: .collect(Collectors.toList());
.toArray 转化成数组
.reduce 返回单个结果值(执行层,每次处理一个元素创建一个新值),用法:.reduce(a)
.sorted 排序
.findFirst 查询第一个元素并输出
.findAny 返回任何一个元素,并返回Optional实例
.flatmap 将包含通过映射函数替换源流的每个元素而获得的元素,并使结果平坦化
.limit 限制最大数量值
.max 获取最大值,min反之
.peek 中间操作流,返回一个新流
.skip 从开始的流对象中跳过给定数量的元素
.allMatch 全匹配,匹配成功返回true。同理有anyMatch,noneMatch
.count 计数
- JDK 8新特性学习之Lambda表达式
- JDK 8 新特性学习(二) Lambda表达式、集合流之操作
- Java 8 新特性之 Lambda 表达式
- Java 8 新特性之 Lambda表达式
- jdk1.8 新特性之 lambda表达式
- JDK 1.8 新特性 ( 一) ---- Lambda表达式
- Android 使用jdk1.8新特性之lambda表达式
- JDK1.8的新特性之Lambda表达式的应用
- C++ 11 新特性之 lambda表达式
- C++11 新特性之 Lambda表达式
- JDK8新特性之Lambda表达式
- java8新特性之lambda表达式(一)
- java8新特性之lambda表达式(二)
- JDK8新特性之Lambda表达式
- Java8新特性之lambda表达式
- jdk8新特性之lambda表达式
- Java8新特性之(lambda表达式)
- C++11 新特性之Lambda表达式
- 形参和实参的区别
- Servlet的生命周期
- 线性回归及其概率解释
- 宏定义中的一些问题
- 机器学习之CART算法python实现
- JDK 8新特性学习之Lambda表达式
- Java学习第五天
- vlayout实战 —— 仿淘宝首页
- 【2017年 腾讯校招笔试】【数位DP】 + 【解方程 贪心 正难则反】
- 深网
- Hive之 优化篇
- 欢迎使用CSDN-markdown编辑器
- 关于supersocker的数据传输中的问题与解决
- PAT甲级 1043