字符串相关的类:String

String的特性

  • String类:代表字符串。Java程序中所有的字符串面值(如”abc”)都作为此类的实例实现。

  • 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。

  • String内部定义了final char[] value用于存储字符串数据。

    public final class String
    implements java.io.Serializable,Comparable<String>,CharSequence{
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash;//Default to 0
  • String实现了Serializable接口:表示字符串是支持序列化的;

    实现了Comparable接口:表示String可以比较大小。

  • String是一个final类,代表不可改变的字符序列

    简称:不可变性。

    体现:

    ① 当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。

    ② 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。

    ③ 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值。

  • 通过字面量的方式(区别于new)给一个字符赋值,此时的字符串值生命在字符串常量池中。

  • 字符串常量池中是不会存储相同内容的字符串的。

String对象的创建

String str = "hello";

//本质上this.value = new char[0];
String s1 = new String();

//this.value = original.value;
String s2 = new String(String original);

//this.value = Arrays.copyOf(value,value.length);
String s3 = new String(char[] a);

String s4 = new String(char[] a,int startIndex,int count);

String的实例化方式:

面试题:String str1 = "abc";String str2 = new String ("abc");的区别?

  1. 方式一:通过字面量定义的方式
  2. 方式二:通过 new + 构造器 的方式
/**
* String的实例化方式
* 方式一:通过字面量定义的方式
* 方式二:通过 new + 构造器 的方式
*/
@Test
public void test2(){
//通过字面量定义的方式:此时的s1和s2的数据JavaEE声明在方法区的字符串常量池中。
String s1 = "JavaEE";
String s2 = "JavaEE";

//通过 new + 构造器 的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
String s3 = new String("JavaEE");
String s4 = new String("JavaEE");

System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s2);//false
}

字符串对象是如何存储的

public class Person{
String name;
int age;

public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
public void test2(){
System.out.println("********************");
Person p1 = new Person("Tom",12);
Person p2 = new Person("Tom",12);

System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name == p2.name);//true
}

面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?

答:2个。一个是堆空间中new的结构,另一个是char[]对应的常量池中的数据(”abc”)。

练习题:

@Test
public void test3(){
String s1 = "JavaEE";
String s2 = "hadoop";

String s3 = "JavaEEhadoop";
String s4 = "JavaEE" + "hadoop";
String s5 = s1 + "hadoop";
String s6 = "JavaEE" + s2;
String s7 = s1 + s2;

System.out.println(s3 == s4);//true
System.out.println(s3 == s5);//false
System.out.println(s3 == s6);//false
System.out.println(s3 == s7);//false
System.out.println(s5 == s6);//false
System.out.println(s5 == s7);//false
System.out.println(s6 == s7);//false

String s8 = s5.intern();//返回值得到的s8使用的是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3 == s8);//true
}

结论:

  • 常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
  • 只要其中有一个变量,结果就在堆空间中。
  • 如果拼接的结果调用intern()方法,返回值就在常量池中。

**面试题:**下列程序运行的结果:

package top.triabin._01string.exer1;

/**
* @author DawnLee
* @create 2020-11-01 18:36
*/
public class StringTest {
String str = new String("good");
char[] ch = {'t','e','s','t'};

public void change(String str,char[] ch){
str = "test ok";
ch[0] = 'b';
}
public static void main(String[] args){
StringTest ex = new StringTest();
ex.change(ex.str,ex.ch);
System.out.print(ex.str + " and ");//good and
System.out.println(ex.ch);//best
}
}

分析:将属性str和ch的地址值分别赋给change()方法的形参str和ch,change()方法将形参str所指向的堆空间中的地址对应的常量池中的值修改,由于String具有不可变性,所以相当于在常量池中创建了一个新的字符串,因而只改变形参str的值而不改变属性str的值。ch为char型数组,不具有不可变性,所以形参ch改变后,属性ch也改变。

