Java工具類——數學相關的類

在上一篇文章中,我們系統學習了 Java 裏面的包裝類,那麼這篇文章,我們就來學習一下Java提供好的類——數學相關的類。

一、數學類介紹

在最早期學習 Java 基礎語法結構的時候,其實我們學習並瞭解了加減乘除這些算數運算符,有了這些運算符,我們就可以做一些簡單的運算了,但是當我們需要做一些比較複雜的運算的時候,其實用這些運算符是很難去處理的(比如獲取隨機數等等)。其實數學類對於我們並不陌生,在學習 Java 基礎的時候,你一定用過 Math 類的,這個其實就是我們最早期接觸的一個數學類了,其實與數學相關的類還有 BigInteger 類、BigDecimal 類等等,下面這個表格將這三個類做了一個小的梳理總結:

數學類 所屬包 繼承關係
Math類 java.lang包,不需要導包 默認繼承Object基類
BigInteger類 java.math包,需要導包 繼承自Number類,實現了Serializable, Comparable接口
BigDecimal類 java.math包,需要導包 繼承自Number類,實現了Serializable, Comparable接口

下面我們就對這三種類做一個詳細的學習。

二、Math類

其實看源碼我們看到,Math 這個類是 final 修飾的,意思就是不能讓子類去繼承的,只能使用這個類。

public final class Math {}

下面,我們來詳細瞭解一下Math類

1、Math類構造方法

通過看源碼,我們可以得知 Math 這個類的構造方法是私有的,也就是我們是不能創建對象的,爲什麼會這樣設計呢,其實是因爲 Math 類裏面的屬性和方法都是靜態的( static 修飾)。

/**
 * Don't let anyone instantiate this class.
 */
private Math() {}

2、Math類常用的方法

  • abs()方法 返回給定數的絕對值,方法提供了4個不同參數類型重載方法(int, long, float, double)
int abs1 = Math.abs(-1);
long abs2 = Math.abs(-3l);
float abs3 = Math.abs(-1.2f);
double abs4 = Math.abs(-3.923);
System.out.println(abs1);
System.out.println(abs2);
System.out.println(abs3);
System.out.println(abs4);
  • ceil()方法 返回大於或等於參數且等於一個數學整數的最小的雙精度值,可以理解爲向上取整。
System.out.println(Math.ceil(-1.3));//-1.0
System.out.println(Math.ceil(1.9));//2.0
System.out.println(Math.ceil(-7.9));//-7.0
System.out.println(Math.ceil(123));//123.0
  • floor()方法 返回最大的雙精度值,該雙精度值小於或等於參數,並且等於一個數學整數,可以理解爲向下取整。
System.out.println(Math.floor(-1.3));//-2.0
System.out.println(Math.floor(1.9));//1.0
System.out.println(Math.floor(1.3));//1.0
System.out.println(Math.floor(-7.9));//-8.0
System.out.println(Math.floor(123));//123.0
  • round()方法 返回與參數最接近的整型數,四捨五入爲正無窮,其實就是四捨五入的整數。
System.out.println(Math.round(-1.3));//-1
System.out.println(Math.round(1.9));//2
System.out.println(Math.round(1.3));//1
System.out.println(Math.round(-7.9));//-8
System.out.println(Math.round(123));//123
  • max()方法 返回最大值,該方法提供了4個不同參數類型重載方法(int,long,float,double)
System.out.println(Math.max(1, 3));//3
System.out.println(Math.max(-4, -5));//-4
System.out.println(Math.max(1.8, 1.92));//1.92
System.out.println(Math.max(-4f, -4f));//-4.0
  • min(a, b)方法 返回最小值,該方法提供了4個不同參數類型重載方法(int, long, float, double)
System.out.println(Math.min(1, 3));//1
System.out.println(Math.min(-4, -5));//-5
System.out.println(Math.min(1.8, 1.92));//1.8
System.out.println(Math.min(-4f, -4f));//-4.0
  • pow(a, b)方法 返回 a 的 b 次方,其中參數和返回值都是 double 類型的
