提高Java程序效率:ImmutableList、Stream API 和 JSON序列化实战指南

news/2024/8/26 18:53:40 标签: java, json, 编程优化

常用列表构建方法:

1.ImmutableList.of() : 静态方法、不可变的列表

可以接受任意数量的参数,并将它们作为元素添加到新创建的列表中,但是一旦创建,集合的内容就不能被改变。在多线程环境中非常有用,因为它可以避免并发修改异常,并且可以安全地在多个线程之间共享。

使用 ImmutableList.of() 创建的列表是线程安全的,并且具有高效的性能,因为它们是预先计算和缓存的,这使得访问元素非常快速。

此外,由于列表是不可变的,所以它们是不可变的集合的一个很好的选择,可以作为函数的返回值,或者作为对象的属性,以确保集合的内容不会被外部代码修改。

2.Lists.newArrayList() : 用于快速创建一个空的 ArrayList, 或者从已有的集合或数组中创建一个新的 ArrayList。可变的,可以添加、删除或修改其中的元素。

流中map和flatMap的使用场景

在Java的Stream API中,map 和 flatMap 是两个常用的方法,它们都用于转换流中的元素,但使用场景和转换的方式有所不同。

使用 map 的情况

map 方法用于将流中的每个元素转换成另一种形式或类型,但是它不会改变流中元素的数量。map 通常用于一对一的转换。

例子: 假设你有一个 List 包含员工对象,每个员工对象都有一个 getName() 方法返回员工的名字。如果你想要得到一个包含所有员工名字的 List,你可以使用 map 方法:

List<Employee> employees = ...; // 员工列表
List<String> names = employees.stream()
    .map(Employee::getName) // 将每个员工对象转换为名字
    .collect(Collectors.toList());

使用 flatMap 的情况

flatMap 方法用于将流中的每个元素转换成另一个流,然后将这些流合并成一个流。flatMap 通常用于一对多的转换。

例子: 假设你有一个 List 包含订单对象,每个订单对象都有一个 getItems() 方法返回该订单包含的商品列表。如果你想要得到一个包含所有订单中所有商品的 List,你可以使用 flatMap 方法:

List<Order> orders = ...; // 订单列表
List<Item> items = orders.stream()
    .flatMap(order -> order.getItems().stream()) // 将每个订单转换为商品列表
    .collect(Collectors.toList());

在这个例子中,每个订单可能包含多个商品,flatMap 将每个订单的 getItems() 方法返回的 List<Item> 流化,并合并这些流,最终得到一个包含所有商品的 List<Item>。

总结

  • 使用 map 当你需要将流中的每个元素转换成另一个对象或值,且转换是一对一的。
  • 使用 flatMap 当你需要将流中的每个元素转换成一个流(或集合),并且想要将这些流合并成一个更大的流,且转换是一对多的。

flatMap 可以看作是 map 和 flatten 的组合,即先映射(map),然后将结果展平(flatten)成一个单一的流。

预编译正则表达式

正则表达式的预编译是指将正则表达式的字符串模式编译成一个 Pattern 对象。编译过程是比较耗时的操作,如果在方法体内定义,每次方法调用时都会重新编译正则表达式,增加了不必要的开销。因此,推荐在类的静态成员中预先编译正则表达式,并在需要时直接使用预编译的 Pattern 对象。

public class XxxClass {
    // Use precompile
    private static final Pattern NUMBER_PATTERN = Pattern.compile("[0-9]+");

    public Pattern getNumberPattern() {
        // Return the precompiled pattern
        return NUMBER_PATTERN;
    }
}

这样修改后,每次调用 getNumberPattern() 方法时都会返回同一个预编译的 Pattern 对象,避免了重复编译的开销,提高了运行效率。

所有的包装类对象之间值的比较,全部使用equals方法比较。

  1. 对于Integer var=?在-128至127之间的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。
Integer a = 235;
Integer b = 235;
if (a.equals(b)) {
    // code
}

SimpleDateFormat(线程不安全)

在Java 1.8之后,SimpleDateFormat存在线程安全问题,因为它是非线程安全的。多线程环境中使用SimpleDateFormat可能会导致不可预测的结果。

JDK1.8后用:

private static final DateTimeFormatter dateTimeFormatter = 
DateTimeFormatter.ofPattern("yyMMddHHmmss");

JSON对象转string性能

  1. List<String>数组,转String对象输出