String常用方法

  1. int length():返回字符串的长度: return value.length。

  2. char charAt(int index):返回某索引处的字符:return value[index]。

  3. boolean isEmpty():判断是否是空字符串:return value.length == 0。

  4. String toLowerCase():使用默认语言环境,将String中的所有字符转换为小写。

  5. String toUpperCase():使用默认语言环境,将String中的所有字符转换为大写。

  6. String trim():返回字符串的副本,忽略前导空白和尾部空白。

  7. boolean equals(Object obj):比较字符串的内容是否相同。

  8. boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写。

  9. String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”。

  10. int compareTo(String anotherString):比较两个字符串的大小。

  11. String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。

  12. String substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。

  13. boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。

  14. boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始。

  15. boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始。

  16. boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true。

  17. int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。

  18. int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。

  19. int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引。

  20. int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。

    注:indexOf和lastIndexOf方法如果未找到都是返回-1。

  21. String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。

  22. String replace(CharSequence target,CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。

  23. String replaceAll(String regex, String replacement):使 用 给 定 的replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

  24. String replaceFirst(String regex, String replacement):使 用 给 定 的eplacement 替换此字符串匹配给定的正则表达式的第一个子字符串。

  25. boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。

  26. String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。

  27. String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。

使用:

package top.triabin._01string;

import org.junit.Test;

/**
* @author DawnLee
* @create 2020-11-02 20:27
*/
public class StringMethodTest {
/**
* 1.int length()
* 2.char charAt(int index)
* 3.boolean isEmpty()
* 4.String toLowerCase()
* 5.String toUpperCase()
* 6.String trim()
*/
@Test
public void test1() {
String s1 = "Hello World";
System.out.println(s1.length());
System.out.println(s1.charAt(0));
System.out.println(s1.charAt(10));
// System.out.println(s1.charAt(11));
// s1 = "";
System.out.println(s1.isEmpty());

String s2 = s1.toLowerCase();
System.out.println(s1);//s1不可变,仍为原来的字符串
System.out.println(s2);//改成小写以后的字符串
System.out.println(s2.toUpperCase());

String s3 = " he llo world ";
String s4 = s3.trim();
System.out.println("----" + s3 + "----");
System.out.println("----" + s4 + "----");
}

/**
* 7.boolean equals(Object obj)
* 8.boolean equalsIgnoreCase(String anotherString)
* 9.String concat(String str)
* 10.int compareTo(String anotherString)
* 11.String substring(int beginIndex)
* 12.String substring(int beginIndex, int endIndex)
*/
@Test
public void test2(){
String s1 = "HelloWorld";
String s2 = "helloworld";
System.out.println(s1.equals(s2));
System.out.println(s1.equalsIgnoreCase(s2));

String s3 = "abc";
String s4 = s3.concat("def");//一般用"+"号连接,不常用concat
System.out.println(s4);

String s5 = "abc";
String s6 = new String("abe");
System.out.println(s5.compareTo(s6));//涉及到字符串排序

String s7 = "北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
System.out.println(s8);

String s9 = s7.substring(2, 5);//左闭右开
System.out.println(s9);
}

/**
* 13.boolean endsWith(String suffix)
* 14.boolean startsWith(String prefix)
* 15.boolean startsWith(String prefix, int toffset)
*
* 16.boolean contains(CharSequence s)
* 17.int indexOf(String str)
* 18.int indexOf(String str, int fromIndex)
* 19.int lastIndexOf(String str)
* 20.int lastIndexOf(String str, int fromIndex)
*/
@Test
public void test3(){
String str1 = "helloworld";
boolean b1 = str1.endsWith("ld");
System.out.println(b1);

boolean b2 = str1.startsWith("He");
System.out.println(b2);

boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);

String str2 = "wo";
System.out.println(str1.contains(str2));

System.out.println(str1.indexOf("lo"));//没有则返回-1

System.out.println(str1.indexOf("lo",5));//-1

String str3 = "hellorworld";
System.out.println(str3.lastIndexOf("or"));//7
System.out.println(str3.lastIndexOf("or",6));//4
//什么情况下indexOf(str)和lastIndexOf(str)返回值相同?
//情况一:存在为唯一的str。 情况二:不存在str
}

/**
* 替换:
* 21.String replace(char oldChar, char newChar)
* 22.String replace(CharSequence target,CharSequence replacement)
* 23.String replaceAll(String regex, String replacement)
* 24.String replaceFirst(String regex, String replacement)
*
* 匹配:
* 25.boolean matches(String regex)
*
* 切片:
* 26.String[] split(String regex)
* 27.String[] split(String regex, int limit)
*/
@Test
public void test4(){
String str1 = "北京尚硅谷教育北京";
String str2 = str1.replace('北', '东');
System.out.println(str1);
System.out.println(str2);

String str3 = str1.replace("北京", "上海");
System.out.println(str3);

String str = "12hello34world5java7891mysql456";
//把字符串中的数字替换成逗号,如果结果中开头和结尾有逗号的话去掉
String string = str.replaceAll("\\d+", ",").replaceAll("^,|,$", "");
System.out.println(string);

str = "12345";
//判断str字符串中是否全部有数字组成,即有1-n个数字组成
boolean matches = str.matches("\\d+");
System.out.println(matches);
String tel = "0571-4534289";
//判断这是否是一个杭州的固定电话
boolean result = tel.matches("0571-\\d{7,8}");
System.out.println(result);

str = "hello|world|java";
String[] strs = str.split("\\|");
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
System.out.println();
str2 = "hello.world.java";
String[] strs2 = str2.split("\\.");
for (int i = 0; i < strs2.length; i++) {
System.out.println(strs2[i]);
}
}
}
  • test1()

  • test2()

  • test3()

  • test4()

