Java常用API(一)

第九章 常用API

本章学习目标

  • 掌握JUnit框架@Test的使用
  • 掌握包装类与基本数据类型的自动装箱与拆箱
  • 了解哪些包装类有缓存对象
  • 掌握数学工具类Math类的常用方法
  • 掌握使用BigInteger和BigDecimal表示整数和小数的方式
  • 掌握使用Random类的方法产生随机数
  • 了解第1、2代日期时间类的基本使用及其问题
  • 掌握第3代日期时间类的常用方法
  • 掌握数组工具类Arrays的常用方法
  • 掌握系统类System类的常用方法
  • 掌握两种比较器接口的使用
  • 掌握字符串String类的常用方法
  • 掌握可变字符串StringBuffer和StringBuilder的常用方法
  • 知道String,StringBuffer和StringBuilder的区别
  • 理解String类及其对象的特点
  • 了解文本块的语法格式

9.1 JUnit单元测试工具

JUnit是由Erich Gamma和Kent Beck编写的一个回归测试框架(regression testing framework),供Java开发人员编写单元测试之用。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。JUnit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。

要使用JUnit,必须在项目的编译路径中必须引入JUnit的库,即相关的.class文件组成的jar包。

9.1.1 在线下载JUnit库

如果没有单独安装和设置过maven仓库(Maven后面阶段学习),则IDEA会使用默认的maven仓库路径,它在C盘的用户目录下:

image-20220616175209325.png

当我们使用JUnit时,IDEA会提示我们自动下载jar到C盘。

image-20221105140348475.png
image-20221105140654619.png

9.2.2 允许JUnit的测试方法中键盘输入

因为把ja-netfilter.jar破解工具把idea使用的vmoption文件重定向到它自己的文vmoption文件了。找到ja-netfilter.jar破解工具的解压目录的vmoptions文件夹,找到idea.vmoptions文件。

image-20221105154403298.png
image-20240715194815959.png

打开idea.vmoptions配置文件,在最后独立一行加入如下配置参数

-Deditable.java.test.console=true

image-20221105154450636.png

9.3.3 示例代码

package com.atguigu.junit;
import org.junit.Test;
import java.util.Scanner;
public class TestJUnit {
    @Test
    public void test1() throws Exception {
        System.out.println("hello");
    }
    @Test
    public void test2() throws Exception {
        System.out.println("world");
    }
    @Test
    public void test3() throws Exception {
        Scanner input = new Scanner(System.in);
        System.out.print("请输入一句话:");
        String word = input.next();
        System.out.println("word = " + word);
        input.close();
    }
}

9.2 包装类

9.2.1 包装类

Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而当要使用只针对对象设计的API或新特性(例如泛型),那么基本数据类型的数据就需要用包装类来包装。

序号基本数据类型包装类(java.lang包)
1byteByte
2shortShort
3intInteger
4longLong
5floatFloat
6doubleDouble
7charCharacter
8booleanBoolean
9voidVoid

9.2.2 装箱与拆箱

装箱:把基本数据类型转为包装类对象。

转为包装类的对象,是为了使用专门为对象设计的API和特性

拆箱:把包装类对象拆为基本数据类型。

转为基本数据类型,一般是因为需要运算,Java中的大多数运算符是为基本数据类型设计的。比较、算术等

基本数值---->包装对象

Integer obj1 = Integer.valueOf(4);//使用构造函数函数
Integer obj2 = Integer.valueOf(4);//使用包装类中的valueOf方法

包装对象---->基本数值

Integer obj = Integer.valueOf(4);
int num1 = obj.intValue();

JDK1.5之后,可以自动装箱与拆箱。

注意:只能与自己对应的类型之间才能实现自动装箱与拆箱。

Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;
//加法运算完成后,再次装箱,把基本数值转成对象。
Integer i = 1;
Double d = 1;//错误的,1是int类型

7.10.3 包装类的一些API

1、基本数据类型和字符串之间的转换

(1)把基本数据类型转为字符串
int a = 10;
//String str = a;//错误的
//方式一:
String str = a + "";
//方式二:
String str = String.valueOf(a);
(2)把字符串转为基本数据类型

