当前位置: 首页 > news >正文

《SpringBoot篇》26.SpringBoot整合Jackson超详细教程(附Jackson工具类)

陈老老老板🦸
👨‍💻本文专栏:SpringBoot篇(主要讲一些与springboot整合相关的内容)
👨‍💻本文简述:本文讲一下Jackson常见用法,超级详细。
👨‍💻上一篇文章:《SpringBoot篇》25.SpringBoot整合ActiveMQ
👨‍💻有任何问题,都可以私聊我,我能帮得上的一定帮忙,感谢大佬们支持。
🦹我认为人人都可以学好编程,我愿意成为你的领路人!(需内推私聊)

在这里插入图片描述

一、Jackson简介

说明:本篇讲的是Jackson的详细用法,Jackson工具类在文章最后,直接复制粘贴即可使用。 Jackson是公司中必用的组件之一,常用的还用阿里的Fastjson,但是由于一些原因bug与漏洞是在是太多,在注重安全的公司直接被pass,还有就是谷歌的Gson(这个没用过不太了解)。 Spring MVC 的默认 json 解析器便是 Jackson。 Jackson 优点很多。 Jackson 所依赖的 jar 包较少 ,简单易用。与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快;Jackson 运行时占用内存比较低,性能比较好;Jackson 有灵活的 API,可以很容易进行扩展和定制。

额外了解:
Jackson 的 1.x 版本的包名是 org.codehaus.jackson
当升级到 2.x 版本时,包名变为com.fasterxml.jackson

Jackson 有三个核心包,分别是 StreamingDatabidAnnotations,通过这些包可以方便的对 JSON 进行操作.

  • jackson-core:核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
  • jackson-annotations:注解包,提供标准注解功能.
  • jackson-databind :数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。包含上面两个包,只导入这个坐标即可。

运行环境:

  • idea2020.2
  • jdk1.8
  • springboot 2.7.9

下载demo:直接去我的资源下载即可(Jackson实例-附工具类)

二、Json简介

说明: 作为Java开发一定要学习Json,在现在的前后端分离的项目中,Json是最常见的数据交换格式。比如SpringBoot中@RequestBody注解就是作为接收Json格式的注解,在使用Postman进行测试时传输的raw-json也是Json格式数据。

JSON表示结构:
对象数组: 对象结构以”{”大括号开始,以”}”大括号结束,中间部分由0或多个以”,”分隔的”key(关键字)/value(值)”对构成,关键字和值之间以”:”分隔,语法结构如代码。这里给一个示例。

{"array": [1,2,3],"boolean": true,"name": "cllb","null": null,"age": 12345,"object": {"height": 100,"color": "红色"},"string": "陈老老老板"
}

三、springboot整合Jackson

1.创建项目

说明: 创建一个空springboot项目(2.7.9版本)。这里就不过多复述了,创建时将lombok组件选上,十分方便无需再写Get/Set方法。
注意:可以看到导入databind包会自动导入剩下两个包。
在这里插入图片描述

2.导入坐标

说明: 可以看到导入databind包会自动导入剩下两个包。

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.3</version>
</dependency>

在这里插入图片描述

3.配置文件

a.配置文件配置

properties格式:

#指定日期格式,比如yyyy-MM-dd HH:mm:ss,或者具体的格式化类的全限定名
spring.jackson.date-format
#指定日期格式化时区,比如America/Los_Angeles或者GMT+10.
spring.jackson.time-zone
#是否开启Jackson的反序列化
spring.jackson.deserialization
#是否开启json的generators.
spring.jackson.generator
#指定Joda date/time的格式,比如yyyy-MM-ddHH:mm:ss). 如果没有配置的话,dateformat会作为backup
spring.jackson.joda-date-time-format
#指定json使用的Locale.
spring.jackson.locale
#是否开启Jackson通用的特性.
spring.jackson.mapper
#是否开启jackson的parser特性.
spring.jackson.parser
#指定PropertyNamingStrategy(CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES)或者指定PropertyNamingStrategy子类的全限定类名.
spring.jackson.property-naming-strategy
#是否开启jackson的序列化.
spring.jackson.serialization
#指定序列化时属性的inclusion方式,具体查看JsonInclude.Include枚举.
spring.jackson.serialization-inclusion

