经常使用的第三方类库总结

1. 概述

在项目开发过程中,一般我们都会用到很多类库,比如 spring,guava,hutool,apache io/commons等等等等相关一堆类库。本文就来介绍一下常见的类库以及使用方式,以作备忘和学习。

1.1 为什么学习类库?
1.1.1 提高效率

这是使用类库最重要的原因!

使用别人写好的类库可以很大程度上提高开发效率,在Java开发中我们自己写的代码(这里指的是偏工具类型的代码)是很少的,更多的代码是由各种类库来提供的,否则重复造轮子,开发周期会非常的长。

1.1.2 提高安全性

使得代码安全性更高

各种的经典类库被非常多的公司引用,并且运行了无数次,很少出现bug,但是我们自己实现这些功能浪费时间不说,并且还容易出现一些意想不到的bug,说不定什么时候就暴雷了,而经典的类库都是经过了时间的考验相对来说更稳定一些。

1.1.3 学习设计思想

可以学习好的设计思想

一般比较出名的、使用广泛的类库,都是由比较出名的组织或者大佬编写的,其中很多考虑到了扩展,健壮,安全,稳定,易用性等等这些,可以从中学习到一些思想,从而给自己助力&提升。


下边我们介绍一下guava 这个类库,guava这个类库很优秀,非常值的我们去使用&学习。

2. Guava

image.png

2.1 概述

Guava是一个基于Java的开源库,包含许多Google核心库,这些库在许多项目中都有使用

使用他有助于我们去学习最佳编码方式,并且帮助我们减少编码错误, 它为集合,缓存,并发,通用注释,字符串处理,I/O和验证等相关编程过程中的需求, 提供了大量开箱即用的方法。

2.1.1 Guava的优点
  • 高效设计良好的API,被Google的开发者设计,实现和推广使用。
  • 遵循高效的java语法实践。
  • 使代码更简练,简洁,简单。
  • 节约时间,资源,提高生产力。
2.1.2 源码结构

源码包包含了以下这些工具,可以根据需求使用,其中比较经典的有cache,collect,eventbus,concurrent,等等, 具体见下边:

  • com.google.common.annotations:普通注解类型。
  • com.google.common.base:基本工具类库和接口。
  • com.google.common.cache:缓存工具包,非常简单易用且功能强大的JVM缓存。
  • com.google.common.collect:带泛型的集合接口扩展和实现,以及工具类,这里你会发现很多好玩的集合。
  • com.google.common.eventbus:发布订阅风格的事件总线。
  • com.google.common.graph:对“图”数据结构的支持。
  • com.google.common.hash: 哈希工具包。
  • com.google.common.io:I/O工具包。
  • com.google.common.math:数学相关工具包。
  • com.google.common.net:网络工具包。
  • com.google.common.primitives:八种原始类型和无符号类型的静态工具包。
  • com.google.common.reflect:反射工具包。
  • com.google.common.util.concurrent:多线程工具包。
  • com.google.common.escape:提供了对字符串内容中特殊字符进行替换的框架,并包括了Xml和Html的两个实现。
  • com.google.common.html:HtmlEscapers封装了对html中特殊字符的替换。
  • com.google.common.xml:XmlEscapers封装了对xml中特殊字符的替换。
2.1.3 引入坐标

我们可以在maven的pom中引入最新的坐标和版本,然后就可以使用了

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>

2.2 基础工具类

Guava的经典很大一部分原因来源于对于基础工具类的封装,使用这些类能够让我们的代码更加优雅且完善,这些类大部分都在com.google.common.base包下

2.2.1 注意事项

JDK有很多借鉴guava的地方,这里只讲guava,并且JDK在不断的完善,如果JDK中有已经存这些工具类,建议就不要用guava

2.2.2 Optional(注意这里说的是Guava 中的 Optional)
2.2.2.1 作用

在构造对象的时候就明确申明该对象是否可能为null,快速失败拒绝null值,可以避免空指针异常。