String与基本数据类型转换

  • 字符串 → 基本数据类型、包装类

    ① Integer包装类的public static int parseInt(String s):可将由“数字”字符组成的字符串转换为整形。

    ② 类似的,使用java.lang包中的Byte、Short、Long、Float、Double类调相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。

  • 基本数据类型、包装类 → 字符串

    ① 调用String类的public String valueOf(int n)可将int型转换为字符串。

    ② 相应的,valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double d)、valueOf(boolean b)可由参数的相应类型2到字符串的转换。

  • 字符数组 → 字符串

    ① String类的构造器:String(char[])和String(char[], int offset, int length)分别用字符数组中的全部字符和部分字符创建字符串对象。

  • 字符串 → 字符数组

    ① public char[] toCharArray():将字符串中的全部字符存放在一个字符数组中的方法。

    ② public void getChars(int srcBegin, int srcEnd, char dst, int dstBegin):提供了将制定索引范围内的字符串存放到数组中的方法。

  • 字节数组 → 字符串

    ① String(byte[]):通过使用平台的默认字符集解码指定的byte数组,构造一个新的String。

    ② String(byte[], int offset, int length):用指定的字节数组的一部分,即从数组起始位置offset开始取length个字节构成一个字符串对象。

  • 字符串 → 字节数组

    ① public byte[] getBytes():使用平台的默认字符集将此String编码为byte序列,并将结果存储到一个新的byte数组中。

    ② public byte[] getBytes(String charsetName):使用指定的字符集将此String编码到byte序列,并将结果存储到新的byte数组。

  • 实际应用

    package top.triabin._01string;

    import org.junit.Test;

    import java.io.UnsupportedEncodingException;
    import java.util.Arrays;

    /**
    * 涉及到String类与其他结构之间的转换
    *
    * @author DawnLee
    * @create 2020-11-03 14:12
    */
    public class StringTest1 {
    /**
    * String与基本数据类型、包装类之间的转换
    */
    @Test
    public void test1(){
    //字符串 → 基本数据类型、包装类
    String str1 = "123";
    int num = Integer.parseInt(str1);//123

    //基本数据类型、包装类 → 字符串
    String str2 = String.valueOf(num);//"123"
    String str3 = num + "";//"123"
    }

    /**
    * String与char[]之间的转换
    */
    @Test
    public void test2(){
    String str1 = "abc123";//题目:反转字符串指定部分字母,例:a21cb3
    //Sting → char[]:调用String的toCharArray()方法
    char[] charArray = str1.toCharArray();
    for (int i = 0; i < charArray.length; i++) {
    System.out.println(charArray[i]);
    }

    //char[] → Sting:调用String的构造器
    char[] arr = new char[]{'h','e','l','l','o'};
    String str2 = new String(arr);
    System.out.println(str2);
    }

    /**
    * String与byte[]之间的转换
    *
    * 编码:字符串 → 字节
    * 解码:解码的逆过程,字节 → 字符串
    *
    * 说明:解码时,要求解码使用的字符集必须与编码使用的字符集一致,否则会出现乱码
    */
    @Test
    public void test3() throws UnsupportedEncodingException {
    String str1 = "abc123中国";
    System.out.println("原字符串str1:" + str1);

    //String → byte[]:调用String的getBytes()方法
    byte[] bytes = str1.getBytes();//使用默认的字符集,进行编码
    System.out.println("使用默认的字符集(UTF-8)编码str1为bytes:" + Arrays.toString(bytes));

    byte[] gbks = str1.getBytes("gbk");//使用gbk字符集进行编码
    System.out.println("使用gbk编码str1为gbks:" + Arrays.toString(gbks));

    //byte[] → String:
    String str2 = new String(bytes);//使用默认的字符集,进行解码
    System.out.println("使用默认字符集(UTF-8)解码bytes:" + str2);
    String str3 = new String(gbks);
    System.out.println("使用默认字符集(UTF-8)解码gbks:" + str3);//出现乱码,原因:编码集和解码集不一致

    String str4 = new String(gbks,"gbk");//指定解码方式为gbk
    System.out.println("使用gbk解码gbks:" + str4);//没有出现乱码,原因:编码集与解码集一致
    }
    }

    ① test1():String与基本数据类型、包装类之间的转换

    ② test2():String与char[]之间的转换

    ③ test3():String与byte[]之间的转换

常见算法题目(讲解在P41)

模拟一个trim方法,去除字符串两端的空格。

将一个字符串进行反转。将字符串中指定部分进行反转。

比如“abcdefg”反转为”abfedcg”。

获取一个字符串在另一个字符串中出现的次数。

比如:获取“ab”在“abkkcadkabkebfkabkskab”中出现的次数。

获取两个字符串中最大相同子串。

比如:str1 = “abcwerthelloyuiodef“;str2 = “cvhellobnm”
提示:将短的那个串进行长度依次递减的子串与较长的串比较。

对字符串中字符进行自然顺序排序。

提示:
1)字符串变成字符数组。
2)对数组排序、选择、冒泡,Arrays.sort();
3)将排序后的数组变成字符串。

StringBuffer与StringBuilder类

String/StringBuffer、StringBuilder三者的异同?

  • String:不可变的字符序列;底层结构使用char[]存储。
  • StringBuffer:可变的字符序列;线程安全的,效率低;底层结构使用char[]存储。
  • StringBuilder:可变的字符序列;JDK 5.0新增的,线程不安全的,效率高;底层结构使用char[]存储。

源码分析:

String str = new String();//char[] value = new char[];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};

StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度为16的数组。
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
sb1.append('c');//value[2] = 'c';

StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length + 16];

问题1 System.out.println(sb2.length());//3

问题2 扩容问题,如果要添加的数据底层数组存不下了,那就需要扩容底层数组。
默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中。

指导意义:开发中建议使用StringBuffer(int capacity)或StringBuilder(int capacity)以指定长度,避免扩容浪费资源,降低效率。