System.out.println(Math.pow(3, 3));//27.0
System.out.println(Math.pow(3.2, 5));//335.5443200000001
  • random()方法 生成一個 double 類型的隨機數,範圍是[ 0.0, 1.0),注意是左閉右開。
System.out.println(Math.random());//0.4128879706448445
System.out.println(Math.random());//0.9024029619163387
System.out.println(Math.random());//0.4265563513755902

三、BigInteger類

我們都知道,在基本數據類型裏面,long型的取值範圍是最大的,也就是8個字節,取值範圍是-2的63次方到正的2的63次方減去1,當然,這個取值範圍很大很大,在平時的開發中,我們其中只用到int類型的都基本夠了,但是當我們存儲的數據的長度超過了 long 型的長度時,我們該怎麼存儲呢?這時候,BigInteger 類就可以解決我們的問題。

BigInteger 顧名思義,其實就是叫大整數,也就是說只能存儲整型的數,我們通過構造方法和常用方法來了解BigInteger 類。

1、構造方法

BigInteger 類有8個構造方法,其中有2個私有構造方法。8個構造方法分別是:

private BigInteger(int[] val){}
private BigInteger(int signum, int[] magnitude){}
public BigInteger(byte[] val){}
public BigInteger(String val){}
public BigInteger(String val, int radix) {}
public BigInteger(int signum, byte[] magnitude){}
public BigInteger(int numBits, Random rnd){}
public BigInteger(int bitLength, int certainty, Random rnd){}

2、類中常用的方法

當我們想用這個類做四則運算的時候,是不是也可以直接加減乘除呢,比如下面這張圖:

通過上面這張圖,BigInteger類直接做四則運算顯然是不可以的,因爲上面兩個數是引用類型,而運算符只能對基本數據類型做運算。那麼我們怎麼做相應的四則運算呢?其實BigInteger類裏面其實已經幫我們實現對應的方法,我們直接用實例化的的對象調用它就行了。比如下方的代碼進行加減乘除:

private static void test6() {
    BigInteger num1 = new BigInteger("1111");
    BigInteger num2 = new BigInteger("2222");
    //加法
    BigInteger add = num1.add(num2);
    //減法
    BigInteger subtract = num2.subtract(num1);
    //乘法
    final BigInteger multiply = num1.multiply(num2);
    //除法(取整)
    BigInteger divide = num2.divide(num1);
    //除法(取餘)
    BigInteger mod = num2.mod(num1);
    System.out.println(add);//3333
    System.out.println(subtract);//1111
    System.out.println(multiply);//2468642
    System.out.println(divide);//2
    System.out.println(mod);//0
  }

四、BigDecimal類

與 BigInteger 類對應的是 BigDecimal 類,BigInteger 是處理整數的,而 BigDecimal 是處理小數的,Decimal 英文單詞就是小數的意思,所以 BigDecimal 顧名思義就是大小數,處理大的小數的。如果一個小數超過了 double類型的取值範圍,就需要用到 BigDecimal。

1、構造方法

BigDecimal 類的構造方法有很多,最常用的是以下四個:

