JDK8 新特性和stream流的使用(一)

JDK 8 的新特性包括:

  • Lambda表达式。允许编写更加简洁和灵活的代码,它允许将代码作为参数传递给其他方法或作为函数返回。Lambda表达式使用“->”操作符,并且可以包含一个或多个参数,这些参数的类型由编译器推断得出。123
  • 函数式接口的增强。在接口中可以添加默认方法和静态方法,这增强了接口的可扩展性和功能。14
  • Optional类。用于避免NullPointerException的检查,提供了处理可能为空的对象的便捷方式。13
  • 新的时间和日期API。重新设计了API,支持多线程操作,并且提供了更现代的设计。1
  • 可重复注解。允许在同一个位置放置多个相同的注解。
  • Stream API提供了一种强大的数据操作方式,类似于SQL语句,使得处理集合和数据更加高效和简洁。
  • 并行Stream操作。通过Fork/Join框架提升性能,简化并行编程。
  • 速度优化。包括改进的垃圾回收机制,如元空间的引入代替了永久代,以及数据结构如HashMap的调整。3
  • ConcurrentHashMap的改进。从锁分段机制改为大量CAS操作,同时HashMap和ConcurrentHashMap的结构也从链表改为链表+红黑树。
  • 引入新的Date/Time API。提供了更现代的时间和日期处理方式。4
  • jdeps命令行工具。用于分析类、目录、jar包的类依赖层级关系。
  • MetaSpace取代永久代。JVM使用MetaSpace代替了永久代,以优化内存管理和避免内存溢出。

jdk8 Stream API

      1. map集合value总和

        在Java中,使用Stream API对Map集合的value进行求和操作是一个常见的需求。以下是一个示例,展示了如何使用Stream API来计算Map集合中所有value的总和:

import java.util.HashMap;  
import java.util.Map;  
import java.util.OptionalDouble;  
  
public class MapSumExample {  
    public static void main(String[] args) {  
        Map<String, Integer> map = new HashMap<>();  
        map.put("apple", 1);  
        map.put("banana", 2);  
        map.put("cherry", 3);  
        map.put("date", 4);  
  
        // 使用Stream API计算Map中所有value的总和  
        OptionalDouble sum = map.values().stream()  
                .mapToInt(Integer::intValue) // 将Integer转换为int的Stream  
                .summaryStatistics() // 获取IntSummaryStatistics  
                .getSum(); // 获取总和  
  
        // 如果确定map不为空且value都是非null,可以直接使用sum()  
        double directSum = map.values().stream()  
                .mapToDouble(Integer::doubleValue) // 将Integer转换为double的Stream  
                .sum();  
  
        System.out.println("使用summaryStatistics的总和: " + sum.getAsDouble());  
        System.out.println("直接求和的总和: " + directSum);  
    }  
}

 

在这个例子中,我们首先创建了一个包含字符串键和整数值的Map。然后,我们使用map.values().stream()来获取Map中所有value的Stream。接着,我们使用mapToInt(Integer::intValue)将Stream中的Integer对象转换为int类型的Stream,以便进行数值计算。最后,我们使用sum()方法计算总和。

另外,我们还可以通过summaryStatistics()方法获取一个IntSummaryStatistics对象,它包含了流中元素的各种摘要统计信息,如计数、总和、平均值、最大值和最小值等。在这个例子中,我们只关心总和,所以使用getSum()方法来获取它。

注意,如果Map可能为空或者value可能包含null,那么在求和之前应该进行非空检查。在上面的示例中,我们假设Map不为空且value都是非null。

最后,请注意summaryStatistics()方法可能会在处理大数据集时导致性能下降,因为它需要计算所有的摘要统计信息,而不仅仅是总和。如果只需要计算总和,使用sum()方法会更高效。

2. 合并map切value相同时

如果你想要合并两个Map,并且当key相同时,将它们的value进行加和,你可以使用Stream API结合Collectors.toMap来实现。

