百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

不要重复造轮子提高生产效率!3个常用的开源工具库分享

toyiye 2024-05-25 20:11 15 浏览 0 评论

我们实际项目开发中是比较忌讳造轮子,但是,自己在学习过程中造轮子绝对是对自己百利而无一害的!造轮子是一种特别能够提高自己系统编程能力的手段。

今天就分享几个我常用的开源工具库,希望对小伙伴们有帮助!

  1. OSHI[1] :一款为 Java 语言提供的基于 JNA 的(本机)操作系统和硬件信息库。
  2. EasyExcel[2] :一款快速、简单避免 OOM 的 java 处理 Excel 工具。
  3. Hutool[3] : 一个非常实用的 Java 工具类库,对文件、流、加密解密、转码、正则、线程、XML 等 JDK 方法进行了封装。

以下是较为详细一点的介绍,建议小伙伴们看完,方便自己快速上手,用在自己的项目中来提高生产效率。

oshi

介绍

OSHI 是一款为 Java 语言提供的基于 JNA 的(本机)操作系统和硬件信息库。

JNA(Java Native Access)[4]是一个开源的 Java 框架,是 Sun 公司推出的一种调用本地方法的技术,是建立在经典的 JNI 基础之上的一个框架。之所以说它是 JNI 的替代者,是因为 JNA 大大简化了调用本地方法的过程,使用很方便,基本上不需要脱离 Java 环境就可以完成。

JNI(Java Native Interface) 是 JDK 提供的一个编程接口,它允许 Java 程序调用其他语言编写的程序或者代码库,其实 JDK 本身的实现也大量用到 JNI 技术来调用本地 C 程序库。

通过 OSHI ,我们不需要安装任何其他本机库,就能查看内存和 CPU 使用率、磁盘和分区使用情况、设备、传感器等信息。

OSHI 旨在提供一种跨平台的实现来检索系统信息,支持 Windows、Linux、MacOS、Unix 等主流操作系统。

官方是这样介绍 oshi 的:(翻译 Chrome 插件:Mate Translate):

使用 oshi 你可以轻松制作出项目常用的系统监控功能,如下图所示:

引入依赖

Maven

<!-- https://mvnrepository.com/artifact/com.github.oshi/oshi-core -->
<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>5.2.5</version>
</dependency>

Gradle

// https://mvnrepository.com/artifact/com.github.oshi/oshi-core
compile group: 'com.github.oshi', name: 'oshi-core', version: '5.2.5'

功能演示

获取硬件信息对象HardwareAbstractionLayer :

//系统信息
SystemInfo si = new SystemInfo();
//操作系统信息
OperatingSystem os = si.getOperatingSystem();
//硬件信息
HardwareAbstractionLayer hal = si.getHardware();

有了代表硬件信息的对象HardwareAbstractionLayer 之后,我们就可以获取硬件相关的信息了!

下面简单演示一下获取内存和 CPU 相关信息。

1.获取内存相关信息

//内存相关信息
GlobalMemory memory = hal.getMemory();
//获取内存总容量
String totalMemory = FormatUtil.formatBytes(memory.getTotal());
//获取可用内存的容量
String availableMemory = FormatUtil.formatBytes(memory.getAvailable());

有了内存总容量和内存可用容量,你就可以计算出当前内存的利用率了。

2.获取 CPU 相关信息

//CPU相关信息
CentralProcessor processor = hal.getProcessor();
//获取CPU名字
String processorName = processor.getProcessorIdentifier().getName();
//获取物理CPU数
int physicalPackageCount = processor.getPhysicalPackageCount();
//获取物理核心数
int physicalProcessorCount = processor.getPhysicalProcessorCount();

EasyExcel

介绍

Java 解析、生成 Excel 常用的框架有 Apache poi、jxl ,但是这两个框架使用起来都不够优雅,并且非常耗内存严重时会导致内存溢出

怎么解决这个问题呢?

推荐你使用阿里开源的 EasyExcel。正如这个项目官网介绍的那样,这是一款快速、简单避免 OOM 的 java 处理 Excel 工具。

官方是这样介绍 EasyExcel 的:

引入依赖

Maven

<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

Gradle

// https://mvnrepository.com/artifact/com.alibaba/easyexcel
compile group: 'com.alibaba', name: 'easyexcel', version: '2.2.6'

功能演示

这里直接分享官方提供读取 Excel 的例子(在实际项目中我对这部分做了简单的封装,涉及的地方比较多,就不分享出来了)。

实体对象 (Excel 导入导出实体对象)