public BigDecimal(double val) {
public BigDecimal(int val) {}
public BigDecimal(String val) {}
public BigDecimal(long val) {}

2、類中常用的方法

和 BigInteger 類一樣,BigDecimal 也是不可以直接進行加減乘除的,加減乘除的方式和 BigInteger 處理方式一樣,比如下面的代碼對BigDecimal 進行四則運算:

private static void test7() {
  BigDecimal num1 = new BigDecimal("1.23");
  BigDecimal num2 = new BigDecimal("2.46");
  //加法
  BigDecimal add = num1.add(num2);
  //減法
  BigDecimal subtract = num2.subtract(num1);
  //乘法
  final BigDecimal multiply = num1.multiply(num2);
  //除法(取整)
  BigDecimal divide = num2.divide(num1);

  System.out.println(add);//3.69
  System.out.println(subtract);//1.23
  System.out.println(multiply);//3.0258
  System.out.println(divide);//2
}

由於小數和整數不一樣,小數經常涉及到精度的問題,所以 BigDecimal 裏面也提供了方法來設置小數的精度,設置精度的方法有三個重載的方法:

public BigDecimal setScale(int newScale)
public BigDecimal setScale(int newScale, int roundingMode)
public BigDecimal setScale(int newScale, RoundingMode roundingMode)

這三個方法的第一個參數是設置保留小數點之後的位數,第二個參數是設置的模式(比如向上取整還是向下取整等等),設置四捨五入的模式有8種:

public final static int ROUND_UP =           0;
    
    public final static int ROUND_DOWN =         1;
    
    public final static int ROUND_CEILING =      2;
    
     public final static int ROUND_FLOOR =        3;
 
    public final static int ROUND_HALF_UP =      4;
   
    public final static int ROUND_HALF_DOWN =    5;
  
    public final static int ROUND_HALF_EVEN =    6;
    
    public final static int ROUND_UNNECESSARY =  7;

下面我們就來對這其中4種模式的用法做一個詳細的分析

  • ROUND_UP 模式

UP的意思就是向上的意思,可以理解爲加的意思。比如我保留了三位小數,那麼我不管你後面的小數值如何(除了0),我都給你加一,就相當於四捨五入的五入。比如下面這個代碼,我保留3爲小數,模式設置爲ROUND_UP模式,那麼如果最後一位是0,那麼結果就是9.461,否則就是9.462

BigDecimal bigDecimal = new BigDecimal("9.4610");
BigDecimal result = bigDecimal.setScale(3, BigDecimal.ROUND_UP);
  • ROUND_DOWN 模式

是一個舍位取值的概念,比如我保留了三位小數,那麼我不管你後面的小數值如何,也不會四捨五入,就硬生生的的截斷,相當於什麼呢,就是我從小數點後面開始取三位,三位後面的都不要了。比如下面這個代碼,我保留3爲小數,模式設置爲ROUND_DOWN模式,那麼最後一位不管是什麼(從0到9),最後的結果都是9.461

BigDecimal bigDecimal = new BigDecimal("9.4611");
BigDecimal result = bigDecimal.setScale(3, BigDecimal.ROUND_DOWN);
  • ROUND_CEILING 模式

這個模式就是給定的數如果爲正數,行爲和ROUND_UP一樣,如果爲負數,行爲和ROUND_DOWN一樣 。

  • ROUND_FLOOR 模式

這個模式就是給定的數如果爲正數,行爲和ROUND_DOWN一樣,如果爲負數,行爲和ROUND_UP一樣

五、小結

以上就是我對數學相關類的總結以及個人的理解,如果有任何不清楚的,可以去看官方文檔(API官方文檔地址: https://docs.oracle.com/javas... ),其實,很多人都很排斥看源碼和閱讀官網文檔,原因就是源碼和閱讀官網文檔都是全英文的,解讀起來很費時間;其實這是一種不好的學習方式,源碼和閱讀官網文檔是最官方權威的第一手資料,也是最正確的,如果我們去網上看其他的相關解讀,這也只能是他人的解讀,而其他人的解讀就代表了他對源碼和閱讀官網文檔的個人理解,而這個理解是可能會有出入的,也就是可能會誤導我們,所以我們一定要養成習慣去閱讀源碼和閱讀官網文檔,可能剛開始的確很慢,但是慢慢的就你的閱讀速度和效率就會提高的。

最後,最近很多小夥伴找我要 Linux學習路線圖 ,於是我根據自己的經驗,利用業餘時間熬夜肝了一個月,整理了一份電子書。無論你是面試還是自我提升,相信都會對你有幫助!

免費送給大家,只求大家金指給我點個贊!

電子書 | Linux開發學習路線圖

也希望有小夥伴能加入我,把這份電子書做得更完美!

有收穫?希望老鐵們來個三連擊,給更多的人看到這篇文章

相關文章