StringBuffer的常用方法:(StringBuilder与它相同)

  1. StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接。

  2. StringBuffer delete(int start,int end):删除指定位置的内容。

  3. StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str。

  4. StringBuffer insert(int offset, xxx):在指定位置插入xxx。

  5. StringBuffer reverse() :把当前字符序列逆转。

  6. public int indexOf(String str):返回字符串第一次出现的索引。

  7. public String substring(int start,int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串。

  8. public int length():

  9. public char charAt(int n)

  10. public void setCharAt(int n ,char ch)

  • 总结:

    增:append(xxx)
    删:delete(int start,int end)
    改:setCharAt(int n ,char ch)修改一个字符,replace(int start, int end, String str)修改一个字符串
    查:char charAt(int n)
    插:insert(int offset, xxx)
    长度:length()
    *遍历:for() + charAt()、toString()

应用:

package top.triabin._01string;

import org.junit.Test;

/**
* 关于StringBuffer和StringBuilder的使用
*
* @author DawnLee
* @create 2020-11-03 15:21
*/
public class StringBufferBuilderTest {
/*
String/StringBuffer、StringBuilder三者的异同?
String:不可变的字符序列;底层结构使用char[]存储;
StringBuffer:可变的字符序列;线程安全的,效率低;底层结构使用char[]存储;
StringBuilder:可变的字符序列;JDK 5.0新增的,线程不安全的,效率高;底层结构使用char[]存储;
*/
@Test
public void test1(){
StringBuffer sb1 = new StringBuffer("abc");
sb1.setCharAt(0,'m');
System.out.println(sb1);//mbc,可变

StringBuffer sb2 = new StringBuffer();
System.out.println(sb2.length());//0
}

/**
* StringBuffer的常用方法:(StringBuilder与它相同)
*/
@Test
public void test2(){
StringBuffer s1 = new StringBuffer("abc");
s1.append(1);
s1.append('2');
System.out.println(s1);//abc12

// s1.delete(2,4);//ab2
// s1.replace(2,4,"hello");//abhello2
// s1.insert(2,false);//abfalsec12,s1.length() = 10
// s1.reverse();//21cba
String s2 = s1.substring(1, 3);//bc
System.out.println(s1);
System.out.println(s2);
}

/**
* 对比String、StringBuffer、StringBuilder三者的效率
* 从高到低:StringBuilder > StringBuffer > String
*/
@Test
public void test3(){
//初始设置
long startTime = 0L;
long endTime = 0L;
String text = "";
StringBuffer buffer = new StringBuffer("");
StringBuilder builder = new StringBuilder("");
//开始对比
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++){
text = text + i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime));
}
}
  • test1():String/StringBuffer、StringBuilder三者的异同

  • test2():StringBuffer的常用方法:(StringBuilder与它相同)

  • test3(): 对比String、StringBuffer、StringBuilder三者的效率

JDK 8之前的日期时间API

java.lang.System类

  • System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。

  • 此方法适于计算时间差。

  • 计算世界时间的主要标准有

    • UTC(Coordinated Universal Time)
    • GMT(Greenwich Mean Time)
    • CST(Central Standard Time)
  • 应用

    /**
    * System类中的currentTimeMillis()
    */
    @Test
    public void test1(){
    long time = System.currentTimeMillis();
    //返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
    //称为时间戳
    System.out.println(time);
    }

java.util.Date类

​ 表示特定的瞬间,精确到毫秒。

  • 构造器:

    ① Date():使用无参构造器创建的对象可以获取本地的当前时间。

    ② Date(long date)

  • 常用方法

    ① getTime():返回自1970年1月1日00:00:00 GMT以来此Date对象表示的毫秒数。

    ② toString():把此Date对象转换成以下形式的String:dow mon dd hh:mm:ss zzz yyyy 其中:dow是一周中的某一天(Sun,Mon,Tue,Wed,Thu,Fri,Sat),zzz是时间标准。

    ③ 其他很多方法都过时了。

  • 应用

    /**
    * java.util.Date类
    * |---java.sql.Date类
    * 1.两个构造器的使用
    * >构造器一:Date():创建一个对应当前时间的Date对象
    * >构造器二:创建指定毫秒数的对象
    *
    * 2.两个方法的使用
    * >toString():显示当前年、月、日、时、分、秒
    * >getTime():获取当前Date对象对应的的时间戳。
    *
    * 3.java.sql.Date对应着数据库中的日期类型变量
    * >如何实例化
    * >如何将java.util.Date对象转换为java.sql.Date对象
    */
    @Test
    public void test2(){
    //构造器一:Date():创建一个对应当前时间的Date对象
    Date date1 = new Date();
    System.out.println(date1.toString());//Wed Nov 04 22:40:52 CST 2020

    System.out.println(date1.getTime());//1604500906084

    //构造器二:创建指定毫秒数的对象
    Date date2 = new Date(1604500906084L);
    System.out.println(date2.toString());//Wed Nov 04 22:41:46 CST 2020

    //创建java.sql.Date对象
    java.sql.Date date3 = new java.sql.Date(1604500906084L);
    System.out.println(date3);//2020-11-04

    //如何将java.util.Date对象转换为java.sql.Date对象
    //情况一:
    // Date date4 = new java.sql.Date(1604500906084L);
    // java.sql.Date date5 = (java.sql.Date) date4;
    //情况二:
    Date date6 = new Date();
    java.sql.Date date7 = new java.sql.Date(date6.getTime());
    }