yml格式:

spring:jackson:#日期格式化date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8#设置空如何序列化default-property-inclusion: non_null    serialization:#格式化输出 indent_output: true#忽略无法转换的对象fail_on_empty_beans: falsedeserialization:#允许对象忽略json中不存在的属性fail_on_unknown_properties: falseparser:#允许出现特殊字符和转义符allow_unquoted_control_chars: true#允许出现单引号allow_single_quotes: true

b.自定义配置

说明: 这里直接将Jackson工具类给大家,自定义配置指的就是工具类中,对于object_mapper的set赋值。什么方法都有,演示也直接使用工具类进行。

package com.clllb.jackson.utils;import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;@Slf4j
public class JacksonUtil {private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();private static final ObjectMapper OBJECT_MAPPER_SNAKE_CASE = new ObjectMapper();// 日期格式化private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";static {//对象的所有字段全部列入OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.ALWAYS);//取消默认转换timestamps形式OBJECT_MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//忽略空Bean转json的错误OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ssOBJECT_MAPPER.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));//忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);}static {//对象的所有字段全部列入OBJECT_MAPPER_SNAKE_CASE.setSerializationInclusion(JsonInclude.Include.ALWAYS);//取消默认转换timestamps形式OBJECT_MAPPER_SNAKE_CASE.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//忽略空Bean转json的错误OBJECT_MAPPER_SNAKE_CASE.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ssOBJECT_MAPPER_SNAKE_CASE.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));//忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误OBJECT_MAPPER_SNAKE_CASE.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//转换为下划线OBJECT_MAPPER_SNAKE_CASE.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);}private JacksonUtil() {}/*** 对象转Json格式字符串** @param obj 对象* @return Json格式字符串*/public static <T> String obj2String(T obj) {if (obj == null) {return null;}try {return obj instanceof String ? (String) obj : OBJECT_MAPPER.writeValueAsString(obj);} catch (JsonProcessingException e) {log.warn("Parse Object to String error : {}", e.getMessage());return null;}}/*** 对象转file* @param fileName* @param obj*/public static void obj2File(String fileName,Object obj){if (obj == null){return;}try {OBJECT_MAPPER.writeValue(new File(fileName),obj);} catch (IOException e) {e.printStackTrace();}}/*** 对象转Json格式字符串; 属性名从驼峰改为下划线形式** @param obj 对象* @return Json格式字符串*/public static <T> String obj2StringFieldSnakeCase(T obj) {if (obj == null) {return null;}try {ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);} catch (JsonProcessingException e) {log.warn("Parse Object to String error : {}", e.getMessage());return null;}}/*** 字符串转换为自定义对象; 属性名从下划线形式改为驼峰** @param str   要转换的字符串* @param clazz 自定义对象的class对象* @return 自定义对象*/public static <T> T string2ObjFieldLowerCamelCase(String str, Class<T> clazz) {if (StringUtils.isEmpty(str) || clazz == null) {return null;}try {ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);} catch (Exception e) {log.warn("Parse String to Object error : {}", e.getMessage());return null;}}/*** 字符串转换为自定义对象(List); 属性名从下划线形式改为驼峰** @param str           要转换的字符串* @param typeReference 自定义对象的typeReference List 对象* @return 自定义对象*/public static <T> List<T> string2ListFieldLowerCamelCase(String str, TypeReference<List<T>> typeReference) {if (StringUtils.isEmpty(str) || typeReference == null) {return null;}try {ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;return objectMapper.readValue(str, typeReference);} catch (Exception e) {log.warn("Parse String to Object error : {}", e.getMessage());return null;}}/*** 对象转Json格式字符串(格式化的Json字符串)** @param obj 对象* @return 美化的Json格式字符串*/public static <T> String obj2StringPretty(T obj) {if (obj == null) {return null;}try {return obj instanceof String ? (String) obj : OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);} catch (JsonProcessingException e) {log.warn("Parse Object to String error : {}", e.getMessage());return null;}}/*** 字符串转换为自定义对象** @param str   要转换的字符串* @param clazz 自定义对象的class对象* @return 自定义对象*/public static <T> T string2Obj(String str, Class<T> clazz) {if (StringUtils.isEmpty(str) || clazz == null) {return null;}try {return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz);} catch (Exception e) {log.warn("Parse String to Object error : {}", e.getMessage());return null;}}/*** 字符串转换为自定义字段转为list* @param str* @param typeReference* @param <T>* @return*/public static <T> T string2Obj(String str, TypeReference<T> typeReference) {if (StringUtils.isEmpty(str) || typeReference == null) {return null;}try {return (T) (typeReference.getType().equals(String.class) ? str : OBJECT_MAPPER.readValue(str, typeReference));} catch (IOException e) {log.warn("Parse String to Object error", e);return null;}}public static <T> T string2Obj(String str, Class<?> collectionClazz, Class<?>... elementClazzes) {JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClazz, elementClazzes);try {return OBJECT_MAPPER.readValue(str, javaType);} catch (IOException e) {log.warn("Parse String to Object error : {}" + e.getMessage());return null;}}
}