String转换成对应的基本类型 ,除了Character类之外,其他所有包装类都具有parseXxx静态方法可以将字符串参数转换为对应的基本类型,例如:

  • public static int parseInt(String s):将字符串参数转换为对应的int基本类型。
  • public static long parseLong(String s):将字符串参数转换为对应的long基本类型。
  • public static double parseDouble(String s):将字符串参数转换为对应的double基本类型。

或把字符串转为包装类,然后可以自动拆箱为基本数据类型

  • public static Integer valueOf(String s):将字符串参数转换为对应的Integer包装类,然后可以自动拆箱为int基本类型
  • public static Long valueOf(String s):将字符串参数转换为对应的Long包装类,然后可以自动拆箱为long基本类型
  • public static Double valueOf(String s):将字符串参数转换为对应的Double包装类,然后可以自动拆箱为double基本类型

注意:如果字符串参数的内容无法正确转换为对应的基本类型,则会抛出java.lang.NumberFormatException异常。

int a = Integer.parseInt("整数的字符串");
double d = Double.parseDouble("小数的字符串");
boolean b = Boolean.parseBoolean("true或false");
int a = Integer.valueOf("整数的字符串");
double d = Double.valueOf("小数的字符串");
boolean b = Boolean.valueOf("true或false");

2、数据类型的最大最小值

Integer.MAX_VALUE和Integer.MIN_VALUE
Long.MAX_VALUE和Long.MIN_VALUE
Double.MAX_VALUE和Double.MIN_VALUE

3、字符转大小写

Character.toUpperCase('x');
Character.toLowerCase('X');

9.2.4 包装类对象的特点

1、包装类对象不可变

public class TestExam {
    public static void main(String[] args) {
        int i = 1;
        Integer j = Integer.valueOf(2);
        Circle c = new Circle();
        change(i, j, c);
        System.out.println("i = " + i);//1
        System.out.println("j = " + j);//2
        System.out.println("c.radius = " + c.radius);//10.0
    }
    /*
     * 方法的参数传递机制:
     * (1)基本数据类型:形参的修改完全不影响实参
     * (2)引用数据类型:通过形参修改对象的属性值,会影响实参的属性值
     * 这类Integer等包装类对象是“不可变”对象,即一旦修改,就是新对象,和实参就无关了
     */
    public static void change(int a, Integer b, Circle c) {
        a += 10;
//        b += 10;//等价于  b = Integer.valueOf(b+10);//指向另一个Integer对象
        c.radius += 10;
        /*c = new Circle();
        c.radius+=10;*/
    }
}
class Circle {
    double radius;
}

2、包装类缓存对象

包装类缓存对象
Byte-128~127
Short-128~127
Integer-128~127
Long-128~127
Float没有
Double没有
Character0~127
Booleantrue和false
Integer a = 1;
Integer b = 1;
System.out.println(a == b);//true
Integer i = 128;
Integer j = 128;
System.out.println(i == j);//false
Integer x = Integer.valueOf(1);
Integer y = Integer.valueOf(1);
System.out.println(x == y);//true
Double d1 = 1.0;
Double d2 = 1.0;
System.out.println(d1 == d2);//false 比较地址,没有缓存对象,每一个都是新new的

3、包装类对象计算问题

- 两个包装类对象之间进行“==”和“!=”运算,比较的是对象的地址值,要求两个包装类对象必须是同一种类型。

- 两个包装类对象之间进行其他运算(>,<,+,-等等),先自动拆箱为基本数据类型之后再运算,不要求两个包装类对象是同一种类型(Boolean不参与)。

- 包装类对象和基本数据类型的混合运算都是自动拆箱为基本数据类型之后再运算。

Integer i = 1;
Integer j = 1;
System.out.println(i == j);//true 比较地址值,缓存对象
Integer i = 128;Integer j = 128;
System.out.println(i==j);//false 比较地址值
Integer i = 1000;
double j = 1000;
System.out.println(i == j);//true  会先将i自动拆箱为int,然后根据基本数据类型“自动类型转换”规则,转为double比较
Integer i = 1000;
int j = 1000;
System.out.println(i == j);//true 会自动拆箱,按照基本数据类型进行比较
Integer i = 1;
Double d = 1.0
System.out.println(i == d);//编译报错
Integer i = 2;
Double d = 1.0
System.out.println(i > d);//true,自动拆箱后比较