java.text.SimpleDateFormat类

SimpleDateFormat的使用:SimpleDateFormat对日期Date类的格式化和解析。

  • 两个操作

    ① 格式化:日期 → 字符串

    ② 解析:格式化的逆过程,字符串 → 日期

  • 实例化

  • 应用

    /**
    * SimpleDateFormat的使用:SimpleDateFormat对日期Date类的格式化和解析
    *
    * 1.两个操作:
    * 1.1 格式化:日期 --> 字符串
    * 1.2 解析:格式化的逆过程,字符串 --> 日期
    *
    * 2.SimpleDateFormat的实例化
    */
    @Test
    public void test3(){
    //实例化SimpleDateFormat:使用默认构造器
    SimpleDateFormat sdf = new SimpleDateFormat();

    //格式化:日期 --> 字符串
    Date date = new Date();
    System.out.println(date);

    String format = sdf.format(date);
    System.out.println(format);//20-11-6 下午10:13

    //解析:格式化的逆过程,字符串 --> 日期
    String str = "20-11-6 下午10:13";
    Date date1 = null;
    try {
    date1 = sdf.parse(str);
    } catch (ParseException e) {
    e.printStackTrace();
    }
    System.out.println(date1);

    //************按照指定的方式格式化和解析:调用带参的构造器*****************
    // SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss aaa");
    String format1 = sdf1.format(date);
    System.out.println(format1);//2020-11-06 10:23:14 下午

    //解析:要求字符串必须符合SimpleDateFormat识别的格式(通过构造器参数体现)
    Date date2 = null;
    try {
    date2 = sdf1.parse("2020-11-06 10:23:14 下午");
    } catch (ParseException e) {
    e.printStackTrace();
    }
    System.out.println(date2);
    }

练习:将字符串”2020-09-08”转换为java.sql.Date

/**
* 练习一:字符串"2020-09-08"转换为java.sql.Date
*/
@Test
public void testExer(){
String birth = "2020-09-08";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try{
date = sdf.parse(birth);
}catch(ParseException e){
e.printStackTrace();
}
java.sql.Date birthDate = new java.sql.Date(date.getTime());
System.out.println(birthDate);
}

java.util.Calender(日历)类

  • Calendar是一个抽象基类,主要用于完成日期字段之间相互操作的功能。

  • 获取Calendar实例的方法:

    ① 使用Calendar.getInstance()方法

    ② 调用它的子类GregorianCalendar的构造器

  • 一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY、MINUTE、SECOND。

    ①pubilc void set(int field,int value):field为本周/月/年的第几天,将今天改为指定周/月/年的第value天;

    ②public void add(int field,int amount):将本周/月/年的第field天加/减amount天;

    ③public final Date getTime():将Calendar类转换为Date类;

    ④public fianl void setTime(Date date):将Date类转换为Calendar类。

  • 注意:

    ①获取月份时:月是0,二月是1,以此类推,12月是11;

    ②获取星期时:周日是1,周一是2……周六是7。

  • 实际应用

    /**
    * Calendar日历类(抽象类)的使用
    */
    @Test
    public void testCalendar(){
    //1.实例化
    //方式一:创建其子类(GregorianCalendar)的对象
    //方式二:调用其静态方法getInstance()
    Calendar calendar = Calendar.getInstance();
    // System.out.println(calendar.getClass());

    //2.常用方法
    //get()
    int days = calendar.get(Calendar.DAY_OF_MONTH);//返回今天是本月的第几天
    System.out.println(days);
    System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//返回今天是今年的第几天

    //set()
    calendar.set(Calendar.DAY_OF_MONTH,22);//将今天改为本月第22天
    days = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(days);//22

    //add()
    calendar.add(Calendar.DAY_OF_MONTH,3);
    days = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(days);//25(22 + 3),减相应天数则将amount改为负数即可

    //getTime():日历类 --> Date
    Date date = calendar.getTime();
    System.out.println(date);

    //setTime():Date --> 日历类
    Date date1 = new Date();
    calendar.setTime(date1);
    days = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(days);
    }

JDK 8中新日期时间API

新时间日期API出现的背景

如果我们可以跟别人说:“我们在1502643933071见面,别晚了!”那么就再简单不过了。但是我们希望时间与昼夜和四季有关,于是事情就变复杂了。JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar并不比Date好多少。它们面临的问题是:

  • 可变性:像日期和时间这样的类应该是不可变的。
  • 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
  • 格式化:格式化只对Date有用,Calendar则不行。
  • 此外,它们也不是线程安全的;不能处理闰秒等。

总结:对日期和时间的操作一直是Java程序员最痛苦的地方之一。

闰秒,是指为保持协调世界时接近于世界时时刻,由国际计昰局统规定在年底或年中(也可能在季末)对协调世界时増加或减少1秒的调整。由于地球自转的不均匀性和长期变愠性(主要由潮汐摩擦引起的),会使世界时(民用时)和原子时之间相差超过到±0.9秒时,就把协调世界时向前拨1秒(负闰秒,最后一分钟为59秒)或向后拨1秒(正闰秒,最后一分钟为61秒);闰秒一般加在公历年未或公历六月末。

