【精通函数式编程】(七) Collection在Java8和9中的增强

简介: Collection、Map API在java8以后的版本重大更新就是引入了流,添加了多个默认方法,例如Arrays.asList、.of、remove*、replace*、sort、forEach、merge等等,介绍了变化最大的一个数据结构ConcurrentHashMap

 

前言📫 作者简介:小明java问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫

🏆 Java领域优质创作者、阿里云专家博主、华为云专家🏆

🔥 如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主哦

导读

Collection、Map API在java8以后的版本重大更新就是引入了流,添加了多个默认方法,例如Arrays.asList、.of、remove*、replace*、sort、forEach、merge等等,介绍了变化最大的一个数据结构ConcurrentHashMap

一、集合工厂(Arrays.asList、List.of、Set.of、Map.of)

java8、9引入了新方法,例如Arrays.asList、List.of、Set.of可以很便捷的创建 Collection及其子类

Arrays.asList是一个静态工厂,该方法适用于对象型数据的数组(String、Integer…),不建议使用于基本数据类型的数组(因为会被当成一个整体的对象),将数组与List列表链接起来:当更新其一个时,另一个自动更新,不支持add()、remove()、clear() 等方法

public static void main(String[] args) {
    // 该方法适用于对象型数据的数组(String、Integer…)
    String[] strings = {"aa", "bb", "cc"};
    List<String> stringList = Arrays.asList(strings);
    // 该方法不建议使用于基本数据类型的数组(byte,short,int,long,float,double,boolean)
    int[] ints = new int[]{1, 2, 3};
    List intList = Arrays.asList(ints);
    System.out.println(Arrays.toString(intList.toArray()));
    // 将数组与List列表链接起来:当更新其一个时,另一个自动更新
    stringList.set(0, "dd");
    System.out.println(stringList + " == " + Arrays.toString(strings));
    // java.lang.UnsupportedOperationException
    stringList.add(3, "ee");
}

List.of Arrays.asList、Set.of 创建不可变的set集合,如果有重复值 java.lang.IllegalArgumentException: duplicate element:、Map.of 交替的以列表中的元素作为键值对

public static void main(String[] args) {
    // 该方法适用于对象型数据的数组
    List<String> list = List.of("aa", "bb", "cc");
    // 创建不可变的set集合,如果有重复值 java.lang.IllegalArgumentException: duplicate element:
    Set<String> set = Set.of("aa", "bb", "cc");
    // 交替的以列表中的元素作为键值对
    Map<? extends Serializable, String> map = Map.of(123, "aa", "bb", "cc");
}

二、List、Set方法增强(removeIf、replaceAll、sort)

API是不断演进的,前几讲说过,java想在go、python等语言中保持活力需要不断迭代,不断接收新的需求和适配新型的硬件

removeIf,可以移除集合中满足某个条件的所有元素,作用是按照一定规则过滤集合中的元素,这个方法和 Stream流中的 filter方法不一样,filter不会对数据源改变

replaceAll ,可以对集合中每个元素执行操作并返回替换后的结果集,类似于Stream流中的 map方法,map是生成新元素,replaceAll 是修改集合元素

public static void main(String[] args) {
    List<OrderInfo> orderInfos = Arrays.asList(new OrderInfo("456", BigDecimal.ONE),
            new OrderInfo("123", BigDecimal.TEN));
    // 订单号又小到大排序
    orderInfos.sort(Comparator.comparing(OrderInfo::getOrderId));
    System.out.println(orderInfos);
    // 订单金额又大到小排序
    orderInfos.sort((o1, o2) -> o1.getOrderAmt().compareTo(o2.getOrderAmt()) < 0 ? 1 : -1);
    System.out.println(orderInfos);
    // 注:不可是 .of 工厂创建的集合
    orderInfos.replaceAll(orderInfo -> new OrderInfo("123", BigDecimal.ONE));
    System.out.println(orderInfos);
    // 注:不可是Arrays.asList工厂创建的集合
    orderInfos.removeIf(orderInfo -> "456".equals(orderInfo.getOrderId()));
    System.out.println(orderInfos);
}

sort,Arrays.sort是我们常用来排序数组的方法,不止如此,其实Collections.sort方法中也是直接拿到集合中的元素数组作为入参直接调用Arrays.sort方法的。

网络异常,图片无法展示
|

legacyMergeSort是一个插入排序+分治思想+归并的排序思路,ComparableTimSort算法采取了分治+归并的排序思想,对数组内元素进行排序的,当元素没有具体值时,则会根据数组中的假定的比较器Comparable.compareTo进行元素的比较排序

三、Map方法增强(forEach、Entry.comparingBy*、compute*、remove、replace*、merge)

Map增强最多,增加了多个新方法,forEach 可以遍历map中每个元素,sorted 按照odrId排序,,ap+.entrySet().stream()转换成Streeam流,remove/replace/compute前面介绍过,这里不再追叙。