2.2.2.2 使用
public class OptionTest {
  public static void main(String[] args) {
    Integer a = null;
    Integer b = 10;
    //支持传入null以及非null的数据
    Optional<Integer> optional_a = Optional.fromNullable(a);
    Optional<Integer> optional_b = Optional.fromNullable(b);
    //of方式支支持非null的数据
    //Optional<Integer> optional_c = Optional.fromNullable(a);
    //创建一个空的没有对象引用的Option
    Optional<Integer> optional_d = Optional.absent();
    //不存在对象实例不进入
    if (optional_a.isPresent()) {
      System.out.println("A:" + optional_a.get());
     }
    //存在对象实例进入
    if (optional_b.isPresent()) {
      System.out.println("B:" + optional_b.get());
     }
    //不存在对象实例不进入
    if (optional_d.isPresent()) {
      System.out.println("D:" + optional_d.get());
     }
   }
}

2.2.2.3 源码结构

Optional封装了Absent对象以及Present对象,如果参数为空,则Optional封装Absent否则封装Present

image-20220303102921546.png

2.2.2.4 JDK8替代

在JDK8以及更高版本,可以使用java.util.Optional来代替使用

2.2.3 Preconditions
2.2.3.1 作用

封装了前置条件校验,让方法中的条件检查更简单

实际开发中需要做入参校验的情况比比皆是,比如开发一个rest接口,肯定要对参数各种校验,防止错误的输入导致程序出错,我们可以使用Preconditions(前置条件),这样我们自己代码中就不会出现大段的if代码了

2.2.3.2 以前的做法

以前我们都是大段的用if写各种判断,如果入参很多,或者校验逻辑很复杂,这个函数中if会越来越多,圈复杂度越来越高

  public static void query(String name, int age) {
        if (name == null || name.equals("")) {
            throw new IllegalArgumentException("name should not be empty.");
        }
     
        if (age <= 0||age>=100) {
            throw new IllegalArgumentException("age should not be negative.");
        }
    }
2.2.3.3 代码优化

使用Preconditions对我们的代码进行优化

public static void query(String name, int age) {
  Preconditions.checkNotNull(name,"name should not be empty.");
  Preconditions.checkArgument(!"".equals(name),"name should not be empty.");
  Preconditions.checkArgument(age >= 0 && age < 100,"age should not be negative.");
}

使用Preconditions就可以消除代码中的if了,当然也可以使用Assert ,后边我们会讲。

2.2.3.4 常见的一些校验
  • checkArgument: 检查boolean是否为真,用作方法中检查参数,失败时抛出的异常类型: IllegalArgumentException
  • checkNotNull:检查value不为null, 直接返回value,失败时抛出的异常类型:NullPointerException
  • checkState:检查对象的一些状态,不依赖方法参数,失败时抛出的异常类型:IllegalStateException
  • checkElementIndex:检查index是否为在一个长度为size的list, string或array合法的范围,失败时抛出的异常类型:IndexOutOfBoundsException
  • checkPositionIndex:检查位置index是否为在合法的范围,index的范围区间是[0, size]失败时抛出的异常类型:IndexOutOfBoundsException
2.2.4 Splitter
2.2.4.1 作用

Splitter 可以让你使用一种非常简单流畅的模式来控制字符分割的行为

2.2.4.2 String.split的问题

Java 中关于分词的工具类会有一些古怪的行为,String.split 函数会悄悄地丢弃尾部的分割符,下边做个演示:

image.png

2.2.4.3 Splitter优化

而使用 Splitter 可以让你使用一种非常简单流畅的模式来解决这些令人困惑的行为

public static void guavaSplit(String str) {
    List<String> strings = Splitter.on(",").
            //omitEmptyStrings().
                    splitToList(str);
    strings.forEach(x -> System.out.print(x + ";"));
}

这样尾部空格不会被跳过,可以正常显示尾部空串

image.png

2.2.4.4 去除空格

Splitter还支持自定义分割字符串,比如去掉空格、去掉空字符串等等,上面代码可以优化为

public static void guavaSplit(String str) {
    List<String> strings = Splitter.on(",").
                    //将结果中的空格删除(如果有的话)
                    trimResults().
                    //移去结果中的空字符串
                    omitEmptyStrings().
                    //需要分割的字符串
                    splitToList(str);
    strings.forEach(x -> System.out.print(x + ";"));
}

执行后将会去除空格(如果有的话)以及空字符串

image.png

2.2.4.5 MapSplitter