@Data
public class DemoData {
    private String string;
    private Date date;
    private Double doubleData;
}

监听器 (自定义 AnalysisEventListener 一次读取 5 条数据存储到数据库)

// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class DemoDataListener extends AnalysisEventListener<DemoData> {
    private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<DemoData> list = new ArrayList<DemoData>();
    /**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private DemoDAO demoDAO;
    public DemoDataListener() {
        // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
        demoDAO = new DemoDAO();
    }
    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param demoDAO
     */
    public DemoDataListener(DemoDAO demoDAO) {
        this.demoDAO = demoDAO;
    }
    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }
    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        LOGGER.info("所有数据解析完成!");
    }
    /**
     * 加上存储数据库
     */
    private void saveData() {
        LOGGER.info("{}条数据,开始存储数据库!", list.size());
        demoDAO.save(list);
        LOGGER.info("存储数据库成功!");
    }
}

持久层 (mybatis 或者 jpa 来做都行)

/**
 * 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。
 **/
public class DemoDAO {
    public void save(List<DemoData> list) {
        // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
        System.out.println(list);
    }
}

读取数据

String fileName = "src/test/resources/demo/demo.xlsx";
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();

输出结果 (已过滤非必要数据)

2020-09-16 08:14:33.727 DEBUG [main] com.alibaba.excel.context.AnalysisContextImpl:91 - Began to read:ReadSheetHolder{sheetNo=0, sheetName='Sheet1'} com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder@6f3b5d16
2020-09-16 08:14:33.870 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1577811661000,"doubleData":1.0,"string":"字符串0"}
2020-09-16 08:14:33.870 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1577898061000,"doubleData":2.0,"string":"字符串1"}
2020-09-16 08:14:33.871 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1577984461000,"doubleData":3.0,"string":"字符串2"}
2020-09-16 08:14:33.871 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1578070861000,"doubleData":4.0,"string":"字符串3"}
2020-09-16 08:14:33.872 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1578157261000,"doubleData":5.0,"string":"字符串4"}
2020-09-16 08:14:33.872 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:80 - 5条数据,开始存储数据库!
[DemoData(string=字符串0, date=Wed Jan 01 01:01:01 CST 2020, doubleData=1.0), DemoData(string=字符串1, date=Thu Jan 02 01:01:01 CST 2020, doubleData=2.0), DemoData(string=字符串2, date=Fri Jan 03 01:01:01 CST 2020, doubleData=3.0), DemoData(string=字符串3, date=Sat Jan 04 01:01:01 CST 2020, doubleData=4.0), DemoData(string=字符串4, date=Sun Jan 05 01:01:01 CST 2020, doubleData=5.0)]
2020-09-16 08:14:33.874 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:82 - 存储数据库成功!
2020-09-16 08:14:33.875 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1578243661000,"doubleData":6.0,"string":"字符串5"}
2020-09-16 08:14:33.875 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1578330061000,"doubleData":7.0,"string":"字符串6"}
2020-09-16 08:14:33.876 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1578416461000,"doubleData":8.0,"string":"字符串7"}
2020-09-16 08:14:33.876 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1578502861000,"doubleData":9.0,"string":"字符串8"}
2020-09-16 08:14:33.876 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:54 - 解析到一条数据:{"date":1578589261000,"doubleData":10.0,"string":"字符串9"}
2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:80 - 5条数据,开始存储数据库!
[DemoData(string=字符串5, date=Mon Jan 06 01:01:01 CST 2020, doubleData=6.0), DemoData(string=字符串6, date=Tue Jan 07 01:01:01 CST 2020, doubleData=7.0), DemoData(string=字符串7, date=Wed Jan 08 01:01:01 CST 2020, doubleData=8.0), DemoData(string=字符串8, date=Thu Jan 09 01:01:01 CST 2020, doubleData=9.0), DemoData(string=字符串9, date=Fri Jan 10 01:01:01 CST 2020, doubleData=10.0)]
2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:82 - 存储数据库成功!
2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:80 - 0条数据,开始存储数据库!
[]
2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:82 - 存储数据库成功!
2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:73 - 所有数据解析完成!

Process finished with exit code 0

Hutool

介绍

Hutool 是一个非常实用的 Java 工具类库,对文件、流、加密解密、转码、正则、线程、XML 等 JDK 方法进行了封装。

非常使用的开源工具类库,推荐小伙伴们在自己项目中使用。

官方是这样介绍 Hutool 的:

引入依赖

Maven

<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.4.2</version>
</dependency>

Gradle