public static void main(String[] args) {
    Map<String, OrderInfo> orderInfos = Map.of("456", new OrderInfo("456", BigDecimal.ONE),
            "123", new OrderInfo("123", BigDecimal.TEN));
    // forEach 可以遍历map中每个元素
    orderInfos.forEach((odrId, orderInfo) -> System.out.println(odrId));
    // sorted 按照odrId排序
    orderInfos.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(System.out::print);
    System.out.println();
    // merge两个map
    Map<String, OrderInfo> orderInfoMap0 = Map.of("456", new OrderInfo("456", BigDecimal.ONE));
    Map<String, OrderInfo> orderInfoMap1 = Map.of("456", new OrderInfo("456", BigDecimal.ONE));
    Map<String, OrderInfo> orderInfoMap = new HashMap<>(orderInfoMap0);
    orderInfoMap1.forEach((o1, o2) -> orderInfoMap.merge(o1, o2, (k1, k2) -> k2));
    orderInfoMap.entrySet().stream().forEachOrdered(System.out::print);
}

四、ConcurrentHashMap增强

ConcurrentHashMap 改良数据结构,原ConcurrentHashMap使用 桶(数组+链表,List实现),但是数据存储在桶中必然需要hash值访问,如果大量 key 返回一样的hash值,他的查询的时间复杂度就是O(n),为了改善性能改为,数组+链表+红黑树(也叫sorted tree排序树)

ConcurrentHashMap提供了一个新的方法计数,size()方法和mappingCount()方法的有什么异同呢?size()最大值是 Integer 类型的最大值,但是 Map 的 size 可能超过 MAX_VALUE, 所以还有一个方法 mappingCount(),JDK 的建议使用 mappingCount() 而不是size()。KeySetView 将ConcurrentHashMap视图作为Set ,其中可以通过映射到公共值来可选地启用添加。

public static void main(String[] args) {
    Map map = Map.of("456", new OrderInfo("456", BigDecimal.ONE),
            "123", new OrderInfo("123", BigDecimal.TEN));
    ConcurrentHashMap hashMap = new ConcurrentHashMap(map);
    // ConcurrentHashMap计数
    System.out.println(hashMap.mappingCount());
    // set视图
    ConcurrentHashMap.KeySetView keySetView = hashMap.keySet();
    System.out.println(keySetView.getMap());
    System.out.println(keySetView);
}

总结

Collection、Map API在java8以后的版本重大更新就是引入了流,添加了多个默认方法,例如Arrays.asList、.of、remove*、replace*、sort、forEach、merge等等,介绍了变化最大的一个数据结构ConcurrentHashMap

相关文章
|
4月前
|
Java API 容器
Java 8中的函数式编程特性
【5月更文挑战第28天】 本文将深入探讨Java 8中引入的函数式编程特性,包括Lambda表达式、Stream API和Optional类。我们将通过实例和代码示例来展示这些特性如何简化代码、提高可读性和性能。我们还将讨论一些常见的使用场景和最佳实践,以帮助您更好地利用Java 8的函数式编程特性。
|
1月前
|
Java 编译器 开发者
探索Java中的Lambda表达式:简化代码与提升性能
在Java 8中引入的Lambda表达式,不仅改变了我们编写代码的方式,还为提升程序的性能提供了新的可能性。本文将深入探讨Lambda表达式如何简化集合操作和事件处理,以及它们背后对性能优化的贡献。通过实际案例分析,我们将了解Lambda表达式如何使代码更加简洁、易读,同时保持高效执行。
16 0
|
3月前
|
存储 Java 测试技术
滚雪球学Java(56):探究Java中Collection接口,理解集合框架的实现原理
【6月更文挑战第10天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
42 2
滚雪球学Java(56):探究Java中Collection接口,理解集合框架的实现原理
|
3月前
|
Java API 开发者
高效利用Java中的函数式编程特性
高效利用Java中的函数式编程特性
|
4月前
|
存储 算法 Java
java数据结构,列举并解释Java中的集合框架(Collection Framework)。
java数据结构,列举并解释Java中的集合框架(Collection Framework)。
42 0
|
存储 Java 数据库
Java 集合框架概述及Collection接口中常用的方法总结
Java 集合框架概述及Collection接口中常用的方法总结
83 0
|
存储 算法 数据可视化
Java8特性详解 lambda表达式(一):使用篇
Java8特性详解 lambda表达式(一):使用篇
Java8特性详解 lambda表达式(一):使用篇
|
JavaScript 前端开发 Java
Java如何支持函数式编程?
Java是面向对象的语言,无法直接调用一个函数。Java 8开始,引入了函数式编程接口与Lambda表达式,便于开发者写出更少更优雅的代码。什么是函数式编程?函数式编程的特点是什么?本文通过代码实例,从Stream类、Lambda表达式和函数接口这三个语法概念来分享Java对函数式编程的支持。
11079 0
Java如何支持函数式编程?