【java筑基】面试、工作不可不知的六个Java工具类

简介: 【java筑基】面试、工作不可不知的六个Java工具类

Java中有许多方便的工具类,可以避免方法传入空参数的Objects类,实现java国际化的Locale类,ResourceBundle类,避免计算浮点数计算精度损失的BigDecimal运算类…

1. Objects类

ava7新增了Objects类,不会引发空指针异常,如果不确定一个对象是否为空,可以使用这个类的方法。在传入参数时可以使用Objects类中的requireNonNull()方法,防止传入的参数为null。

import java.util.Objects;
public class ObjectsTest {
  static ObjectsTest obj;
  public static void main(String[] args) {
    // 打印结果:null
    System.out.println(Objects.toString(obj));
    // 要求某个对象不为null,返回该对象,否则引发异常且报错进行提示
    obj = new ObjectsTest();
    System.out.println(Objects.requireNonNull(obj, "该对象未进行初始化!"));
  }
}

2.StringBuffer、StringBuilder

String创建的字符串对象不可以改变,StringBuffer与StringBuilder都可以改变,其中StringBuffer类型是线程安全的,但其效率也会降低点。

String有许多API,可以实现将字符数组与字符串序列相互转换,可以将StringBuilder、StringBuffering类数据转换为String类,也可以与它们进行值的比较。

StringBuffer与StringBuilder类中有length()与capcity()两个方法,前者表示字符串序列的长度,二者表示容量。

3.ThreadLocalRandom与Random

Random用于生成伪随机数(比Math类提供了更多方式),ThreadLocalRandom是其线程安全的增强版,也提供了指定范围的随机数生成方法。

import java.util.Random;
public class RandomTest {
  public static void main(String[] args) {
    // 使用默认种子生成伪随机数,以当前时间为种子
    Random rd = new Random();
    // 伪随机生成boolean值
    System.out.println("rd.nextBoolean():" + rd.nextBoolean());
    // 伪随机生成平均值是0.0,标准差是1 .0的高斯数
    System.out.println("rd.nextGaussian():" + rd.nextGaussian());
    // 伪随机生成0~26之间的int值
    System.out.println("rd.nextInt(26):" + rd.nextInt(26));
    // rd1与rd2的种子一样,方法调用顺序也相同,生成的结果一样,所以是伪随机数
    System.out.println("------------");
    Random rd1 = new Random(50);
    System.out.println("rd1.nextBoolean():" + rd1.nextBoolean());
    System.out.println("rd1.nextGaussian():" + rd1.nextGaussian());
    System.out.println("rd1.nextInt(26):" + rd1.nextInt(26));
    System.out.println("------------");
    Random rd2 = new Random(50);
    System.out.println("rd2.nextBoolean():" + rd2.nextBoolean());
    System.out.println("rd2.nextGaussian():" + rd2.nextGaussian());
    System.out.println("rd2.nextInt(26):" + rd2.nextInt(26));
  }
}

4.BigDecimal类

BigDecimal提供精确计算浮点数的方式。

import java.math.BigDecimal;
public class BigDecimalTest {
  public static void main(String[] args) {
    // 输出0.05+0.01=0.060000000000000005
    System.out.println("0.05+0.01=" + (0.05 + 0.01));
    BigDecimal f1 = new BigDecimal("0.05");
    BigDecimal f2 = BigDecimal.valueOf(0.01);
    BigDecimal f3 = new BigDecimal(0.05);
    // 基于String作为BigDecimal构造器参数,输出0.05+0.01=0.06,推荐!
    System.out.println("0.05+0.01=" + f1.add(f2));
    // 基于Double作为BigDecimal构造器参数,输出0.05+0.01=0.06000000000000000277555756156289135105907917022705078125
    System.out.println("0.05+0.01=" + f2.add(f3));
  }
}

如果程序需要对于double浮点数进行精确的加、减、乘、除运算,可以编写一个Arith工具类,在这个类里面使用BigDecimal类返回精确的计算结果。

5.java.time包

java8以前使用Data类、Calendar类来实现对于日期、时间的处理,但由于Date类设计存在问题,Calendar过于复杂,Java8吸取了Joda-Time库,提供一个java.time包用于处理时间。

public class NewDatePackageTest {
  public static void main(String[] args) {
    // -------Clock类的使用:可取代System.currentTimeMillis()方法获取当前时间--------
    Clock clock = Clock.systemUTC();
    // 输出 当前时刻为:2021-04-01T06:50:55.221Z,注意这里打印的时间是UTC时间,北京时间=UTC+8h
    System.out.println("当前UTC时刻为:" + clock.instant());
    // clock对应的毫秒数,下面二者打印内容相同
    System.out.println(clock.millis());
    System.out.println(System.currentTimeMillis());
    // --------Duration类的用法:获取一段时间进行计算------------
    Duration d = Duration.ofSeconds(3600 * 8);
    System.out.println("3600 * 8 秒=" + d.toHours() + "时");
    Clock clock2 = Clock.offset(clock, d);
    System.out.println("当前时刻的北京时间" + clock2.instant());
    // ------------Instant类的用法,可以获取精确到纳秒的时间------------
    // 获取当前时间
    Instant instant = Instant.now();
    System.out.println(instant);
    // 根据当前字符串解析时间
    Instant instant2 = Instant.parse("2021-04-01T15:26:43.281Z");
    System.out.println(instant2);
    // -----LocalDate获得日期—-----------
    LocalDate localDate = LocalDate.ofYearDay(2021, 146);
    // 2021年的第146天是2021-05-26
    System.out.println(" 2021年的第146天是" + localDate);
    // -----LocalTime获得当地时间—-----------
    LocalTime localTime = LocalTime.now();
    System.out.println(localTime);
  }
}