// https://mvnrepository.com/artifact/cn.hutool/hutool-all
compile group: 'cn.hutool', name: 'hutool-all', version: '5.4.2'

功能演示

简单演示几个比较实用的功能。

邮件

在 Java 中发送邮件主要品依靠 javax.mail 包,但是由于使用比较繁琐,因此 Hutool 针对其做了封装。由于依赖第三方包,因此将此工具类归类到 extra 模块中。

实际项目中可以自定义邮箱配置,然后让配置保存在数据库,并在缓存中保存一份。

如果不想自定义配置的话,直接在配置文件中把邮箱配置写死就行了。

有了邮件的相关配置之后,定义邮件服务器之后即可发送邮件,非常方便:

MailAccount account = new MailAccount();
account.setHost("smtp.yeah.net");
account.setPort("25");
account.setAuth(true);
account.setFrom("hutool@yeah.net");
account.setUser("hutool");
account.setPass("q1w2e3");

MailUtil.send(account, CollUtil.newArrayList("hutool@foxmail.com"), "测试", "邮件来自Hutool测试", false);

唯一 ID

在分布式环境中,唯一 ID 生成应用十分广泛,生成方法也多种多样,Hutool 针对一些常用生成策略做了简单封装。

https://juejin.im/post/6844903935296176141

Hutool 提供的唯一 ID 生成器的工具类,涵盖了:

  • UUID
  • ObjectId(MongoDB)
  • Snowflake(Twitter)

拿 UUID 举例!

Hutool 重写java.util.UUID的逻辑,对应类为cn.hutool.core.lang.UUID,使生成不带-的 UUID 字符串不再需要做字符替换,性能提升一倍左右

//生成的UUID是带-的字符串,类似于:a5c8a5e8-df2b-4706-bea4-08d0939410e3
String uuid = IdUtil.randomUUID();

//生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42
String simpleUUID = IdUtil.simpleUUID();

Http 请求工具类

针对最为常用的 GET 和 POST 请求,HttpUtil 封装了两个方法,

  • HttpUtil.get
  • HttpUtil.post
// 最简单的HTTP请求,可以自动通过header等信息判断编码,不区分HTTP和HTTPS
String result1 = HttpUtil.get("https://www.baidu.com");
// 当无法识别页面编码的时候,可以自定义请求页面的编码
String result2 = HttpUtil.get("https://www.baidu.com", CharsetUtil.CHARSET_UTF_8);
//可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result3 = HttpUtil.get("https://www.baidu.com", paramMap);

缓存

Hutool 提供了常见的几种缓存策略的实现:

  1. FIFO(first in first out) :先进先出策略。
  2. LFU(least frequently used) :最少使用率策略。
  3. LFU(least frequently used) :最少使用率策略。
  4. 定时缓存 :对被缓存的对象定义一个过期时间,当对象超过过期时间会被清理。
  5. ......

FIFO(first in first out) 策略缓存使用:

Cache<String,String> fifoCache = CacheUtil.newFIFOCache(3);

//加入元素,每个元素可以设置其过期时长,DateUnit.SECOND.getMillis()代表每秒对应的毫秒数,在此为3秒
fifoCache.put("key1", "value1", DateUnit.SECOND.getMillis() * 3);
fifoCache.put("key2", "value2", DateUnit.SECOND.getMillis() * 3);
fifoCache.put("key3", "value3", DateUnit.SECOND.getMillis() * 3);

//由于缓存容量只有3,当加入第四个元素的时候,根据FIFO规则,最先放入的对象将被移除
fifoCache.put("key4", "value4", DateUnit.SECOND.getMillis() * 3);

//value1为null
String value1 = fifoCache.get("key1");

控制台打印封装-Console

一般情况下,我们打印信息到控制台小伙伴们应该再熟悉不过了!

System.out.println("Hello World");

但是,这种方式不满足很多场景的需要:

  1. 不支持参数,对象打印需要拼接字符串
  2. 不能直接打印数组,需要手动调用Arrays.toString

为此,Hutool 封装了Console对象。

Console 对象的使用更加类似于 Javascript 的console.log()方法,这也是借鉴了 JS 的一个语法糖。

String[] a = {"java", "c++", "c"};
Console.log(a);//控制台输出:[java, c++, c]

Console.log("This is Console log for {}.", "test");//控制台输出:This is Console log for test.

参考资料

[1]

oshi: https://github.com/oshi/oshi

[2]

EasyExcel: https://github.com/alibaba/easyexcel

[3]

Hutool: https://github.com/looly/hutool

[4]

JNA(Java Native Access): https://github.com/java-native-access/jna

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码