4.实体类

说明: 这里创建一个user实体类

package com.clllb.jackson.PO;import lombok.Data;import java.util.List;@Data
public class User {private String username;private Integer age;private List<String> info;private Long userId;
}

项目样图:
在这里插入图片描述

5.测试类

说明: 测试类中直接调工具类中的方法,非常简单,附输出结果。

a.object类型转Json

说明: 使用writeValueAsString方法

  @Testvoid obj2string(){User user = new User();user.setUsername("clllb");user.setAge(24);user.setUserId(1L);List<String> infoList = new ArrayList<>();infoList.add("有一百万");infoList.add("发大财");user.setInfo(infoList);String json = JacksonUtil.obj2String(user);System.out.println(json);}

输出结果:

{"username":"clllb","age":24,"info":["有一百万","发大财"],"userId":1}

b.object类型转file

说明: 使用writeValue方法

  @Testvoid obj2file(){User user = new User();user.setUsername("clllb");user.setAge(24);user.setUserId(1L);List<String> infoList = new ArrayList<>();infoList.add("有一百万");infoList.add("发大财");user.setInfo(infoList);String fileName = "ccccc";JacksonUtil.obj2File(fileName,user);}

输出结果:
在这里插入图片描述

c.string类型转Object自定义类型

说明: 使用readValue方法

 @Testvoid string2obj(){String json = "{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"userId\":11}";User user = JacksonUtil.string2Obj(json, User.class);System.out.println(user);}

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)

d.string类型转Object自定义类型list

说明: 使用readValue方法,传参变为TypeReference typeReference,这里工具类用的重载方法名是相同的。

@Testvoid string2objList(){String json = "[{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"userId\":11},\n" +"{\"username\":\"陈老老老板\",\"age\":25,\"info\":[\"有一千万\",\"发大大财\"],\"userId\":12}]";List<User> user = JacksonUtil.string2Obj(json, new TypeReference<List<User>>(){});user.forEach(System.out::println);}

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)
User(username=陈老老老板, age=25, info=[有一千万, 发大大财], userId=12)

e.object类型转String(驼峰转下划线)

说明: 使用writeValueAsString方法,这里区别看工具类就会发现,就是多了一个设置OBJECT_MAPPER_SNAKE_CASE.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);

 @Testvoid obj2sringSnakeCase(){User user = new User();user.setUsername("clllb");user.setAge(24);user.setUserId(11L);List<String> infoList = new ArrayList<>();infoList.add("有一百万");infoList.add("发大财");user.setInfo(infoList);String json = JacksonUtil.obj2StringFieldSnakeCase(user);System.out.println(json);}

输出结果:

{"username":"clllb","age":24,"info":["有一百万","发大财"],"user_id":11}

f.string类型(下划线)转Object类型