目前,全球已经进行了27次闰秒,均为正闰秒。

新时间日期API

Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的 API。新的 java.time 中包含了所有关于本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。历史悠久的 Date 类新增了 toInstant() 方法,用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简化了日期时间和本地化的管理。

  • java.time:包含值对象的基础包;
  • java.time.chrono:提供对不同的日历系统的访问;
  • java.time.format – 格式化和解析时间和日期;
  • java.time.temporal – 包括底层框架和扩展特性;
  • java.time.zone – 包含时区支持的类。

说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一。

  • LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。

    ①LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。

    ②LocalTime表示一个时间,而不是日期。

    ③LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一

注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法,也就是公历。

方法 描述
now() / now(ZondId zone) 静态方法,根据当前时间创建对象/指定时区的对象
of() 静态方法,根据指定日期/时间创建对象
getDayOfMonth() / getDayOfYear() 获得月份天数(131) / 年份天数(1366)
getDayOfWeek() 获得星期几(返回一个DayOfWeek枚举值)
getMonth() 获得月份,获得一个Month枚举值
getMonthValue() / getYear() 获得月份(1~12) / 获得年份
getHour() / getMinute() / getSecond() 获得当前对象对应的时、分、秒
withDayOfMonth() / withDayOfYear() / withMonth() / withYear() 将月份天数、年份天数、月份、年份、修改为指定的值并返回先新的对象
plusDays(), plusWeeks(), plusMonths(), plusYears(), plusHours() 向当前对象添加几天、几周、几个月、几年、几小时
minusMonths() / minusWeeks() / minusDays() / minusYears() / minusHours() / 从当前对象减去几月、几周、几天、几年、几小时

应用:

/**
* LocalDate、LocalTime、LocalDateTime的使用
*
* 说明:
* 1.LocalDateTime相较于LocalDate、LocalTime,使用频率更高。
* 2.类似于Calendar
*/
@Test
public void test1() {
//now():获取当前的日期、时间或日期+时间
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();

System.out.println(localDate);//2020-11-13
System.out.println(localTime);//12:16:39.144
System.out.println(localDateTime);//2020-11-13T12:16:39.144

//of():设置指定的年、月、日、时、分、秒,没有偏移量
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 11, 12, 12, 14, 59);
System.out.println(localDateTime1);//2020-11-12T12:14:59

//getXxx():获取相关属性
System.out.println(localDateTime.getDayOfMonth());//13
System.out.println(localDateTime.getDayOfWeek());//FRIDAY
System.out.println(localDateTime.getMonth());//NOVEMBER
System.out.println(localDateTime.getMonthValue());//11
System.out.println(localDateTime.getMinute());//20

//体现不可变性
//withXxx():设置相关属性
LocalDate localDate1 = localDate.withDayOfMonth(22);
System.out.println(localDate);//2020-11-13
System.out.println(localDate1);//2020-11-22

LocalDateTime localDateTime2 = localDateTime.withHour(4);
System.out.println(localDateTime);//2020-11-13T12:25:18.535
System.out.println(localDateTime2);//2020-11-13T04:25:18.535

//仍体现不可变性
LocalDateTime localDateTime3 = localDateTime.plusMonths(3);
System.out.println(localDateTime);//2020-11-13T12:28:01.609
System.out.println(localDateTime3);//2021-02-13T12:28:01.609

LocalDateTime localDateTime4 = localDateTime.minusDays(6);
System.out.println(localDateTime);//2020-11-13T12:30:29.578
System.out.println(localDateTime4);//2020-11-07T12:30:29.578
}

瞬时:Instant

  • Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。
  • 在处理时间和日期的时候,我们通常会想到年,月,日,时,分,秒。然而,这只是时间的一个模型,是面向人类的。第二种通用模型是面向机器的,或者说是连续的。在此模型中,时间线中的一个点表示为一个很大的数,这有利于计算机处理。在UNIX中,这个数从1970年开始,以秒为的单位;同样的,在Java中,也是从1970年开始,但以毫秒为单位。
  • java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间单位。Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒UTC)开始的秒数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。
  • (1 ns = 10-9 s) 1秒 = 1000毫秒 =106微秒=109纳秒。
方法 描述
now() 静态方法,返回默认UTC时区的Instant类的对象
ofEpochMilli(long epochMilli) 静态方法,返回返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象
atOffset(ZoneOffset offset) 结合即时的偏移来创建一个OffsetDateTime
toEpochMilli() 返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳

时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

应用:

/**
* Instant的使用
*
* 类似于java.util.Date类
*/
@Test
public void test2(){
//now():获取本初子午线对应的标准时间
Instant instant = Instant.now();
System.out.println(instant);//2020-11-13T04:49:25.712Z

//添加时间的偏移量
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);//2020-11-13T12:51:00.439+08:00

//toEpochMilli():获取自1970-01-01 00:00:00(UTC)到当前时间的毫秒数 --> 类似Date类的getTime()
long milli = instant.toEpochMilli();
System.out.println(milli);//1605243305678

