Hutool 嘎嘎香,开炫了!

在日常开发中,我们会使用很多工具类来提升项目开发的速度,而国内用的比较多的 Hutool 框架,就是其中之一。

先来看官方对于 Hutool 的定义:

Hutool 是一个小而全的 Java 工具类库,通过静态方法封装,降低相关 API 的学习成本,提高工作效率,使 Java 拥有函数式语言般的优雅,让 Java 语言也可以“甜甜的”。

Hutool 中的工具方法来自每个用户的精雕细琢,它涵盖了 Java 开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;

Hutool 是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的 bug。

Hutool 官方文档:https://doc.hutool.cn/

1.包含模块

Hutool 包含以下模块:

模块介绍
hutool-aopJDK 动态代理封装,提供非 IOC 下的切面支持。
hutool-bloomFilter布隆过滤,提供一些 Hash 算法的布隆过滤。
hutool-cache简单缓存实现。
hutool-core核心,包括 Bean 操作、日期、各种Util等。
hutool-cron定时任务模块,提供类 Crontab 表达式的定时任务。
hutool-crypto加密解密模块,提供对称、非对称和摘要算法封装。
hutool-dbJDBC 封装后的数据操作,基于 ActiveRecord思想。
hutool-dfa基于 DFA 模型的多关键字查找。
hutool-extra扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等)。
hutool-http基于 HttpUrlConnection 的 Http 客户端封装。
hutool-log自动识别日志实现的日志门面。
hutool-script脚本执行封装,例如 Javascript。
hutool-setting功能更强大的 Setting 配置文件和 Properties 封装。
hutool-system系统参数调用封装(JVM 信息等)。
hutool-jsonJSON 实现。
hutool-captcha图片验证码实现。
hutool-poi针对 POI 中 Excel 和 Word 的封装。
hutool-socket基于 Java 的 NIO 和 AIO 的 Socket 封装。
hutool-jwtJSON Web Token(JWT)封装实现。

2.引入框架

首先,在项目的 pom.xml 的 dependencies 中加入以下内容:

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

3.常见使用场景

3.1 HTTP 请求类

在 Java 中,Apache 的 HttpClient 用的比较多,但是由于此包较为庞大,API 又比较难用,因此并不适用很多场景,而 Hutool 的 Hutool-http 针对 JDK 的 HttpUrlConnection 做一层封装,简化了 HTTPS 请求、文件上传、Cookie 记忆等操作,使 Http 请求变得无比简单。

具体使用,例如发送一个 GET 请求:

// GET请求
String content = HttpUtil.get(url);

发送一个 POST 请求:

// POST 请求
HashMap<String, Object> param = new HashMap<>();
paramMap.put("city", "西安");
String result1 = HttpUtil.post("www.javacn.site", param);

3.2 生成 N 位随机验证码

例如,生成手机验证码(4 位或 6 位),使用 Hutool 的这个功能就再也合适不过了,具体实现代码如下:

// 生成 4 位随机验证码
String verificationCode = RandomUtil.randomStringUpper(4);

3.3 拼音工具

Hutool 封装了拼音的门面,用于兼容以下拼音库:

  1. TinyPinyin

  2. JPinyin

  3. Pinyin4j

和其它门面模块类似,采用 SPI 方式识别所用的库。例如你想用 Pinyin4j,只需引入 jar,Hutool 即可自动识别。

以下为 Hutool 支持的拼音库的 pom 坐标,你可以选择任意一个引入项目中,如果引入多个,Hutool 会按照以上顺序选择第一个使用。

TinyPinyin 依赖:

<dependency>
  <groupId>io.github.biezhi</groupId>
  <artifactId>TinyPinyin</artifactId>
  <version>2.0.3.RELEASE</version>
</dependency>

JPinyin 依赖:

<dependency>
  <groupId>com.belerweb</groupId>
  <artifactId>pinyin4j</artifactId>
  <version>2.5.1</version>
</dependency>

Pinyin4j 依赖:

<dependency>
  <groupId>com.github.stuxuhai</groupId>
  <artifactId>jpinyin</artifactId>
  <version>1.1.8</version>
</dependency>
① 获取全部拼音
// 输出结果:ni hao
String pinyin = PinyinUtil.getPinyin("你好", " "); 

这里定义的分隔符为空格,你也可以按照需求自定义分隔符,亦或者使用 "" 代表无分隔符。

