优秀工具包-Hutool工具详解

课程概述

Hutool简介

  • 定位:

    • 小而全的Java工具库,简化开发流程。
    • 对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装。
  • 核心优势:零依赖、高性能、中文网页完善。

  • 应用场景:Web开发、数据处理、加密解密等。

课程目标

  • 掌握Hutool核心模块的使用方法
  • 理解工具类设计哲学与最佳实践
  • 实现常见开发场景的快速编码

核心模块详解

集合操作

集合创建与判空

传统方式

// 创建集合
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");// 集合判空
if(list == null || list.isEmpty()) {System.out.println("集合为空");
}

Hutool方式

// 一行代码创建集合
List<String> list = CollUtil.newArrayList("a", "b", "c"); //newHashSet// 安全的判空方法
if(CollUtil.isEmpty(list)) {System.out.println("集合为空");
}

优势

  • 集合初始化代码量减少70%
  • 避免NPE风险
  • 代码可读性更强
集合分组
[Emp(name=赵六, dept=技术部, age=23)]
[Emp(name=李四, dept=产品部, age=23), Emp(name=王五, dept=产品部, age=23)]

传统方式

// 分组
Map<String, List<Emp>> groupedMap = new HashMap<>();
for (Emp emp : employees) {String dept = emp.getDept();if (!groupedMap.containsKey(dept)) {groupedMap.put(dept, new ArrayList<>());}groupedMap.get(dept).add(emp);
}
// 转换
List<List<Emp>> list = new ArrayList<>();
for (List<Emp> empList : groupedMap.values()) {list.add(empList);
}

Hutool方式

List<List<Emp>> list = CollUtil.groupByField(employees, "dept");

优势

  • 代码量减少80%
  • 避免手动处理分组逻辑
  • 支持按字段名分组
集合过滤

传统方式

// 过滤
List<Emp> filtered = new ArrayList<>();
for (Emp emp : employees) {if (emp.getAge() > 30 && "研发部".equals(emp.getDept())) {filtered.add(emp);}
}

Hutool方式

List<Emp> filtered = CollUtil.filter(employees, emp -> emp.getAge() > 30 && "研发部".equals(emp.getDept()));

优势

  • 使用Lambda表达式更简洁
  • 链式调用更流畅
  • 可读性更好

IO流 & 文件操作

文件读取

传统方式

/*** 读取文件所有行内容(传统JDK方式)* @param filePath 文件路径* @return 行内容列表*/
public List<String> readFileTraditional(String filePath) {List<String> lines = new ArrayList<>();BufferedReader br = null;try {// 1. 创建缓冲读取器br = new BufferedReader(new FileReader(filePath));String line;// 2. 按行读取并放入集合while ((line = br.readLine()) != null) {lines.add(line);}} catch (IOException e) {// 4. 异常处理System.err.println("读取文件失败: " + e.getMessage());e.printStackTrace();} finally {// 5. 关闭资源(需要嵌套try-catch)try {if (br != null){br.close();}} catch (IOException e) {System.err.println("关闭流失败: " + e.getMessage());}}return lines;
}

传统方式的问题

  • 需要手动管理流对象
  • 异常处理代码占整体代码量的50%以上
  • 资源关闭需要嵌套try-catch,容易遗漏
  • 不支持指定字符编码(默认使用系统编码)
  • 代码行数20多,实际业务逻辑只有5行

Hutool方式

/*** 读取文件所有行内容(Hutool方式)* @param filePath 文件路径* @return 行内容列表*/
public List<String> readFileByHutool(String filePath) {// 指定UTF-8编码读取(自动关闭资源)return FileUtil.readLines(filePath, CharsetUtil.UTF_8);
}

优势

  • 代码量减少70%
  • 指定字符编码更简单
  • 自动关闭资源
文件拷贝

传统方式

try (InputStream in = new FileInputStream("source.txt");OutputStream out = new FileOutputStream("target.txt")) {byte[] buffer = new byte[1024];int length;while ((length = in.read(buffer)) != -1) {out.write(buffer, 0, length);}
} catch (IOException e) {e.printStackTrace();
}

Hutool方式

FileUtil.copy("source.txt", "target.txt", true);// true 如果目标文件已存在,则覆盖它

优势

  • 代码量减少90%
  • 自动处理资源关闭
  • 支持覆盖选项
关闭流

传统方式:

try {if (stream != null) {stream.close();}
} catch (IOException e) {e.printStackTrace();
}

Hutool方式

IoUtil.close(stream);

如果用上面传统方式的编码进行关闭流的实现,当第三方机构对代码进行安全扫描时,就不能通过。

流转换为字符串

传统方式

// 将inputStream流中的内容读取出来并使用String接收
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
){String line;while ((line = reader.readLine()) != null) {sb.append(line);}
} catch (IOException e) {e.printStackTrace();
}
String content = sb.toString();

