最近项目中做的一个模块,逻辑有一点绕,经常需要代码中出现循环操作,之前看过一篇关于介绍Java 8 新特性的文章,了解到 Java 8 提供了一些新的 API 来方便遍历操作,记录一下这两天的学习。
首先介绍一下 Lambda
1)Lambda 表达式
Lambda的基本形式是()->,->左面是入参,可以为空,->右面是具体的执行,可以写多行,但需要使用{}
Runnable newRunnable = () -> {
System.out.println(Thread.currentThread().getName() + ": New Lambda Runnable");
};
public static void main(String[] args) {
// old way:
Runnable oldRunnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": Old Runnable");
}
};
new Thread(oldRunnable).start();
// new way:
Runnable newRunnable = () -> {
System.out.println(Thread.currentThread().getName() + ": New Lambda Runnable");
};
new Thread(newRunnable).start();
}
对比一下传统的写法,Java 8 Lambda 更简洁,易读
2)Lambda 作用域
Lambda表达式和匿名内部类很像,如果想在 Lambda 中 使用参数,参数定义为 final
//这样写编译器会报错
int num = 1;
Runnable newRunnable = () -> {
System.out.println(Thread.currentThread().getName() + ": New Lambda Runnable" + num);
};
//正确写法
final int num = 1;
Runnable newRunnable = () -> {
System.out.println(Thread.currentThread().getName() + ": New Lambda Runnable" + num);
};
3)Lambda 与 函数式接口
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
函数式接口的目的是为了使Lambda表达式更好的融入Java,那我们先看看什么是函数式接口,如果一个接口只包含一个抽象的方法,那么该接口成为函数式接口,同时提供一个新的注解@FunctionalInterface,这个注解不是必须的,如果满足条件不加@FunctionalInterface也会被虚拟机翻译为函数式接口,若增加@FunctionalInterface将会增加编译时的检查,如果接口不满足将会在编译时报错。
Predicates
Predicate提供一个单参数,返回值为Boolean的函数式接口,返回值与参数定义 为其泛型
Predicate<String> predicate = (s) -> s.length() > 0;
predicate.test("foo");// true
Stream的使用
Java 8针对集合类,使编程更为便利的方式,可以与 Lambda 表达式一起使用,让你的代码更加简洁,分为并行流和串行流,本文只简单介绍一下串行流。
- 创建:
Collection.stream()取得集合对象的数据集 - 过滤:对数据集进行过滤、检索等数据集的再次处理。例如 forEach(),filter(),map(),reduce()
- 结果:返回过滤后的结果
下面是 Stream 配合 Lambda 的几个小例子
// List 创建 stream
List<Person> list = new ArrayList<Person>();
Stream<Person> stream = list.stream();
// 数组 创建 stream
String[] names = {"Taven","liupeng","gaoye","zjl"};
Stream<String> stream = Arrays.stream(names);
// forEach
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
// map() 完成了赋值操作 第一个i 代表流中一个元素 -> 后代表 对i进行赋值操作,distinct() 去重
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
// filter 过滤, filter(Predicate<? super 你的Stream泛型> predicate),这里需要用到上述的Predicates
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
// 获取空字符串的数量
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
int count = strings.stream().filter(s -> s.isEmpty()).count();
// 排序
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
//统计,IntSummaryStatistics 对象中包含 求和,平均值,最大值,最小值,总条数。
List<Integer> list = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = list.stream().mapToInt((x) -> x).summaryStatistics();
Java 8 特性介绍 https://blog.csdn.net/wsrspirit/article/details/52179400











网友评论