② 获取拼音首字母
// 输出结果:h, s, d, y, g
String result = PinyinUtil.getFirstLetter("H是第一个", ", "); 
③ 自定义拼音库(拼音引擎)
Pinyin4jEngine engine = new Pinyin4jEngine();
// 输出结果:ni hao h
String pinyin = engine.getPinyin("你好h", " ");

3.4 计时器

Hutool 通过封装 TimeInterval 实现计时器功能,即可以计算方法或过程执行的时间。

具体使用如下:

TimeInterval timer = DateUtil.timer();
// todo:执行具体业务
timer.interval();  // 花费毫秒数
timer.intervalRestart();// 返回花费时间,并重置开始时间
timer.intervalMinute(); // 花费分钟数

也可以实现分组计时:

final TimeInterval timer = new TimeInterval();
// 分组 1
timer.start("1");
ThreadUtil.sleep(1000);
// 分组 2
timer.start("2");
ThreadUtil.sleep(2000);
// 打印时间
Console.log("Timer 1 took {} ms", timer.intervalMs("1"));
Console.log("Timer 2 took {} ms", timer.intervalMs("2"));

3.5 数字工具

NumberUtil 数字工具针对数学运算做工具性封装。

我最喜欢使用它的保留小时和数字格式化,下面一起来看吧。

① 保留小数

保留小数的方法主要有两种:

  • NumberUtil.round 方法主要封装 BigDecimal 中的方法来保留小数,返回 BigDecimal,这个方法更加灵活,可以选择四舍五入或者全部舍弃等模式。

  • NumberUtil.roundStr 方法主要封装 String.format 方法,舍弃方式采用四舍五入。

具体实现如下。

NumberUtil.round 方法使用:

double te1=123456.123456;
double te2=123456.128456;
Console.log(round(te1,4)); // 结果:123456.1235
Console.log(round(te2,4)); // 结果:123456.1285

NumberUtil.roundStr 方法使用:

double te1=123456.123456;
double te2=123456.128456;
Console.log(roundStr(te1,2));//结果:123456.12
Console.log(roundStr(te2,2));//结果:123456.13
② 时间格式化

针对 DecimalFormat.format 进行简单封装。按照固定格式对 double 或 long 类型的数字做格式化操作,具体实现如下:

long c = 299792458; // 光速
String format = NumberUtil.decimalFormat(",###", c); // 299,792,458

格式中主要以 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。

  • 0 -> 取一位整数。

  • 0.00 -> 取一位整数和两位小数。

  • 00.000 -> 取两位整数和三位小数。

  • # -> 取所有整数部分。

  • #.##% -> 以百分比方式计数,并取两位小数。

  • #.#####E0 -> 显示为科学计数法,并取五位小数。

  • ,### -> 每三位以逗号进行分隔,例如:299,792,458。

  • 光速大小为每秒,###米 -> 将格式嵌入文本。

③ 校验数字
  • NumberUtil.isNumber:是否为数字。

  • NumberUtil.isInteger:是否为整数。

  • NumberUtil.isDouble:是否为浮点数。

  • NumberUtil.isPrimes:是否为质数。

④ 随机数
  • NumberUtil.generateRandomNumber 生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组。

  • NumberUtil.generateBySet 生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组。

3.6 数据脱敏

在数据处理或清洗中,可能涉及到很多隐私信息的脱敏工作,因此Hutool针对常用的信息封装了一些脱敏方法。

现阶段支持的脱敏数据类型包括:

  1. 用户 id

  2. 中文姓名

  3. 身份证号

  4. 座机号

  5. 手机号

  6. 地址

  7. 电子邮件

  8. 密码

  9. 中国大陆车牌,包含普通车辆、新能源车辆

  10. 银行卡

整体来说,所谓脱敏就是隐藏掉信息中的一部分关键信息,用*代替,自定义隐藏可以使用 StrUtil.hide 方法完成。

我们以身份证号码为例:

// 5***************1X
DesensitizedUtil.idCardNum("51343620000320711X", 1, 2);

对于约定俗成的脱敏,我们可以不用指定隐藏位数,比如手机号:

// 180****1999
DesensitizedUtil.mobilePhone("18049531999");

当然还有一些简单粗暴的脱敏,比如密码,只保留了位数信息:

// **********
DesensitizedUtil.password("1234567890");

3.7 邮件发送工具