6.正则表达式相关工具类

正则表达式可用于对字符串进行查找、分割、替换等操作,java提供了Pattern和Matcher两个类专门用于支持正则表达式。正则表达式可以应用与比如网站的密码格式检查等实际场景。

image.jpeg


正则表达式语法参见:你是如何学会正则表达式的? - 老刘的回答 - 知乎 https://www.zhihu.com/question/48219401/answer/742444326

正则表达式在java中的使用示例代码如下。

// 将一个字符串编译成为Pattern对象,这是正则表达式在内存中的表示形式
Pattern p = Pattern.compile("a*b");
// 利用Pattern对象来创建Matcher对象
Matcher m = p.matcher("aaaaab");
//返回true
System.out.println(m.matches());
//上面代码等价于该行代码
System.out.println(Pattern.matches("a*b", "aaaaab"));

使用正则表达式可以实现网络爬虫——提取网络的网址超链接,再进入超链接即可。下面通过一小段代码提取电话号码。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindGroup {
  public static void main(String[] args) {
    String str = "我是wz,call我电话15173737429" + "我是wd," + "喝茶联系15627270324"
        + "我是zzsgd,水果配送热线13683675854";
    Matcher m = Pattern.compile("((15[1|6])|136)\\d{8}").matcher(str);
    while (m.find()) {
      System.out.println(m.group());
    }
  }
}

matcheres()方法需要字符串与正则表达式完全一致才返回true,lookingAt()方法只需要与Pattern作为开头即返回true。

学习正则表达式建议多练习题目,推荐使用牛客网刷题巩固:大厂真题大全

7.国际化与格式化工具类

软件可能需要适应不同地区的本土市场,比如支付宝投入日本市场需要能够对日文进行本土化显示,因此要能够进行国际化与本土化。当然本土化不仅仅是语言方面的工作,还有比如日期格式、货币格式等。

Java格式化的思路是将程序中的标签、提示等通过资源文件来存放,不同国家、语言环境调用不同的资源文件。资源文件的存放格式是Key-value对,每个资源key不变,value随国家、语言环境而变。

java.util.Locale类可以获取Java所支持的国家和语言。

import java.util.Locale;
public class LocalList {
  public static void main(String[] args) {
    Locale[] localList = Locale.getAvailableLocales();
    // 遍历获取java支持的国家与语言,打印:阿拉伯联合酋长国=AE 阿拉伯文=ar...
    for (int i = 0; i < localList.length; i++) {
      System.out.println(localList[i].getDisplayCountry() + "="
          + localList[i].getCountry() + " "
          + localList[i].getDisplayLanguage() + "="
          + localList[i].getLanguage());
    }
  }
}

下面编写一个实现了国际化的程序。

import java.util.Locale;
import java.util.ResourceBundle;
public class Hello {
  public static void main(String[] args) {
    //获取系统默认的国家/语言环境
    Locale myLocale=Locale.getDefault(Locale.Category.FORMAT);
    //根据指定的国家/语言环境加载资源文件
    ResourceBundle bundle=ResourceBundle.getBundle("mess", myLocale);
    //打印该国家/语言环境文件资源中的hello
    System.out.println(bundle.getString("hello"));
  }
}

这个程序将获取系统默认支持的语言,并且加载对应语言的资源文件。如果默认的语言环境是中文,则在配置文件mess_zh_CN.properties下查找hello具体的值。下面是配置文件的具体内容(看似乱码的部分是中文的“你好”所对应的ASCII码)。

hello=\u4F60\u597D!


相关文章
|
26天前
|
Java 程序员
Java社招面试中的高频考点:Callable、Future与FutureTask详解
大家好,我是小米。本文主要讲解Java多线程编程中的三个重要概念:Callable、Future和FutureTask。它们在实际开发中帮助我们更灵活、高效地处理多线程任务,尤其适合社招面试场景。通过 Callable 可以定义有返回值且可能抛出异常的任务;Future 用于获取任务结果并提供取消和检查状态的功能;FutureTask 则结合了两者的优势,既可执行任务又可获取结果。掌握这些知识不仅能提升你的编程能力,还能让你在面试中脱颖而出。文中结合实例详细介绍了这三个概念的使用方法及其区别与联系。希望对大家有所帮助!
163 60
|
2天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
33 14
|
5天前
|
安全 Java 程序员
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
34 13
|
25天前
|
算法 安全 Java
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
65 16
|
22天前
|
Java 程序员 调度
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
55 9
|
27天前
|
安全 Java 程序员
Java面试必问!run() 和 start() 方法到底有啥区别?
在多线程编程中,run和 start方法常常让开发者感到困惑。为什么调用 start 才能启动线程,而直接调用 run只是普通方法调用?这篇文章将通过一个简单的例子,详细解析这两者的区别,帮助你在面试中脱颖而出,理解多线程背后的机制和原理。
60 12
|
1月前
|
监控 Dubbo Java
Java Dubbo 面试题
Java Dubbo相关基础面试题
|
1月前
|
SQL Java 数据库连接
Java MyBatis 面试题
Java MyBatis相关基础面试题
|
1月前
|
存储 监控 算法
Java JVM 面试题
Java JVM(虚拟机)相关基础面试题
|
1月前
|
SQL 监控 druid
Java Druid 面试题
Java Druid 连接池相关基础面试题

热门文章

最新文章