9.3 和数学相关的类

9.3.1 java.lang.Math

java.lang.Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。类似这样的工具类,其所有方法均为静态方法,并且不会创建对象,调用起来非常简单。

  • public static double abs(double a) :返回 double 值的绝对值。
  • public static double ceil(double a) :返回大于等于参数的最小的整数。
  • public static double floor(double a) :返回小于等于参数最大的整数。
  • public static long round(double a) :返回最接近参数的 long。(相当于四舍五入方法)
  • public static double pow(double a,double b):返回a的b幂次方法
  • public static double sqrt(double a):返回a的平方根
  • public static double random():返回[0,1)的随机值
  • public static final double PI:返回圆周率
  • public static double max(double x, double y):返回x,y中的最大值
  • public static double min(double x, double y):返回x,y中的最小值

9.3.2 java.math包

1、BigInteger

不可变的任意精度的整数。

  • BigInteger(String val)
  • BigInteger add(BigInteger val)
  • BigInteger subtract(BigInteger val)
  • BigInteger multiply(BigInteger val)
  • BigInteger divide(BigInteger val)
  • BigInteger remainder(BigInteger val)
  • ....

@Test
public void test01(){
//        long bigNum = 123456789123456789123456789L;
    BigInteger b1 = new BigInteger("123456789123456789123456789");
    BigInteger b2 = new BigInteger("78923456789123456789123456789");
//        System.out.println("和:" + (b1+b2));//错误的,无法直接使用+进行求和
    System.out.println("和:" + b1.add(b2));
    System.out.println("减:" + b1.subtract(b2));
    System.out.println("乘:" + b1.multiply(b2));
    System.out.println("除:" + b2.divide(b1));
    System.out.println("余:" + b2.remainder(b1));
}

2、BigDecimal

不可变的、任意精度的有符号十进制数。

  • BigDecimal(String val)
  • BigDecimal add(BigDecimal val)
  • BigDecimal subtract(BigDecimal val)
  • BigDecimal multiply(BigDecimal val)
  • BigDecimal divide(BigDecimal val)
  • BigDecimal divide(BigDecimal divisor, int roundingMode)
  • BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
  • BigDecimal remainder(BigDecimal val)
  • ....

RoundingMode枚举类的部分常量对象:

  • CEILING :向正无限大方向舍入的舍入模式。
  • DOWN :向零方向舍入的舍入模式。
  • FLOOR:向负无限大方向舍入的舍入模式。
  • HALF_DOWN :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。
  • HALF_EVEN:向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
  • HALF_UP:向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。
  • UNNECESSARY:用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。
  • UP:远离零方向舍入的舍入模式。

@Test
public void test02(){
    /*double big = 12.123456789123456789123456789;
    System.out.println("big = " + big);*/
    BigDecimal b1 = new BigDecimal("123.45678912345678912345678912345678");
    BigDecimal b2 = new BigDecimal("7.8923456789123456789123456789998898888");
//        System.out.println("和:" + (b1+b2));//错误的,无法直接使用+进行求和
    System.out.println("和:" + b1.add(b2));
    System.out.println("减:" + b1.subtract(b2));
    System.out.println("乘:" + b1.multiply(b2));
    System.out.println("除:" + b1.divide(b2,20,RoundingMode.UP));//divide(BigDecimal divisor, int scale, int roundingMode)
    System.out.println("除:" + b1.divide(b2,20,RoundingMode.DOWN));//divide(BigDecimal divisor, int scale, int roundingMode)
    System.out.println("余:" + b1.remainder(b2));
}

9.3.3 java.util.Random

用于产生随机数

  • boolean nextBoolean():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 boolean 值。
  • void nextBytes(byte[] bytes):生成随机字节并将其置于用户提供的 byte 数组中。
  • double nextDouble():返回下一个伪随机数,它是取自此随机数生成器序列的、在 0.0 和 1.0 之间均匀分布的 double 值。
  • float nextFloat():返回下一个伪随机数,它是取自此随机数生成器序列的、在 0.0 和 1.0 之间均匀分布的 float 值。
  • double nextGaussian():返回下一个伪随机数,它是取自此随机数生成器序列的、呈高斯(“正态”)分布的 double 值,其平均值是 0.0,标准差是 1.0。
  • int nextInt():返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。
  • int nextInt(int n):返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
  • long nextLong():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 long 值。