在 Java 中发送邮件主要依靠 javax.mail 包,但是由于使用比较繁琐,因此 Hutool 针对其做了封装  MailUtil,它的使用主要需要两步:

  1. 添加 Java Mail 依赖(因为 MailUtil 是对它的封装)。

  2. 编写邮件发送代码。

① 添加依赖
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
② 编写发送代码
// 发送普通文本邮件,最后一个参数可选是否添加多个附件
MailUtil.send("hutool@foxmail.com", "测试", "邮件来自磊哥测试", false);

// 发送 HTML 格式的邮件并附带附件,最后一个参数可选是否添加多个附件:
MailUtil.send("hutool@foxmail.com", "测试", "<h1>邮件来自磊哥测试</h1>", true, FileUtil.file("d:/aaa.xml"));

// 群发邮件,可选 HTML 或普通文本,可选多个附件:
ArrayList<String> tos = CollUtil.newArrayList( 
    "person1@bbb.com", 
    "person2@bbb.com", 
    "person3@bbb.com", 
    "person4@bbb.com"); 
MailUtil.send(tos, "测试", "邮件来自磊哥群发测试", false);

3.8 布隆过滤器

布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

布隆过滤器的原理是,当一个元素被加入集合时,通过 K 个散列函数将这个元素映射成一个位数组中的 K 个点,把它们置为 1。检索时,我们只要看看这些点是不是都是 1 就(大约)知道集合中有没有它了:如果这些点有任何一个 0,则被检元素一定不在;如果都是 1,则被检元素很可能在。这就是布隆过滤器的基本思想。参考:https://www.cnblogs.com/z941030/p/9218356.html

布隆过滤器的具体使用如下:

// 初始化
BitMapBloomFilter filter = new BitMapBloomFilter(10);
filter.add("123");
filter.add("abc");
filter.add("ddd");

// 查找
filter.contains("abc")

小结

不是代码写不起,而是 Hutool 更有性价比。正如官方描述的那样,使用 Hutool 会有种甜甜的感觉,磨刀不误砍柴工,Hutool 用上之后代码嘎嘎香,快去试试吧~

