jdk8已经发布很久了,直到现在才来研究它的特性,emmmmm...
本文主要从optional,lambda,stream,map 4大块来学习
optional
简单来说Optional<T>
是一个可以包含或者不包含非空值的容器对象,从本质上来说,该类属于包含可选值的封装类(wrapper class),因此它既可以包含对象也可以仅仅为空。
以前为了防止NPE(NullPointException)的出现,我们必须得在使用一个对象之前做非空判断,如下:
public String toUpperCaseUsername(String id) {
if (id != null) {
List<User> userList= userService.getById(id);
if (userList != null) {
for (User user : userList) {
if (user.getUsername() != null) {
return user.getUsername().toUpperCase();
}
return null;
}
}
return null;
}
return null;
}
使用Optional改进
User user = userService.getById(id);
String result = Optional.ofNullable(user)
.map(u -> u.getUsername())
.map(name -> name.toUpperCase())
.orElse("default");
System.out.println(result);
终极版
System.out.println(Optional.ofNullable(id)
.map(userService::getById)
.map(User::getUsername)
.map(String::toUpperCase)
.orElse("default"));
lambda表达式
实际上,上面我们已经使用到了lambda表达式。lambda表达式又称为匿名函数,来看两个经典的例子
- 用lambda表达式实现Runnable
// Java 8之前:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("毫(low)无(de)亮(yi)点(bi)");
}
}).start();
// lambda方式:
new Thread( () -> System.out.println("逼格很高") ).start();
- 使用lambda表达式对集合进行迭代
// java 8之前
List<String> list = new ArrayList<String>();
list.add("xiaodou");
list.add("xiaobai");
list.add("gouzi");
for (String s : list) {
System.out.println(s);
}
// lambda方式
list.forEach(System.out::println);
// 也可在遍历的时候对元素进行一些操作
// 操作元素:转大写
list.stream().map(String::toUpperCase).collect(Collectors.toList()).forEach(System.out::println);
// 过滤数据
List gList = list.stream().map(s -> s.startsWith("g")).collect(Collectors.toList());
System.out.println(gList);
stream
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
创建一个stream
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
map
map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:
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());