Hutool方式

String content = IoUtil.read(inputStream, StandardCharsets.UTF_8);

优势

  • 代码量减少80%
  • 自动处理字符编码
  • 自动关闭资源

JDK8时间API增强

日期格式化与解析

传统方式

// 格式化
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDate = now.format(formatter); // "2025-08-09 14:30:45"// 解析
String dateStr = "2025-08-09 14:30:45";
LocalDateTime parsedDate = LocalDateTime.parse(dateStr, formatter);

Huto增强方式

// 格式化
String str = LocalDateTimeUtil.format( LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss");
// 或使用预定义格式
String str = LocalDateTimeUtil.format(now, DatePattern.NORM_DATETIME_PATTERN);// 解析
LocalDateTime date = LocalDateTimeUtil.parse("2023-08-20 14:30:45","yyyy-MM-dd HH:mm:ss");

优势

  • 内置线程安全的格式化器缓存
  • 支持DatePattern中所有标准格式
  • 更简洁的API
日期比较

传统方式:

LocalDateTime startTime = LocalDateTime.of(2025,8,1,0,0,0);
LocalDateTime endTime = LocalDateTime.of(2025,8,30,23,59,59);
LocalDateTime now = LocalDateTime.now();// 判断当前时间是否在指定的区间内
boolean isInRange = now.isAfter(startTime) && now.isBefore(endTime);

Hutool增强方式

boolean isIn = LocalDateTimeUtil.isIn(now, start, end);  // 是否在区间内
日期范围

传统方式:

// 获取当天开始时间(2025-08-10 00:00:00)
LocalDateTime todayStart = LocalDateTime.now()          // 当前时间.truncatedTo(ChronoUnit.DAYS);                     // 截断到天
// 获取当天结束时间(2025-08-10 23:59:59)
LocalDateTime todayEnd = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS)  // 截断到天.plusDays(1)                   // 加一天.minusNanos(1000000);     	   // 减去一毫秒(1000000纳秒)

Hutool增强方式:

// 获取当天的起始时间 
LocalDateTime dayStart = LocalDateTimeUtil.beginOfDay(LocalDate.now()); // 5.8.28版本
LocalDateTime dayStart = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
// 获取当天结束时间
LocalDateTime dayEnd = LocalDateTimeUtil.endOfDay(LocalDateTime.now());

扩展:

Date 转 LocalDateTime

Date date = new Date();     
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();// Hutool写法
LocalDateTime localDateTime = DateUtil.toLocalDateTime(date);

Date 转 LocalDate

Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

Date转LocalTime

Date date = new Date();
// 转换为 LocalDateTime
LocalTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalTime();

LocalDateTime 转 LocalDate

LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();

序列化操作

JSON序列化与反序列化

传统方式(Jackson)

若完全基于Jdk提供的原生API去实现序列化,生成的数据是二进制格式,不是人类可读的JSON格式。这里不做展示。

Hutool方式

// 将Student对象转成json字符串
String json = JSONUtil.toJsonStr(student);
// 将json字符串转成Student对象
Student student = JSONUtil.toBean(json, Student.class);// 将List<Student>转成json字符串
ArrayList<Student> students = CollUtil.newArrayList(new Student("张三", 18, List.of("java", "python", "c++")),new Student("李四", 18, List.of("java", "python", "c++")),new Student("王五", 18, List.of("java", "python", "c++")));
String studentsStr = JSONUtil.toJsonStr(students);
// 将json字符串转成List<Student>
List<Student> list = JSONUtil.toList(studentsStr, Student.class);

序列化:将对象转换为字符串。

反序列化:将字符串转换为对象。

优势

  • 代码更简洁

  • 无需手动处理异常和类型转换

  • 不需要实现Serializable

扩展:

其他序列化工具:

  • Jackson
    • 组织:com.fasterxml.jackson.core
    • 维护者:FasterXML 公司
    • 是 Spring Boot 默认的 JSON 处理库
  • Fastjson
    • 组织:com.alibaba
    • 维护者:阿里巴巴
    • 是阿里巴巴开源的 JSON 处理库

字符串操作

字符串格式化

传统方式

String name = "lisi";
int age = 23;
double score = 98.5;String s = String.format("姓名:%s,年龄:%d,分数:%.2f", name, age,score);

Hutool方式

StrUtil.format("姓名:{},年龄:{},分数:{}", name, age, score);

优势

  • 不需要记忆各种格式化符号
  • 统一的占位符语法,更简洁易懂
  • 减少格式化错误的可能性
字符串判空

传统方式

String str = "  ";
boolean isEmpty = str == null || str.trim().isEmpty();

Hutool方式

boolean isBlank = StrUtil.isBlank("  ");

优势

  • 自动处理null值
  • 自动去除空白字符判断
  • 代码简洁明了
严格空判断

传统方式

String str = "";
boolean isEmpty = str == null || str.isEmpty();

Hutool方式

boolean isEmpty = StrUtil.isEmpty("");

优势

  • 严格判断空字符串(不包括空白字符)
  • 自动处理null值
  • 方法名语义更明确

与isBlank区别

StrUtil.isEmpty("  ");  // false
StrUtil.isBlank("  ");  // true
安全字符串比较

传统方式

String a = null;
String b = "test";
boolean eq = a != null && a.equals(b);  // a.equals(b)可能NullPointerException 

Hutool方式

boolean eq = StrUtil.equals(null, "test");  // false

优势

  • 完全避免NullPointerException
  • 可以比较null值
  • 语义更明确

Bean操作

对象属性拷贝

传统方式

// 需要手动拷贝每个属性
Student student = new Student("张三", 18, List.of("java", "python", "c++"));
Student student1 = new Student();
student1.setName(student.getName());
student1.setAge(student.getAge());
student1.setLikes(student.getLikes());
System.out.println(student1);//若需要忽略某些属性、处理 null 值、转换日期格式等,需要手动编写大量逻辑,代码复用性差。

Hutool方式

// 将源对象的属性值复制到目标对象中 (目标对象要存在)
BeanUtil.copyProperties(source, target);// 根据源对象创建目标类的实例,并复制属性值,返回新对象 (目标对象不存在)
User target = BeanUtil.copyProperties(source, Student.class);// 忽略null值 + 忽略指定属性 + 日期格式转换   5.7.0 +版有
CopyOptions options = CopyOptions.create().setIgnoreNullValue(true)  // 忽略null值.setIgnoreProperties("id") // 忽略id属性.setDatePattern("yyyy-MM-dd"); // 日期格式化
BeanUtil.copyProperties(source, target, options);

优势

  • 代码简洁
  • 自动拷贝同名属性
  • 支持不同类型转换
  • 复杂格式复用性强
对象与 Map 互转

传统实现:

// 原生方式:Bean转Map
Map<String, Object> map = new HashMap<>();
map.put("name", user.getName());
map.put("age", user.getAge());
// ... 每个属性都要手动put// 原生方式:Map转Bean
User user = new User();
user.setName(map.get("name"));
user.setAge(Integer.parseInt(map.get("age")));
// ... 每个属性都要手动get

Hutool方式

// Bean转Map
Map<String, Object> map = BeanUtil.beanToMap(user);// Map转Bean
User user = BeanUtil.mapToBean(map, User.class, true); // true 是否转换为驼峰命名

优势:

  • 自动完成属性与键值的映射,
  • 嵌套属性
  • 类型自动转换

进阶功能与设计思想