<think>嗯,用户问的是怎么用数学知识解决商店名称的范式识别问题,比如“周姐东北菜”是品名+品类,“周姐嘎嘎东北菜”是品名+修饰词+品类。首先,我需要理解用户的具体需求。可能他们想自动化识别商店名称的结构,用于分类或者数据整理,比如在电商平台或者地图服务中标准化商家信息。 接下来,我得考虑哪些数学方法可以应用到这里。常见的可能有自然语言处理(NLP)技术,但用户特别提到数学知识,所以可能需要基础的算法或统计方法。比如,字符串处理、概率模型、隐马尔可夫模型(HMM)、条件随机场(CRF),或者更简单的规则匹配。 首先想到的是分词,中文分词是基础步骤。但商店名称可能包含非标准的词汇,比如“周姐”是品名,“嘎嘎”是修饰词,而“东北菜”是品类。这时候需要构建一个词典,包含已知的品类词,比如“东北菜”、“火锅”、“烧烤”等,然后从右向左匹配,找到品类,剩下的部分再拆分出品名和修饰词。 但是用户提到数学知识,可能需要更模型化的方法。比如概率模型中的HMM,将每个词的角色(品名、修饰词、品类)作为隐藏状态,观察到的词语作为观测序列,通过训练数据学习转移概率和发射概率,然后使用Viterbi算法找到最可能的状态序列。 另外,条件随机场(CRF)也是一种常用的序列标注模型,适合处理这类问题。需要标注大量的训练数据,每个词标注为品名、修饰词或品类,然后训练CRF模型,利用特征如词的位置、词本身、相邻词等来进行预测。 不过如果用户没有足够的标注数据,可能需要用无监督或半监督的方法。比如,先收集常见的品类词库,然后基于规则进行匹配,剩下的部分通过统计方法(如频率分析)来确定品名和修饰词。例如,修饰词可能是形容词或副词,而品名通常是名词短语。 另一个思路是使用字符串相似度或编辑距离,比如比较商店名称与已知品类词的相似度,但可能不太直接相关。 还需要考虑商店名称的结构,通常品类在最后,比如“XX菜”、“XX店”,所以可以优先从右始匹配品类,然后剩下的部分拆分成前面的部分。比如“周姐嘎嘎东北菜”中先匹配“东北菜”作为品类,剩下的“周姐嘎嘎”中,可能“周姐”是品名,“嘎嘎”是修饰词。这时候可能需要一些规则,比如修饰词通常为形容词,或者长度较短,或者有常见的修饰词库。 数学方法的话,可能需要用概率来确定不同部分的划分可能性。比如,已知“东北菜”作为品类的概率高,而“嘎嘎”作为修饰词的概率高,可以通过统计语料库中的词频来计算。或者使用n-gram模型,计算不同组合的概率,选择概率最高的结构划分。 总结可能的步骤:1. 构建品类词库;2. 使用最大匹配法从右到左确定品类;3. 剩余部分利用统计模型或规则拆分为品名和修饰词。可能需要结合规则和统计模型,比如HMM或CRF,来处理未登录词或复杂情况。 同时,用户可能需要处理大量商店名称,因此效率和准确性的平衡也很重要。如果资源有限,可能需要优先基于规则和词典的方法,再逐步引入机器学习模型提高准确率。</think>商店名称范式识别(如“品名+品类”或“品名+修饰词+品类”)可通过数学方法结合自然语言处理(NLP)技术实现。以下是分步解决方案: --- ### **1. 问题建模** 将名称解析任务转化为**序列标注问题**,每个字符/词需标注为以下类别: - **品名**(如“周姐”) - **修饰词**(如“嘎嘎”) - **品类**(如“东北菜”) **数学目标**:找到最合理的标签序列 \( y^* = \arg\max_y P(y|x) \),其中 \( x \) 为输入名称。 --- ### **2. 核心数学方法** #### **(1) 基于概率模型的隐马尔可夫模型(HMM)** - **状态转移概率**:不同标签间的转移规律(如“品名”后接“修饰词”的概率)。 - **发射概率**:某标签生成具体词的概率(如“东北菜”属于“品类”的概率)。 - **解码算法**:用**维特比算法**(动态规划)求解最优标签序列。 #### **(2) 基于统计学习的条件随机场(CRF)** - **特征函数设计**:引入上下文特征(如词性、位置、长度等)。 - **全局归一化**:通过最大似然估计学习特征权重,优化 \( P(y|x) \)。 #### **(3) 规则与词典匹配** - **品类词库**:构建高频品类词典(如“火锅、烧烤、川菜”),优先匹配。 - **修饰词模式**:统计形容词/副词(如“正宗、老字号”)作为特征。 --- ### **3. 实现步骤** #### **步骤1:数据预处理** - 分词与特征提取(如词边界、词性、是否为品类词库成员)。 - 示例: `周姐/名词 嘎嘎/形容词 东北菜/名词(品类词库)` #### **步骤2:模型训练** - 对标注数据(人工标注或规则生成)训练CRF/HMM,学习标签转移规律。 - 关键公式(CRF): \[ P(y|x) = \frac{1}{Z(x)} \exp\left(\sum_i \sum_k \lambda_k f_k(y_{i-1}, y_i, x, i)\right) \] 其中 \( Z(x) \) 为归一化因子,\( f_k \) 为特征函数。 #### **步骤3:解码与预测** - 输入新名称,用训练好的模型预测标签序列。 - 示例解析: `周姐 嘎嘎 东北菜 → [品名] [修饰词] [品类]` --- ### **4. 优化策略** 1. **领域词典增强**:人工维护品类词库(如“奶茶、湘菜”),提升品类识别准确率。 2. **转移概率约束**:人工设定规则(如“品类通常位于末尾”),修正模型输出。 3. **集成学习**:结合规则匹配与统计模型,平衡准确率与覆盖率。 --- ### **5. 示例代码(Python简化版)** ```python import sklearn_crfsuite # 特征函数:提取当前词及上下文特征 def extract_features(word, pos, is_category): return { "word": word, "pos": pos, "is_category": is_category, "prefix": word[:2], # 前缀特征 "suffix": word[-2:], # 后缀特征 } # 训练CRF模型 crf = sklearn_crfsuite.CRF() crf.fit(X_train, y_train) # 预测 name = "周姐嘎嘎东北菜" predicted_labels = crf.predict([extract_features(name)]) ``` --- ### **6. 挑战与改进** - **未登录词问题**:通过字向量或预训练模型(如BERT)增强语义理解。 - **结构歧义**:引入强化学习,结合业务反馈优化标签策略。 通过结合数学建模与领域知识,可高效解析商店名称范式,适用于商业数据分析、智能推荐等场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值