Splitter除了可以对字符进行拆分,还可以对URL参数进行拆分,比如URL参数id=123&name=green

 public static void guavaSplit3(String str) {
            //分割字符串,获取URL`?`后面的参数部分
            String param = str.split("\?")[1];
            Map<String, String> paramMap = Splitter.
                    //先按照`&`符号进行分割
                            on("&").
                    //在分割的符号里面在按照`=`进行分割
                            withKeyValueSeparator("=").
                    //需要切分的字符串
                            split(str);
            System.out.println(paramMap);
}
2.2.5 Joiner
2.2.5.1 作用

Guava 的 Joiner 让字符串连接变得极其简单,即使字符串中包含 null,也很容易处理

Joiner相当于spliter的反操作,可以将数组或者集合等可遍历的数据转换成使用分隔符连接的字符串

2.2.5.2 Java实现方式

对于这样的list进行数据进行拼接,需要排除空字符串和null的数据

    List<String> list = new ArrayList<String>() {
 {
        add("1");
        add("2");
        add(null);
        add("3");
    }};

如果只使用Java方式需要使用以下的方式进行实现

public static String javaJoin(List<String> strList, String delimiter) {
        StringBuilder builder = new StringBuilder();
        for (String str : strList) {
            if (null != str) {
                builder.append(str).append(delimiter);
            }
        }
        builder.setLength(builder.length() - delimiter.length());
        return builder.toString();
}

实现方式很简单,但是很繁琐

2.2.5.3 Joiner方式优化

我们不在考虑更多的细节,并且很有语义的告诉代码的阅读者,用什么分隔符,需要过滤null值再join

    public static String guavaJoin1(List<String> strList, String delimiter) {
        return Joiner.on(delimiter).skipNulls().join(strList);
    }
2.2.5.4 MapJoinner

Joiner还可以处理URL编码的生成,将MAP数据转换成对应的URL参数

Map<String, String> map = ImmutableMap.of("id", "123", "name", "green");
//第一个分隔符使用&,第二个参数分割符使用 =
String joinStr = Joiner.on("&").withKeyValueSeparator("=").join(map);
System.out.println(joinStr);

image.png

2.2.6 StopWatch

StopWatch用来计算经过的时间(精确到纳秒)

2.2.6.1 原始的计时方式

原始的方式代码复杂,并且很不美观,性能也存在问题

 public static void task() throws InterruptedException {
     long currentTime = System.currentTimeMillis();
     //业务代码
     Thread.sleep(1000);
     long duration = System.currentTimeMillis() - currentTime;
     System.out.println("执行耗时:" + duration + "ms");
 }

2.2.6.2 优化代码

我们发现优化后从代码上来看优雅很多,并且使用起来也比较简单

    public static vo
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MFC(Microsoft Foundation Class)是一种用于开发Windows应用程序的工具,而串口类则是用于实现串口通信的一种类库。在MFC这个框架中,有一些已经封装好的串口类,可以用于串口通信的编程。 然而,有时候我们可能需要更加灵活且功能更强大的串口类,这时就可以使用第三方提供的串口类库第三方串口类库是由一些独立的开发者或者公司开发的,它们提供了更多的功能和更灵活的接口,能够满足特定的需求。 要下载第三方的串口类库,首先需要在互联网上搜索并找到合适的类库。可以通过搜索引擎或者软件开发交流平台来找到相关的资源。通常,这些第三方类库会提供下载链接或者文档说明,可以从官方网站或者其他可信的下载站点下载。 一旦找到了合适的类库,就可以根据说明文档进行下载和安装。常见的类库安装方式可能包括将库文件复制到特定目录,或者在项目中引入相关的库文件。 安装完成后,就可以在MFC应用程序中使用第三方串口类库了。具体的使用方式可以参考类库的文档或者示例程序。一般来说,需要在MFC应用程序中包含类库的头文件,并使用库提供的API接口来进行串口通信的操作。 总结起来,下载第三方串口类库可以通过搜索合适的资源和下载链接。安装完成后,在MFC应用程序中使用类库提供的接口来实现串口通信。这样,就能够更好地满足特定的需求,并且获得更强大和灵活的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔向理想的星辰大海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值