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:map1
和map2
。然后,我们使用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
接收三个参数:
- key的映射函数,这里使用
Map.Entry::getKey
。 - value的映射函数,这里使用
Map.Entry::getValue
。 - 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方法...@Overridepublic 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集合还有很多操作...