设计哲学

  • 链式调用:如StrUtil.builder().append().toString()
  • 智能默认值:避免空指针(如Convert.toInt(null, 0)
  • 低侵入性:静态方法封装,零配置集成

性能优化技巧

  • 复用工具实例(如SecureUtil.aes(key)生成单例)
  • 大文件处理:流式读写避免内存溢出

扩展能力

  • 自定义工具类继承(如扩展XXXUtil
  • 模块化引入(按需选择hutool-core或全量依赖)

实战案例

环境准备

在开始前,请确保项目中已引入Hutool核心依赖:

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.39</version>
</dependency>

案例1:RandomUtil工具 - 随机数据生成专家

功能特性
  • 多样化生成:支持随机数、字符串、日期、中文名等
  • 安全可靠:基于加密算法的随机数生成
  • 灵活配置:可自定义长度、范围、字符集
典型应用场景
  1. 双色球号码生成

    通过randomEle()方法实现彩票系统随机选号:

    // 生成红球(1-33选6)和蓝球(1-16选1)
    String redBalls = RandomUtil.randomEle(getRedBalls()/*获取红球的列表*/, 6).stream().map(i -> String.format("%02d", i))/*格式化*/.collect(Collectors.joining(" "));
    String blueBall = String.valueOf(RandomUtil.randomInt(1, 16));
    System.out.println("双色球号码:" + redBalls + " + " + blueBall);
    
  2. 企业级数据脱敏

    生成随机测试数据替代敏感信息:

    // 生成随机中文姓名
    String chineseName = RandomUtil.randomChineseName();//用RandomUtil.randomChinese()实现单个随机中文字符
    // 生成随机公司名称
    String companyName = RandomUtil.randomStringUpper(5); // 5位含大写字母
    
  3. 分布式ID生成

    结合时间戳生成唯一ID:

    long timestamp = System.currentTimeMillis();
    String uniqueId = timestamp + "-" + RandomUtil.randomString(6);
    

案例2:TreeUtil工具 - 树形结构构建大师

功能特性
  • 零递归构建:自动处理父子关系
  • 灵活配置:支持自定义节点属性映射
  • 高效转换:数据库数据→树形结构一键转换
典型应用场景
  1. 部门组织架构展示

    将扁平化数据转换为树形层级:

    // 定义节点实体(需继承TreeNode)
    @Data
    public class DeptNode extends TreeNode<Integer> {private String deptName;private String manager;
    }// 构建树形结构
    List<DeptNode> deptList = getDataFromDB(); // 从数据库获取数据
    List<Tree<Integer>> tree = TreeUtil.build(deptList, 0, config -> {config.setIdKey("id").setParentIdKey("parentId").setNameKey("deptName").putExtra("manager", node -> getManagerName(node.getId()));
    });
    
  2. 菜单权限管理系统

    我们假设要构建一个菜单,可以实现系统管理和店铺管理,菜单的样子如下:

    系统管理|- 用户管理|- 添加用户店铺管理|- 商品管理|- 添加商品
    

    那这种结构如何保存在数据库中呢?一般是这样的:

    idparentIdnameweight
    10系统管理5
    111用户管理10
    1111用户添加11
    20店铺管理5
    212商品管理10
    2212添加添加11

    动态生成前端菜单树:

    // 构建node列表
    List<TreeNode<String>> nodeList = CollUtil.newArrayList();nodeList.add(new TreeNode<>("1", "0", "系统管理", 5));
    nodeList.add(new TreeNode<>("11", "1", "用户管理", 222222));
    nodeList.add(new TreeNode<>("111", "11", "用户添加", 0));
    nodeList.add(new TreeNode<>("2", "0", "店铺管理", 1));
    nodeList.add(new TreeNode<>("21", "2", "商品管理", 44));
    nodeList.add(new TreeNode<>("221", "2", "商品管理2", 2));// 0表示最顶层的id是0
    List<Tree<String>> treeList = TreeUtil.build(nodeList, "0");//配置
    TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
    // 自定义属性名 都要默认值的
    treeNodeConfig.setWeightKey("order");
    treeNodeConfig.setIdKey("rid");
    // 最大递归深度
    treeNodeConfig.setDeep(3);//转换器
    List<Tree<String>> treeNodes = TreeUtil.build(nodeList, "0", treeNodeConfig,(treeNode, tree) -> {tree.setId(treeNode.getId());tree.setParentId(treeNode.getParentId());tree.setWeight(treeNode.getWeight());tree.setName(treeNode.getName());// 扩展属性 ...tree.putExtra("extraField", 666);tree.putExtra("other", new Object());});
    

    若依的菜单权限管理实现与其类似。

  3. 商品分类树形展示

    支持多级分类嵌套:

    // 构建带扩展属性的分类树
    List<Category> categories = categoryService.findAll();
    List<Tree<Long>> categoryTree = TreeUtil.build(categories, 0L, config -> {config.setIdKey("id").setParentIdKey("parentId").setNameKey("categoryName").putExtra("imageUrl", node -> getImageUrl(node.getType()));
    });
    

学习资源与延伸

其他的api,大家可翻阅官网代码示例和Api文档进行学习。

Hutool中文官网:https://hutool.cn/

api文档:https://plus.hutool.cn/apidocs/

GitHub仓库:looly/hutool

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919044.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919044.shtml
英文地址,请注明出处:http://en.pswp.cn/news/919044.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《深度解构:构建浏览器端Redis控制台的WebSocket协议核心技术》

Redis作为高性能的内存数据库,其原生客户端多依赖命令行或桌面应用,而浏览器端控制台的缺失,成为制约Web化管理的关键瓶颈,WebSocket协议的出现,打破了HTTP协议单向通信的局限,为浏览器与Redis服务之间建立持久、双向的实时连接提供了可能。本文将从协议本质、交互逻辑、…

Pushgateway安装和部署,以及对应Prometheus调整

目录Pushgateway简介安装验证Prometheus的配置&#xff1a;其它命令Pushgateway简介 Pushgateway 是 Prometheus 生态系统中的一个组件。主要特点是推送而非拉取&#xff1a;Prometheus 默认采用拉取&#xff08;pull&#xff09;模式收集指标&#xff0c;但 Pushgateway 允许…

JAVA面试汇总(四)JVM(一)

久违的重新写了一篇面试汇总的&#xff0c;关于JVM的一篇&#xff0c;一共三篇&#xff0c;今天写了第一篇&#xff0c;继续重新学习&#xff0c;重新卷起来&#xff0c;come on baby 1.什么情况下会触发类的初始化&#xff1f; &#xff08;1&#xff09;首先是类未被初始化时…

Agent中的memory

rag系列文章目录 文章目录rag系列文章目录前言一、Memory机制作用二、memory分类三、langgraph实践总结前言 众所周知&#xff0c;大模型是无状态的。但是基于大模型的agent一般是有状态的&#xff0c;也就是它有记忆功能。在AI Agent框架中&#xff0c;Memory机制是核心组件之…

AI与IT从业者的未来:替代焦虑还是协作革命?

​​引言&#xff1a;技术渗透与核心命题​​2025年&#xff0c;人工智能技术已从实验室走向产业核心。国务院《关于深入实施“人工智能”行动的意见》推动AI在医疗、制造、金融等领域的规模化落地&#xff0c;全球AI应用用户规模突破2.3亿&#xff0c;生成式AI工具渗透率达16.…

手机版碰一碰发视频系统批量剪辑功能开发,支持OEM贴牌

引言在当今短视频盛行的时代&#xff0c;视频内容的快速生产与分享变得愈发重要。手机版碰一碰发视频系统&#xff0c;借助 NFC 等近场通信技术&#xff0c;实现了便捷的数据交互与视频分享&#xff0c;而在此基础上集成的批量剪辑功能&#xff0c;更是为内容创作者和商家带来了…

Spring AMQP如何通过配置文件避免硬编码实现解耦

在使用Spring AMQP基于注解声明监听者时&#xff0c;可通过抽取常量来避免硬编码&#xff1a;RabbitListener(bindings QueueBinding(exchange Exchange(MQConstant.USER_EXCHANGE),value Queue(MQConstant.USER_QUEUE),key MQConstant.USER_REDIS_BINDING))public void de…

解决zabbix图片中文乱码

要把 Zabbix 前端字体替换为 simkai.ttf&#xff08;楷体&#xff0c;解决乱码常用&#xff09;&#xff0c;按以下步骤操作&#xff1a;1. 确认 simkai.ttf 路径 先找到系统里 simkai.ttf 字体文件&#xff0c;若没有&#xff0c;可从 Windows 系统&#xff08;C:\Windows\Fon…

实例分割-动手学计算机视觉13

介绍 实例分割(instance segmentation)的目的是从图像中分割出每个目标实例的掩模(mask)。与语义分割相比&#xff0c;实例分割不但要区分不同的类别&#xff0c;还要区分出同一种类别下的不同目标实例。如图13-1所示 语义分割的结果中&#xff0c;不同的羊对应的标签是一样的…

水环境遥感分析!R语言编程+多源遥感数据预处理;水体指数计算、水深回归分析、水温SVM预测、水质神经网络建模及科研级可视化制图

系统性地整合R语言编程、遥感数据处理及机器学习建模&#xff0c;涵盖水线提取&#xff08;水体指数与阈值法&#xff09;、水深反演&#xff08;多元回归&#xff09;、水温预测&#xff08;支持向量机&#xff09;、水质评估&#xff08;神经网络&#xff09;等核心内容&…

微信公众号/小程序百万级OpenID自动化获取工具

摘要 本报告详细阐述了微信用户列表数据获取与处理工具的设计思路,包括分页处理机制、频率控制策略、断点续传功能和分布式存储方案。针对微信API调用限制和用户数据规模特点,该工具旨在高效、安全地获取和存储微信用户列表数据,同时严格遵守微信API调用频率限制,确保系统…

物联网系统中传感器到网关到物联网平台的传输路径、协议、原理、用途与架构详解

摘要物联网&#xff08;IoT&#xff09;系统通过传感器、网关和物联网平台实现数据的采集、传输、处理和应用。本文详细分析了传感器到网关再到物联网平台的传输路径&#xff0c;涵盖直接连接、网关中继、边缘计算、多级网关和混合路径五种方式&#xff1b;介绍了短距离&#x…

SpringBoot自动注入配置类初步实现

一.SpringBoot自动装配SpringBoot 的 自动装配&#xff08;Auto-Configuration&#xff09; 是它的核心特性之一&#xff0c;它让开发者可以 "开箱即用"&#xff0c;避免手动配置大量的 XML 或 Java Config。它的核心思想是&#xff1a;"约定优于配置"&…

直播预告|鸿蒙生态中的AI新玩法

想知道鸿蒙生态里 AI 能玩出啥新花样&#xff1f; 8 月 14 日&#xff08;周四&#xff09;20:00 &#xff0c;「开发者・面对面 坚果派特辑 —— 鸿蒙生态中的 AI 新玩法」直播来袭&#xff01; &#x1f50d; 直播亮点抢先看 AI赋能鸿蒙产品开发&#xff1a;将分享如何利用AI…

智能合约:区块链时代的“数字契约革命”

一、技术原理与核心特征1. 定义与本质智能合约是运行在区块链上的自动化程序&#xff0c;通过代码定义业务规则&#xff0c;在预设条件满足时自动执行操作&#xff08;如资金转移、信息更新&#xff09;&#xff0c;无需人工干预。其核心特性包括&#xff1a;自动执行&#xff…

【数据分析】比较SparCC、Pearson和Spearman相关性估计方法在合成组学数据上的表现

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 加载R包 模拟数据 构建网络 RMSE指数计算 画图 总结 系统信息 介绍 在生物信息学和生态学研究中,组学数据的分析越来越依赖于对微生物群落或基因表达数据中物种或基因间相关性的…

Google C++ 风格指南

文章目录背景介绍风格指南的目标C 版本头文件自包含头文件#define 防护包含所需内容前置声明在头文件中定义函数头文件包含顺序与命名规范作用域命名空间内部链接非成员函数、静态成员函数与全局函数局部变量静态与全局变量关于析构的决策关于初始化的决策常见模式thread_local…

安装部署_WVP流媒体

文章目录一、DEV_WVP流媒体开发手册1、搭建流媒体服务clone代码&#xff1a;安装编译器cmake构建和编译项目修改配置文件启动项目2、搭建GB28181协议视频平台安装 jdk, nodejs, maven, git安装redis安装postgresqlclone代码编译前端代码编译后端代码配置文件修改3、设备接入测测…

软件I2C实现(2):I2C协议实现

0 参考资料 I2C 总线规范.pdf 1 I2C协议实现 1.1 SCL、SDA引脚初始化 将SCL、SDA初始化为开漏输出,电平设置为高电平(使用外部上拉电阻拉高)。 /*** @brief 软件I2C初始化** @param sw_i2c_cfg 软件I2C配置指针*/ int sw_i2c_init(sw_i2c_cfg_t *sw_i2c_cfg) {GPIO_InitT…

疯狂星期四文案网第40天运营日记

网站运营第40天&#xff0c;点击观站&#xff1a; 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 今日访问量 今日搜索引擎收录情况 必应秒发秒收 百度收录很慢 网站优化点 优化seo 修复已知bug