思考: 首先创建了两个包含不同键值对的Map:map1map2。然后,我们使用Stream.of(map1, map2)创建一个包含这两个Map的Stream。接着,我们使用flatMap将每个Map的entry集合转换成一个单独的Stream,并合并它们。最后,我们使用Collectors.toMap收集器来创建一个新的Map。

import java.util.HashMap;  
import java.util.Map;  
import java.util.function.BinaryOperator;  
import java.util.stream.Collectors;  
  
public class MergeMapsExample {  
    public static void main(String[] args) {  
        Map<String, Integer> map1 = new HashMap<>();  
        map1.put("apple", 1);  
        map1.put("banana", 2);  
  
        Map<String, Integer> map2 = new HashMap<>();  
        map2.put("banana", 3);  
        map2.put("cherry", 4);  
  
        // 合并两个Map,并对相同key的value进行加和  
        Map<String, Integer> mergedMap = Stream.of(map1, map2)  
                .flatMap(map -> map.entrySet().stream())  
                .collect(Collectors.toMap(  
                        Map.Entry::getKey,  
                        Map.Entry::getValue,  
                        Integer::sum // 当key相同时,使用sum作为合并函数  
                ));  
  
        System.out.println(mergedMap); // 输出: {apple=1, banana=5, cherry=4}  
    }  
}

Collectors.toMap接收三个参数:

  1. key的映射函数,这里使用Map.Entry::getKey
  2. value的映射函数,这里使用Map.Entry::getValue
  3. merge函数,当key冲突时用于合并value。这里我们传递Integer::sum作为merge函数,它将相同key的value相加。

3. 对list集合操作

在Java中,如果你有一个包含对象的List集合,并且这些对象有一个时间属性,你可以使用Stream API的`sorted()`方法来根据时间属性对List中的对象进行升序排序。下面是一个简单的示例,说明如何做到这一点:

首先,假设你有一个`Event`类,它有一个`LocalDateTime`类型的`time`属性:


import java.time.LocalDateTime;

public class Event {
    private LocalDateTime time;
    // 其他属性...

    public Event(LocalDateTime time) {
        this.time = time;
    }

    public LocalDateTime getTime() {
        return time;
    }

    // 其他getter和setter方法...

    @Override
    public String toString() {
        return "Event{" +
                "time=" + time +
                '}';
    }
}

现在,假设你有一个`Event`对象的List集合,你想要根据`time`属性进行升序排序:

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class EventListSortingExample {
    public static void main(String[] args) {
        List<Event> events = new ArrayList<>();
        events.add(new Event(LocalDateTime.of(2023, 3, 10, 15, 0)));
        events.add(new Event(LocalDateTime.of(2023, 3, 9, 10, 0)));
        events.add(new Event(LocalDateTime.of(2023, 3, 11, 8, 0)));

        // 使用Stream API根据时间进行升序排序
        List<Event> sortedEvents = events.stream()
                .sorted((e1, e2) -> e1.getTime().compareTo(e2.getTime()))
                .collect(Collectors.toList());

        // 打印排序后的事件
        sortedEvents.forEach(System.out::println);
    }
}

在上面的代码中,我们创建了一个`Event`对象的List,并使用`stream()`方法将其转换为一个Stream。然后,我们调用`sorted()`方法,并传递一个Comparator,它比较两个`Event`对象的`time`属性。`LocalDateTime`的`compareTo()`方法会根据时间顺序进行比较,从而实现升序排序。最后,我们使用`collect()`方法将排序后的Stream转换回List。

输出将会是根据时间升序排序的`Event`对象列表:

Event{time=2023-03-09T10:00}
Event{time=2023-03-10T15:00}
Event{time=2023-03-11T08:00}

注意:如果`time`属性有可能为`null`,那么在Comparator中需要添加适当的空值检查来避免`NullPointerException`。此外,如果你的List非常大,排序操作可能会消耗较多的内存和CPU时间,因此在实际应用中需要考虑性能因素。

对list集合还有很多操作...

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全能技术师

相关资源在博客首页资源下获取

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值