@Test
public void test03(){
    Random r = new Random();
    System.out.println("随机整数:" + r.nextInt());
    System.out.println("[0,100)范围的随机整数:" + r.nextInt(100));
    System.out.println("随机小数:" + r.nextDouble());
    System.out.println("随机布尔值:" + r.nextBoolean());
}

9.4 日期时间API

9.4.1 第一代日期时间(JDK1.0)

1、java.lang.System


@Test
public void test1(){
    long time = System.currentTimeMillis();
    System.out.println(time);//1559806982971
    //当前系统时间距离1970-1-1 0:0:0 0毫秒的时间差,毫秒为单位
    //中国地区是距离
}

2、java.util.Date

  • new Date():当前系统时间
  • long getTime():返回该日期时间对象距离1970-1-1 0.0.0 0毫秒之间的毫秒值
  • new Date(long 毫秒):把该毫秒值换算成日期时间对象

@Test
public void test5(){
    long time = Long.MAX_VALUE;
    Date d = new Date(time);
    System.out.println(d);
}
@Test
public void test4(){
    long time = 1559807047979L;
    Date d = new Date(time);
    System.out.println(d);
}
@Test
public void test3(){
    Date d = new Date();
    long time = d.getTime();
    System.out.println(time);//1559807047979
}
@Test
public void test2(){
    Date d = new Date();
    System.out.println(d);
}

3、java.text.SimpleDateFormat

SimpleDateFormat用于日期时间的格式化。

  • public final String format(Date date)将一个 Date 格式化为日期/时间字符串。
  • public Date parse(String source)throws ParseException从给定字符串的开始解析文本,以生成一个日期。
字母描述示例
G纪元标记 根据语言环境显示Locale.CHINA 语言环境下,如:公元;Locale.US语言环境下,如:AD
y年份。yy表示2位年份,yyyy表示4位年份使用yy 表示年份,如23;使用yyyy表示年份,例如2023
M月份 一般用 MM 表示月份,如果使用 MMM,则会根据语言环境显示不同语言的月份使用 MM 表示的月份,如 11; 使用 MMM 表示月份,在 Locale.CHINA语言环境下,如“十月”;在 Locale.US环境下 如Nov
d月份中的天数。一般用dd表示天数使用dd表示天数 例如:20
h一天中的小时(1~12)。 一般使用hh表示小时如 10 (注意 10 有可能是 10 点,也可能是 22 点)
H一天中的小时 (0~23)。如:22
m分钟数 。一般用mm表示分钟数使用mm表示分钟数,如:59
s秒数。一般使用ss表示秒数使用ss表示秒数,如:55
S毫秒数 。一般使用SSS 表示毫秒数使用SSS表示毫秒数,如:234
E星期几.根据语言环境的不同,显示不同语言的星期几Locale.CHINA 语言环境下,如:星期日;在 Locale.US 语言下,如:Sun
D一年中的日子。324 一年中的第324天
F一个月中第几周。3 表示一个月中的第三周 ,从该月1号开始7天一个周期,例如3月1日-3月7日为3月第一周。
w一年中第几周 。48 表示一年中的第48周
W一个月中第几周3 表示一个月中的第三周,看日历,以2023-4-3为例,F还是4月第1周,W已经是4月第2周了。
aA.M./P.M. 或上午/下午标记。根据语言环境不同,显示不同Locale.CHINA 语言环境下,如:下午 Locale.US语言环境下,如:PM
k一天中的小时(1~24)15 一天中的第15小时
K一天中的小时(1~12)3 下午3小时
z时区中国的东八区 如:+0800

@Test
public void test10() throws ParseException{
    String str = "2019年06月06日 16时03分14秒 545毫秒  星期四 +0800";
    SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒  E Z");
    Date d = sf.parse(str);
    System.out.println(d);
}
@Test
public void test9(){
    Date d = new Date();
    SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒  E Z");
    //把Date日期转成字符串,按照指定的格式转
    String str = sf.format(d);
    System.out.println(str);
}