//ofEpochMilli():通过给定的毫秒数,获取Instant实例 --> 类似Date(long millis)
Instant instant1 = Instant.ofEpochMilli(1605243305678L);
System.out.println(instant1);//2020-11-13T04:55:05.678Z
}

格式化与解析日期或时间

java.time.format.DateTimeFormatter 类:该类提供了三种格式化方法:

  • 预定义的标准格式。如

    ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME

  • 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)

  • 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)

方法 描述
ofPattern(String pattern) 静态方法,返回一个指定字符串格式的DateTimeFormatter
format(TemporalAccessor t) 格式化一个日期、时间,返回字符串
parse(CharSequence text) 将指定格式的字符串解析为一个日期、时间

应用:

/**
* DateTimeFormatter:格式化或解析日期、时间
* 类似于SimpleDateFormat
*/
@Test
public void test3(){
//实例化方式一:预定义标准格式
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化:日期 --> 字符串
LocalDateTime localDateTime = LocalDateTime.now();
String str1 = formatter.format(localDateTime);
System.out.println(localDateTime);//2020-11-13T13:13:58.363
System.out.println(str1);//显示结果相同,只是类型变了
//解析:字符串 --> 日期
TemporalAccessor parse = formatter.parse("2020-11-13T13:13:58.363");
System.out.println(parse);//{},ISO resolved to 2020-11-13T13:13:58.363

//实例化方式二:本地化相关的格式。如ofLocalDateTime()
//FormatStyle.LONG/MEDIUM/SHORT:适用于LocalDateTime
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
//格式化
String str2 = formatter1.format(LocalDateTime.now());
System.out.println(str2);//2020年11月13日 下午01时35分39秒
//解析略

//ofLocalDate()
//FormatStyle.FULL/LONG/MEDIUM/SHORT
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
//格式化
String str3 = formatter2.format(LocalDate.now());
System.out.println(str3);//2020年11月13日 星期五

//重点:方式三:自定义格式。如:ofPattern("yyyy-MM-dd hh:mm:ss E")
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
//格式化
String str4 = formatter3.format(LocalDateTime.now());
System.out.println(str4);//2020-11-13 04:45:27
//解析
TemporalAccessor parse1 = formatter3.parse("2020-11-13 04:45:27");
System.out.println(parse1);//{HourOfAmPm=4, MinuteOfHour=45, SecondOfMinute=27, MilliOfSecond=0, NanoOfSecond=0, MicroOfSecond=0},ISO resolved to 2020-11-13
}

其他API

  • ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris。

  • ZonedDateTime:一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris。

    • 其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等。
  • Clock:使用时区提供对当前即时、日期和时间的访问的时钟。

  • 持续时间:Duration,用于计算两个“时间”间隔。

  • 日期间隔:Period,用于计算两个“日期”间隔。

  • TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。

  • TemporalAdjusters : 该类通过静态方法。

    (firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用TemporalAdjuster 的实现。

参考:与传统日期处理的转换

Java比较器

方式一:自然排序(java.lang.Comparable)

/**
* Comparable使用举例:自然排序
* 1.像String、包装类等实现了Comparable接口,重写了compareTo()方法,给出了比较两个对象大小的方法
* 2.像String、包装类重写compareTo()方法后,进行了从小到大的排列
* 3.重写compareTo(obj)的规则:
* 如果当前对象this大于形参对象obj,则返回正整数,
* 如果当前对象this小于形参对象obj,则返回负整数,
* 如果当前对象this等于形参对象obj,则返回零。
* 4.对于自定义类来说,如果需要排序,则让自定义类实现Comparable接口,重写compareTo()方法。
* 在compareTo(obj)方法中指明如何排序
*/
@Test
public void test1() {
String[] arr = new String[]{"AA", "CC", "KK", "MM", "GG", "JJ", "DD"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}

@Test
public void test2(){
Goods[] arr = new Goods[5];
arr[0] = new Goods("lenovoMouse",34);
arr[1] = new Goods("dellMouse",43);
arr[2] = new Goods("xiaomiMouse",23);
arr[3] = new Goods("huaweiMouse",65);
arr[4] = new Goods("microsoftMouse",43);

Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//[Goods{name='xiaomiMouse', price=23.0}, Goods{name='lenovoMouse', price=34.0}, Goods{name='dellMouse', price=43.0}, Goods{name='microsoftMouse', price=43.0}, Goods{name='huaweiMouse', price=65.0}]
}

方式二:定制排序(java.util.Comparator)

/**
* Comparator接口的使用:定制排序
*
* 1.背景:当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
* 或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那
* 么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排
* 序的比较。
* 2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
* 如果返回正整数,o1 > o2;
* 如果返回负整数,o1 < o2;
* 如果返回0,则o1 = o2。
*/
@Test
public void test3(){
String[] arr = new String[]{"AA", "CC", "KK", "MM", "GG", "JJ", "DD"};
Arrays.sort(arr,new Comparator(){
//按照字符串从大到小的顺序排列
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof String && o2 instanceof String){
String s1 = (String)o1;
String s2 = (String)o2;
return -s1.compareTo(s2);//从大到小
}
throw new RuntimeException("输入数据不一致!");
}
});
System.out.println(Arrays.toString(arr));//[MM, KK, JJ, GG, DD, CC, AA]
}
/**
* 练习
*/
@Test
public void test4(){
Goods[] arr = new Goods[6];
arr[0] = new Goods("lenovoMouse",34);
arr[1] = new Goods("dellMouse",43);
arr[2] = new Goods("xiaomiMouse",23);
arr[3] = new Goods("huaweiMouse",65);
arr[4] = new Goods("huaweiMouse",22);
arr[5] = new Goods("microsoftMouse",43);

Arrays.sort(arr, new Comparator() {

//先按照产品名称从高到低,在按照价格从高到低排序
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Goods && o2 instanceof Goods){
Goods g1 = (Goods)o1;
Goods g2 = (Goods)o2;
if(g1.getName().equals(g2.getName())){
return -Double.compare(g1.getPrice(),g2.getPrice());
}else{
return g1.getName().compareTo(g2.getName());
}
}
throw new RuntimeException("输入数据不一致!");
}
});
System.out.println(Arrays.toString(arr));
//[Goods{name='dellMouse', price=43.0}, Goods{name='huaweiMouse', price=65.0}, Goods{name='huaweiMouse', price=22.0}, Goods{name='lenovoMouse', price=34.0}, Goods{name='microsoftMouse', price=43.0}, Goods{name='xiaomiMouse', price=23.0}]
}