List<String> list = new ArrayList<>();
for(int i=0; i<2000000; i++){
    list.add(RandomString.get().randomAlphaNumeric(5));
}
long startone = System.currentTimeMillis();
cn.hutool.json.JSONUtil.toJsonStr(list);
long endone = System.currentTimeMillis();
System.out.println("cn.hutool.json.JSONUtil time:"+(endone-startone));
com.alibaba.fastjson.JSON.toJSONString(list);
long endtwo = System.currentTimeMillis();
System.out.println("com.alibaba.fastjson.JSON time:"+(endtwo-endone));
com.alibaba.fastjson2.JSON.toJSONString(list);
long endthree = System.currentTimeMillis();
System.out.println("com.alibaba.fastjson2.JSON time:"+(endthree-endtwo));
  1. 100个
    1. cn.hutool.json.JSONUtil time:14
    2. com.alibaba.fastjson.JSON time:55
    3. com.alibaba.fastjson2.JSON time:80
  1. 1000个
    1. cn.hutool.json.JSONUtil time:16
    2. com.alibaba.fastjson.JSON time:55
    3. com.alibaba.fastjson2.JSON time:85
  1. 10000个
    1. cn.hutool.json.JSONUtil time:24
    2. com.alibaba.fastjson.JSON time:69
    3. com.alibaba.fastjson2.JSON time:101
  1. 100000个
    1. cn.hutool.json.JSONUtil time:75
    2. com.alibaba.fastjson.JSON time:96
    3. com.alibaba.fastjson2.JSON time:93
  1. 1000000个
    1. cn.hutool.json.JSONUtil time:319
    2. com.alibaba.fastjson.JSON time:159
    3. com.alibaba.fastjson2.JSON time:124
  1. 2000000个
    1. cn.hutool.json.JSONUtil time:576
    2. com.alibaba.fastjson.JSON time:255
    3. com.alibaba.fastjson2.JSON time:132

结论:

  • 对于小规模数据的 JSON 序列化任务,Hutool 是一个很好的选择。
  • 对于大规模数据的 JSON 序列化任务,建议使用 Fastjson2,以获得更高的性能。


http://www.niftyadmin.cn/n/5558368.html

相关文章

linux后门教程

linux后门教程 alias 用法 系统默认别名&#xff1a;alias 设置别名&#xff1a;alias lsls -laih 删除别名&#xff1a;unalias ls **加参数&#xff1a;**alias ls‘ls -laih;pwd’ 注意 系统启动默认加载的配置文件 /etc/profile 切换用户就会执行/etc/profile /etc/bash…

Unsloth 微调 Llama 3

本文参考&#xff1a; https://colab.research.google.com/drive/135ced7oHytdxu3N2DNe1Z0kqjyYIkDXp 改编自&#xff1a;https://blog.csdn.net/qq_38628046/article/details/138906504 文章目录 一、项目说明安装相关依赖下载模型和数据 二、训练1、加载 model、tokenizer2、…

JS中对象的方括号[]和点.【对象属性的访问和设置】

在 JavaScript 中&#xff0c;可以使用多种方式来访问和设置对象的属性, 包括点表示法和方括号表示法。 点表示法和方括号表示法 点表示法&#xff1a;使用点号&#xff08;.&#xff09;来访问或设置对象的属性。方括号表示法&#xff1a;使用方括号&#xff08;[]&#xff…

可解释医学视觉问答的反事实因果干预| 文献速递-基于深度学习的多模态数据分析与生存分析

Title 题目 Counterfactual Causal-Effect Intervention for Interpretable Medical Visual Question Answering 可解释医学视觉问答的反事实因果干预 01 文献速递介绍 深度学习的进步在计算机视觉、自然语言处理和信息检索领域成功地取得了最先进的&#xff08;SOTA&…

【Leetcode】二十一、前缀树 + 词典中最长的单词

文章目录 1、背景2、前缀树Trie3、leetcode208&#xff1a;实现Trie4、leetcode720&#xff1a;词典中最长的单词 1、背景 如上&#xff0c;以浏览器搜索时的自动匹配为例&#xff1a; 如果把所有搜索关键字放一个数组里&#xff0c;则&#xff1a;插入、搜索一个词条时&#x…

树莓派docker自制镜像

挂载img文件到目录 cd /a/img tar -czvf rr.tar.gz ./ docker import tt.tar.gz rootpi:/home/pi/2# docker tag ff142da9042f arm7:v01 rootpi:/home/pi/2# docker images REPOSITORY TAG IMAGE ID CREATED SIZE arm7 …

海外媒体发稿:葡萄牙-实现高效媒体软文发稿计划-大舍传媒

一、葡萄牙媒体环境概述 葡萄牙&#xff0c;位于欧洲大陆西南端的国家&#xff0c;拥有丰富的文化和历史。在这个国家&#xff0c;媒体行业也有着相当大的影响力。葡萄牙的媒体环境多元化&#xff0c;包括电视、广播、报纸、杂志和互联网等各个领域。 二、葡萄牙媒体发稿的重…

亲子母婴行业媒体邀约宣发资源

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 亲子母婴行业是一个综合性的产业&#xff0c;涉及多个领域&#xff0c;包括儿童食品&#xff0c;儿童玩具&#xff0c;服装&#xff0c;洗护&#xff0c;月子中心&#xff0c;母婴护理&a…