JDK8新特性
Lambda表达式
Lambda 表达式也可称为闭包,是推动 Java 8 发布的最重要新特性。lambda表达式本质上是一个匿名方法。Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)或者把代码看成数据。使用 Lambda 表达式可以使代码变的更加简洁紧凑。在最简单的形式中,一个lambda可以由:用逗号分隔的参数列表、–>符号、函数体三部分表示,在某些情况下lambda的函数体会更加复杂,这时可以把函数体放到在一对花括号中,就像在Java中定义普通函数一样。Lambda可以引用类的成员变量与局部变量(如果这些变量不是final的话,它们会被隐含的转为final,这样效率更高)。Lambda可能会返回一个值。返回值的类型也是由编译器推测出来的。如果lambda的函数体只有一行的话,那么没有必要显式使用return语句。
如何使现有的函数友好地支持lambda。最终采取的方法是:增加函数式接口的概念。函数式接口就是接口里面必须有且只有一个抽象方法的普通接口,像这样的接口可以被隐式转换为lambda表达式成为函数式接口。 在可以使用lambda表达式的地方,方法声明时必须包含一个函数式的接口。 任何函数式接口都可以使用lambda表达式替换,例如:ActionListener、Comparator、Runnable。
函数式接口是容易出错的:如有某个人在接口定义中增加了另一个方法,这时,这个接口就不再是函数式的了,并且编译过程也会失败。为了克服函数式接口的这种脆弱性并且能够明确声明接口作为函数式接口的意图,Java 8增加了一种特殊的注解@FunctionalInterface,但是默认方法与静态方法并不影响函数式接口的契约,可以任意使用。
使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例。通过() -> {}代码块替代了整个匿名类。
Java 8 前后对比
java 8之前:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Before Java8, too much code for too little to do");
}
}).start();
Java 8方式:
new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。
Stream
Java 8 API添加了一个新的抽象称为流Stream把真正的函数式编程风格引入到Java中,可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API极大简化了集合框架的处理,这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
Stream流有一些特性
- Stream流不是一种数据结构,不保存数据,它只是在原数据集上定义了一组操作。
- 这些操作是惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作。
- Stream不保存数据,故每个Stream流只能使用一次。
所以这边有两个概念:流、管道。元素流在管道中经过中间操作的处理,最后由最终操作得到前面处理的结果。这里有2个操作:中间操作、最终操作。
中间操作:返回结果都是Stream,故可以多个中间操作叠加。
终止操作:用于返回我们最终需要的数据,只能有一个终止操作。
实例
一下方法来操作List
创建实体
创建实体类,生成对应的get和set方法
@Data
public class Java8Demo{
private Integer id;
private String name;
private Long age;
private Integer sexHigh;
}
创建List
创建list并赋值
List<Java8Demo> list = new ArrayList<Java8Demo>();
list.add(new Java8Demo(1, "测试一",12L,158));
list.add(new Java8Demo(2, "测试二",20L,185));
list.add(new Java8Demo(3, "测试三",23L,150));
list.add(new Java8Demo(4, "测试四",20L,165));
list.add(new Java8Demo(5, "测试",10L,166));
list.add(new Java8Demo(6, "测试四",10L,166));
实际操作
Stream的形式对list操作
过滤某个空值
list.stream().filter(Java8Demo ->
Java8Demo.getSexHigh().intValue() != 166).collect(Collectors.toList());
从list集合中,取出字段name的列表
List<String> names = list.stream().map(Java8Demo :: getName).collect(Collectors.toList());
根据某个类型去重
ArrayList<Java8Demo> collect = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
new TreeSet<>(Comparator.comparing(Java8Demo :: getName))), ArrayList::new));
根据某字段分组
Map<String, List<Java8Demo>> collect2 = list.stream().collect(Collectors.groupingBy(Java8Demo::getName));
根据某字段计算
Optional<Long> collect3 = list.stream()
.filter(e ->(e.getAge() != null)).map(Java8Demo::getAge).reduce(Long::sum);
根据某字段升序排序
// 降序
List<Java8Demo> collect4 = list.stream().sorted(Comparator.comparing(Java8Demo::getAge).reversed()).collect(Collectors.toList());
// 升序
List<Java8Demo> collect5 = list.stream().sorted(Comparator.comparing(Java8Demo::getAge)).collect(Collectors.toList());
判断一个指定值是否存在
if (list.stream().filter(w->String.valueOf(w.getName()).equals("测试一")).findAny().isPresent()) {
System.out.println("存在");
}else {
System.out.println("不存在");
}
2599

被折叠的 条评论
为什么被折叠?