<font color = 'red'><b>说明:</font> 使用readValue方法
```java@Testvoid string2obj(){String json = "{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"user_id\":11}";User user = JacksonUtil.string2Obj(json, User.class);System.out.println(user);}

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)

g.string类型(下划线)转Object自定义类型list

说明: 使用readValue方法,传参变为TypeReference typeReference,这里工具类用的重载方法名是相同的。

 @Testvoid string2objSnakeCase(){String json = "[{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"user_id\":11},\n" +"{\"username\":\"陈老老老板\",\"age\":25,\"info\":[\"有一千万\",\"发大大财\"],\"user_id\":12}]";List<User> user = JacksonUtil.string2ListFieldLowerCamelCase(json, new TypeReference<List<User>>(){});user.forEach(System.out::println);}

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)
User(username=陈老老老板, age=25, info=[有一千万, 发大大财], userId=12)

总结:工具类非常好用,包含日常所需。Jackson常见用法总结。希望对您有帮助,感谢阅读

结束语:裸体一旦成为艺术,便是最圣洁的。道德一旦沦为虚伪,便是最下流的。
勇敢去做你认为正确的事,不要被世俗的流言蜚语所困扰。

相关文章:

《SpringBoot篇》26.SpringBoot整合Jackson超详细教程(附Jackson工具类)

陈老老老板&#x1f9b8;&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;SpringBoot篇&#xff08;主要讲一些与springboot整合相关的内容&#xff09;&#x1f468;‍&#x1f4bb;本文简述&#xff1a;本文讲一下Jackson常见用法&#xff0c;超级详细。&#x1f468;‍&am…...

Redis 如何实现库存扣减操作和防止被超卖?

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…...

(Linux)Ubuntu查看系统版本

uname -a : 查看操作系统的发行版号和操作系统版本 Command: uname -aResult: Linux SERVER 5.19.0-35-generic #36-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 3 18:36:56 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux uname -v : 查看版本号 Command: uname -vResult: #36-Ubuntu …...

VxWorkds 内存管理(3)

虚拟内存管理 对于带MMU的目标板&#xff0c;VxWorks提供虚拟内存的支持&#xff0c;VxWorks提供了两种虚拟内存管理单元(MMU)的支持: 基本MMU和VxVMI 基本MMU邦定于VxWorks中&#xff0c;可以通过config.h中宏定义INCLUDE MMU BASIC或Tornado工程配置中包含基本MMU组件 VxV…...

单元测试、反射、注解、动态代理

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录单元测试、反射、注解、动态代理单元测…...

【数据结构】夯实基础|线性表刷题01

作者&#xff1a;努力学习的大一在校计算机专业学生&#xff0c;热爱学习和创作。目前在学习和分享&#xff1a;算法、数据结构、Java等相关知识。博主主页&#xff1a; 是瑶瑶子啦所属专栏: 【数据结构|刷题专栏】&#xff1a;该专栏专注于数据结构知识&#xff0c;持续更新&a…...

Java怎么实现几十万条数据插入(30万条数据插入MySQL仅需13秒)

本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。 30万条数据插入插入数据库验证实体类、mapper和配置文件定义User实体mapper接口mapper.xml文件jdbc.propertiessqlMapConfig.xml不分批次直接梭哈循环逐条插入MyBatis实现插入30万条数据JDBC实现插入30万条数…...

java多线程之线程的六种状态

线程的六种状态(1) NEW(初始状态)(2) TERMINATED(终止状态 / 死亡状态)(3) RUNNABLE(运行时状态)(4) TIMED_WAITING(超时等待状态)(5) WAITING(等待状态)(6) BLOCK(阻塞状态)sleep和wait的区别:操作系统里的线程自身是有一个状态的,但是java Thread 是对系统线程的封装,把这里的…...

UnixBench----x86架构openEuler操作系统上进行性能测试

【原文链接】UnixBench----x86架构openEuler操作系统上进行性能测试 &#xff08;1&#xff09;打开github上 UnixBench 地址&#xff0c;找到发布的tag &#xff08;2&#xff09;找到tar.gz包&#xff0c;右键复制链接 比如这里是 https://github.com/kdlucas/byte-unix…...

于Java8 Stream教程之collect()

目录 前言正文第一个小玩法 将集合通过Stream.collect() 转换成其他集合/数组&#xff1a;第二个小玩法 聚合&#xff08;求和、最小、最大、平均值、分组&#xff09;总结前言 本身我是一个比较偏向少使用Stream的人&#xff0c;因为调试比较不方便。 但是, 不得不说&#…...

Python

1、str 三个关键点&#xff1a; 正着数&#xff0c;0&#xff0c;1&#xff0c;2 反着数&#xff0c;0&#xff0c;-1&#xff0c;-2 str[a&#xff0c;b] 左闭右开 [a&#xff0c;b) str123456789 print(str) # 输出字符串 print(str[0:-1]) # 输…...

Spring框架中IOC和DI详解

Spring框架学习一—IOC和DI 来源黑马Spring课程&#xff0c;觉得挺好的 目录 文章目录Spring框架学习一---IOC和DI目录学习目标第一章 Spring概述1、为什么要学习spring&#xff1f;2、Spring概述【了解】【1】Spring是什么【2】Spring发展历程【3】Spring优势【4】Spring体系…...

本地快速搭建Kubernetes单机版实验环境(含问题解决方案)

Kubernetes是一个容器编排系统&#xff0c;用于自动化应用程序部署、扩展和管理。本指南将介绍Kubernetes的基础知识&#xff0c;包括基本概念、安装部署和基础用法。 一、什么是Kubernetes&#xff1f; Kubernetes是Google开发的开源项目&#xff0c;是一个容器编排系统&…...

FPGA控制DDS产生1CLK周期误差的分析(二)

前文简短的介绍了DDS的产生原理&#xff0c;其实相当的简单&#xff0c;所以也不需要多做解释&#xff0c;本文详细阐述一下在调试DDS的过程中所产生的一个bug 问题发现 正如上文所述&#xff0c;再用FPGA控制存储在rom中的波形信号输出之后&#xff0c;在上板之前&#xff0…...

这一次,吃了Redis的亏,也败给了GPT

关注【离心计划】&#xff0c;一起离开地球表面 背景 组内有一个系统中有一个延迟任务的需求&#xff0c;关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案&#xff0c;关于时间轮&#xff0c;这边小苏有一个大学时候做的demo&#xff1a; https://github.com/JA…...

第一章 信息化知识

1、信息是客观事物状态和运动特征的一种普遍形式&#xff0c;信息的概念存在两个基本的层次&#xff0c;即本体论层次和认识论层次&#xff1a; 本体论层次&#xff1a;就是事物的运动状态和状态变化方式的自我表述认识论层次&#xff1a;就是主体对于该事物的运动状态以及状态…...

如何用matlab工具箱训练一个SOM神经网络

本站原创文章&#xff0c;转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com本文展示如何用matlab工具箱训练一个SOM神经网络的DEMO并讲解其中的代码含义和相关使用说明- 01.SOM神经网络DEMO代码 -- 本文说明 -下面&#xff0c;我们先随机初始化一些样本点&#xff0c;然后…...

音视频技术开发周刊 | 285

每周一期&#xff0c;纵览音视频技术领域的干货。新闻投稿&#xff1a;contributelivevideostack.com。GPT-4 Office全家桶发布谷歌前脚刚宣布AI工具整合进Workspace&#xff0c;微软后脚就急匆匆召开了发布会&#xff0c;人狠话不多地祭出了办公软件王炸——Microsoft 365 Cop…...

安装flume

flume最主要的作用就是实时读取服务器本地磁盘的数据&#xff0c;将数据写入到hdfs中架构&#xff1a;开始安装一&#xff0c;上传压缩包&#xff0c;解压并更名解压&#xff1a;[rootsiwen install]# tar -zxf apache-flume-1.9.0-bin.tar.gz -C ../soft/[rootsiwen install]#…...

为工作排好优先级

工作&#xff0c;是干不完的&#xff0c;因此我们需要分清轻重缓急&#xff0c;为它们划分优先级&#xff0c;这样才不至于让自己手忙脚乱。 给手头的事情排上正确的优先级&#xff0c;是一项很重要的工作能力。 优先级有很多考量&#xff0c;并不是简单的先来后到的线性时间…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...