Lambda 表达式
Lambda 表达式的初衷是,进一步简化匿名类的语法
//匿名类
new Thread(new Runnable(){
@Override
public void run(){
System.out.println("hello1");
}
}).start();
//Lambda表达式
new Thread(() -> System.out.println("hello2")).start();
使用 Java 8 简化代码
- 使用 Stream 简化集合操作;
- 使用 Optional 简化判空逻辑;
- JDK8 结合 Lambda 和 Stream 对各种类的增强。
使用 Stream 简化集合操作
Lambda 表达式可以帮我们用简短的代码实现方法的定义,给了我们复用代码的更多可能性。利用这个特性,我们可以把集合的投影、转换、过滤等操作抽象成通用的接口,然后通过 Lambda 表达式传入其具体实现,这也就是 Stream 操作。
我们看一个具体的例子。这里有一段 20 行左右的代码,实现了如下的逻辑:
- 把整数列表转换为 Point2D 列表;
- 遍历 Point2D 列表过滤出 Y 轴 >1 的对象;
- 计算 Point2D 点到原点的距离;
- 累加所有计算出的距离,并计算距离的平均值。
private static double calc(List<Integer> ints) {
//临时中间集合
List<Point2D> point2DList = new ArrayList<>();
for (Integer i : ints) {
point2DList.add(new Point2D.Double((double) i % 3, (double) i / 3));
}
//临时变量,纯粹是为了获得最后结果需要的中间变量
double total = 0;
int count = 0;
for (Point2D point2D : point2DList) {
//过滤
if (point2D.getY() > 1) {
//算距离
double distance = point2D.distance(0, 0);
total += distance;
count++;
}
}
//注意count可能为0的可能
return count >0 ? total / count : 0;
}
现在,我们可以使用 Stream 配合 Lambda 表达式来简化这段代码。简化后一行代码就可以实现这样的逻辑,更重要的是代码可读性更强了,通过方法名就可以知晓大概是在做什么事情。比如:
- map 方法传入的是一个 Function,可以实现对象转换;
- filter 方法传入一个 Predicate,实现对象的布尔判断,只保留返回 true 的数据;
- mapToDouble 用于把对象转换为 double;
- 通过 average 方法返回一个 OptionalDouble,代表可能包含值也可能不包含值的可空 double。
下面的第三行代码,就实现了上面方法的所有工作:
List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
double average = calc(ints);
double streamResult = ints.stream()
.map(i -> new Point2D.Double((double) i % 3, (double) i / 3))
.filter(point -> point.getY() > 1)
.mapToDouble(point -> point.distance(0, 0))
.average()
.orElse(0);
Java 8 类对于函数式 API 的增强
要通过 HashMap 实现一个缓存的操作,在 Java 8 之前我们可能会写出这样的 getProductAndCache 方法:先判断缓存中是否有值;如果没有值,就从数据库搜索取值;最后,把数据加入缓存。
private Map<Long, Product> cache = new ConcurrentHashMap<>();
private Product getProductAndCache(Long id) {
Product product = null;
//Key存在,返回Value
if (cache.containsKey(id)) {
product = cache.get(id);
} else {
//不存在,则获取Value
//需要遍历数据源查询获得Product
for (Product p : Product.getData()) {
if (p.getId().equals(id)) {
product = p;
break;
}
}
//加入ConcurrentHashMap
if (product != null)
cache.put(id, product);
}
return product;
}
而在 Java 8 中,我们利用 ConcurrentHashMap 的 computeIfAbsent 方法,用一行代码就可以实现这样的繁琐操作:文章来源:https://www.toymoban.com/news/detail-805946.html
private Product getProductAndCacheCool(Long id) {
return cache.computeIfAbsent(id, i -> //当Key不存在的时候提供一个Function来代表根据Key获取Value的过程
Product.getData().stream()
.filter(p -> p.getId().equals(i)) //过滤
.findFirst() //找第一个,得到Optional<Product>
.orElse(null)); //如果找不到Product,则使用null
}
}
computeIfAbsent 方法在逻辑上相当于:文章来源地址https://www.toymoban.com/news/detail-805946.html
if (map.get(key) == null) {
V newValue = mappingFunction.apply(key);
if (newValue != null)
map.put(key, newValue);
}
到了这里,关于Java 8 简化代码(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!