System类

  • System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。

  • 由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用。

  • 成员变量:System类内部包含in、out和err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。

  • 成员方法

    ①native long currentTimeMillis():该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。

    ②void exit(int status):该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。

    ③void gc():该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。

    ④String getProperty(String key):该方法的作用是获得系统中属性名为key的属性对应的值。系统中常见的属性名以及属性的作用如下表所示:

    属性名 属性说明
    java.version Java运行时环境版本
    java.home Java安装目录
    os.name 操作系统名称
    os.version 操作系统版本
    user.name 用户的账户名称
    user.home 用户的主目录
    user.dir 用户的当前工作目录
package top.triabin._05system;

import org.junit.Test;

/**
* System类的使用
*
* @author DawnLee
* @create 2020-11-13 22:20
*/
public class SystemTest {
@Test
public void test(){
String javaVersion = System.getProperty("java.version");
System.out.println("java的version:" + javaVersion);

String javaHome = System.getProperty("java.home");
System.out.println("java的home:" + javaHome);

String osName = System.getProperty("os.name");
System.out.println("os的name:" + osName);

String osVersion = System.getProperty("os.version");
System.out.println("os的version:" + osVersion);

String userName = System.getProperty("user.name");
System.out.println("user的name:" + userName);

String userHome = System.getProperty("user.home");
System.out.println("user的home:" + userHome);

String userDir = System.getProperty("user.dir");
System.out.println("user的dir:" + userDir);
}
}

Math类

  • java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型。
  1. abs:绝对值
  2. acos,asin,atan,cos,sin,tan:三角函数
  3. sqrt:平方根
  4. pow(double a,doble b):a的b次幂
  5. log:自然对数
  6. exp:e为底指数
  7. max(double a,double b):获取两数之中的较大值
  8. min(double a,double b):获取两数之中的较小值
  9. random():返回0.0到1.0的随机数
  10. long round(double a):double型数据a转换为long型(四舍五入)
  11. toDegrees(double angrad):弧度—>角度
  12. toRadians(double angdeg) 角度—>弧度

BigInteger与BigDecimal

BigInteger

  • Integer类作为int的包装类,能存储的最大整型值为231-1,Long类也是有限的,最大为263-1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。

  • java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。

  • 构造器

    BigInteger(String val):根据字符串构建BigInteger对象

  • 常用方法

    ①public BigInteger abs():返回此 BigInteger 的绝对值的 BigInteger。

    ②BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger。

    ③BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger。

    ④BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger。

    ⑤BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数相除只保留整数部分。

    ⑥BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。

    ⑦BigInteger[] divideAndRemainder(BigInteger val):返回包含(this / val)后跟(this % val)的两个igInteger的数组。

    ⑧BigInteger pow(int exponent) :返回其值为 (thisexponent) 的 BigInteger。

BigDecimal

  • 一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。

  • BigDecimal类支持不可变的、任意精度的有符号十进制定点数。

  • 构造器

    ①public BigDecimal(double val)

    ②public BigDecimal(String val)

  • 常用方法

    ①public BigDecimal add(BigDecimal augend)

    ②public BigDecimal subtract(BigDecimal subtrahend)

    ③public BigDecimal multiply(BigDecimal multiplicand)

    ④public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

package top.triabin._07bigintegerdecimal;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
* BigInteger和BigDecimal类常用方法的使用
*
* @author DawnLee
* @create 2020-11-13 22:47
*/
public class InteDeciTest {
@org.junit.Test
public void test(){
BigInteger bi = new BigInteger("12433241123");
BigDecimal bd = new BigDecimal("12435.351");
BigDecimal bd2 = new BigDecimal("11");
System.out.println(bi);
// System.out.println(bd.divide(bd2));
System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));
System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP));//保留15位小数
}
}

器章节练习与面试题