入门篇-其之八-常用类的简单使用
本文中使用到的工具是Intellij IDEA和JDK 8,需要安裝兩款工具的請查看這兩篇教程:點我查看安裝JDK8/11/17教程、點我查看安裝Intellij IDEA教程。
一、控制臺輸入類Scanner
假設今天我想在瓜攤買一個西瓜(西瓜的重量是10斤),西瓜兩塊錢一斤,此時使用Java程序代碼如下:
/**
* 計算西瓜的價格
*
* @author iCode504
* @date 2023-10-31
*/
public class MyWatermelonDemo1 {
public static void main(String[] args) {
int price = 2; // 西瓜的單價
int weight = 10; // 西瓜的重量(公斤)
int totalPrice = price * weight; // 購買價格
System.out.println("西瓜的價格是: " + totalPrice + "元");
}
}
運行結果:
然而現實生活中西瓜的單價和重量是變化的,我們需要手動輸入單價和重量,再將輸入的內容進行計算。如果在Java代碼中實現這一功能,就需要使用到控制臺輸入類Scanner。
要想執行輸入操作,需要創建一個Scanner類型的對象,Scanner類位于java.util包中(包的概念后續會講到),需要我們在類的上方手動導入。
import java.util.Scanner;
導入完成后,我們就可以在main方法中創建Scanner類型的對象了,在Scanner的構造器中還需要傳入一個參數System.in表示從控制臺輸入,代碼如下:
Scanner scanner = new Scanner(System.in);
此時我們就完成了scanner對象的創建,此時我們就可以調用Scanner類中的方法了,由于我們定義的是int類型的變量,此時我們就可以使用Scanner類中的nextInt()方法實現輸入功能,例如:
int price = scanner.nextInt();
在控制臺輸入的內容就會賦值給當前變量并且可以參與后續的運算。
以下是解決上述方案的完整代碼:
import java.util.Scanner; // 要想使用Scanner類,就必須要在類的上方導入
/**
* 使用Scanner類實現手動輸入,然后計算結果
*
* @author iCode504
* @date 2023-10-31
*/
public class MyWatermelonDemo2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入西瓜的單價: ");
int price = scanner.nextInt();
System.out.println("請輸入西瓜的重量(按斤計算): ");
int weight = scanner.nextInt();
int totalPrice = price * weight;
System.out.println("西瓜的單價是" + price + "元, 重量是" + weight + "斤, 價格是" + totalPrice + "元");
}
}1
運行結果:
除了boolean和char類型以外,其他七種數據類型都可以調用nextXxx()方法,使用方式和上述過程完全相同:
| 基本數據類型 | 調用方法 |
|---|---|
byte |
nextByte() |
short |
nextShort() |
int |
nextInt() |
long |
nextLong() |
float |
nextFloat() |
double |
nextDouble() |
除了能輸入數字以外,Scanner類還提供了字符串輸入的方法:next()和nextLine()。這兩個方法都能在控制臺輸入字符串,二者的區別是:
-
next()方法讀取字符串,直到遇到空格、制表符Tab和回車Enter為止,如果這三個符號后面還存在其他字符,next()方法都會省略。 -
nextLine()方法讀取字符串,直到遇到回車Enter為止。即使當前行存在空格,也能正常輸出。
以下是兩種方法的使用案例:
import java.util.Scanner;
/**
* next()方法和nextLine()方法的區別
*
* @author iCode504
* @date 2023-10-31
*/
public class MyWatermelonDemo3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請使用nextLine()方法輸入內容,按回車鍵結束: ");
String strValue1 = scanner.nextLine();
System.out.println("使用nextLine()輸出結果是: " + strValue1);
System.out.println("請使用next()方法輸入內容,按回車鍵結束: ");
String strValue2 = scanner.next();
System.out.println("使用next()輸出結果是: " + strValue2);
}
}
運行結果:
二、數學類Math
在初高中我們學習的一些數學函數在Java中同樣使用。這些數學函數都在Math類中。
2.1 絕對值、兩數的最小值和最大值
絕對值的概念:正數的絕對值是其本身,0的絕對值是0,負數的絕對值是其相反數。在Math類中,我們可以調用靜態方法Math.abs(number)來獲取number的絕對值,其中number的類型只能是int、long、float、double中的一種。
兩數的最小值可以調用Math.min(number1, number2),如果number1 > number2,那么得到的結果是number2,反之,得到的結果是number1。
兩數的最大值可以調用Math.max(number1, number2),如果number1 > number2,那么得到的結果是number1,反之,得到的結果是number2。
其中number1和number2需要保證是int、long、float、double中的一種。
以下是示例代碼:
/**
* 絕對值abs()、兩數最小值min()、兩數最大值max()的應用
*
* @author iCode504
* @date 2023-10-31
*/
public class MathDemo1 {
public static void main(String[] args) {
// 取絕對值
int intValue1 = 20;
int result1 = Math.abs(intValue1);
double doubleValue1 = -2.45;
double result2 = Math.abs(doubleValue1);
float floatValue1 = 0.0f;
float result3 = Math.abs(floatValue1);
System.out.println("----------取絕對值----------");
System.out.println("result1 = " + result1);
System.out.println("result2 = " + result2);
System.out.println("result3 = " + result3);
// 兩數取最小值、最大值
int intValue2 = 30;
int intValue3 = 40;
int result4 = Math.min(intValue2, intValue3);
int result5 = Math.max(intValue2, intValue3);
System.out.println("----------取最小值、最大值----------");
System.out.println("result4 = " + result4);
System.out.println("result5 = " + result5);
}
}
運行結果:
那么Math.abs()、Math.min()、Math.max()為什么只支持int、long、float、double四種類型。我們使用Ctrl和鼠標左鍵點擊abs()方法進入源碼:
此時按Alt和7鍵,會列舉出當前類所有的方法,此時我們在列表中直接輸入abs搜索,發現只有四個結果:
此時我們依次點擊進入查看源碼,發現它們支持的數據類型只有int、long、float和double。以int類型的abs(int)方法為例,我們發現方法內部就是一個三元運算符組成的表達式:
public static int abs(int a) {
return (a < 0) ? -a : a;
}
如果a < 0,那么得到的結果就是其相反數-a,反之,0和正數得到的絕對值就是其本身。long、float和double的abs()方法亦同理。
此時我們可以按照上述的方式找到min和max方法,發現二者也是僅支持int、long、float和double,方法列表如下:
以min(int, int)方法為例,此時我們點擊查看源碼,發現這個方法體中也用到了三元表達式:
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
如果a小于等于b,那么最小值就是a,反之為b。
而浮點類型的min(double, double)方法源碼則在此基礎上做了進一步判斷:
public static double min(double a, double b) {
if (a != a)
return a; // a is NaN
if ((a == 0.0d) &&
(b == 0.0d) &&
(Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
// Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a <= b) ? a : b;
}
如果參數a的值是NaN(NaN是一個特殊的浮點類型的數值,表示無效或者無意義的數值結果,例如:0.0 / 0.0得到的結果沒有意義,其結果就是NaN),由于NaN是無意義的結果,因此兩個NaN的值比較結果就是false。源碼中的第一個if判斷就是針對NaN結果的判斷,如果a的確是NaN,那么比較的結果沒有意義,返回的結果也就是變量a本身的值NaN。
第二個比較主要是針對a的值是0.0,b的值是-0.0的情況,0.0在默認情況下無論前面加上正負號都是0.0,第三個條件中Double.doubleToRawLongBits()方法是將當前按浮點數轉換成64位的long類型數,negativeZeroDoubleBits就是上述方法默認的-0.0轉換成long類型的數字,如果此時Double.doubleToRawLongBits(b)得到的結果和negativeZeroDoubleBits的值完全相同,那么得到的結果是b的值-0.0。
如果上述兩個條件都不符合,那么就使用三元運算符進行比較,如果a小于等于b,返回值是a,反之為b。
2.2 數學常量\(\pi\)和\(e\)
數學常量是指在數學領域中經常使用的,具有特定數值的量。在中學階段,我們接觸到的兩個常量是圓周率\(\pi\)(3.1415926...)和自然對數\(e\)(2.7182818...)。這兩個常量在Java的Math類有存儲,我們只需要調用Math.PI即可獲取\(\pi\)值,調用Math.E即可獲取\(e\)值。
/**
* 數學常量:圓周率和自然對數
*
* @author iCode504
* @date 2023-11-02
*/
public class MathDemo2 {
public static void main(String[] args) {
System.out.println("圓周率的值是: " + Math.PI);
System.out.println("自然對數的值是: " + Math.E);
}
}
運行結果:
從運行結果中我們可以發現,Math.PI和Math.E只輸出了小數點后的一部分,這是因為在Math類中關于PI和E使用的是double類型,由于double的精度只有15位,因此輸出結果保留了小數點后15位。
2.3 三角函數
在Math類中定義了很多和三角函數相關方法,所有的三角函數得到的結果都是double類型,這里選擇了3個具有代表性的三角函數:
| 方法 | 說明 |
|---|---|
sin(a) |
正弦函數 |
cos(a) |
余弦函數 |
tan(a) |
正切函數 |
和數學上的使用基本上一樣,我們只需要確定a的值即可。例如:\(sin(\frac{\pi}{6})=0.5,cos(\frac{\pi}{3}=0.5),tan(\frac{\pi}{4})=1\),此時我們可以使用程序來檢驗一下:
/**
* 三角函數的使用
*
* @author iCode504
* @date 2023-11-02
*/
public class MathDemo3 {
public static void main(String[] args) {
// 弧度使用Math.PI來表示
double sinResult = Math.sin(Math.PI / 6);
double cosResult = Math.cos(Math.PI / 3);
double tanResult = Math.tan(Math.PI / 4);
System.out.println("sinResult = " + sinResult);
System.out.println("cosResult = " + cosResult);
System.out.println("tanResult = " + tanResult);
}
}
運行結果:
但是從運行結果中我們可以發現得到的結果和預期的值相差“一點點”,出現上述情況的原因主要有兩點:首先,計算機本身處理浮點類型的數值就不準確。另外,Math.PI的值是小數點的后15位,做不到十分精確。因此得到的結果和期望值存在誤差。
2.4 指數函數和對數函數
Math類中定義了如下常用的指數函數和對數函數:
| 方法名 | 說明 |
|---|---|
sprt(a) |
求a的平方根 |
pow(a, b) |
求a的b次方,即\(a^b\) |
exp(a) |
求自然對數\(e\)的a次方,即\(e^a\) |
log(a) |
求以自然對數\(e\)為底,a的對數,即\(ln(a)\) |
log10(a) |
求以10為底,a的對數,即\(log_{10}a\) |
以下是這些數學函數在代碼中的應用:
/**
* 指數函數、對數函數的使用
*
* @author iCode504
* @date 2023-11-03
*/
public class MathDemo4 {
public static void main(String[] args) {
int number1 = 49;
double result1 = Math.sqrt(number1); // 求number1的平方根
int number2 = 3;
int number3 = 4;
double result2 = Math.pow(number2, number3); // 求number2的number3次方
double result3 = Math.exp(3); // 求e的3次方
double result4 = Math.log(2 * Math.E); // 求以e為底,2e的對數
double result5 = Math.log10(100); // 求以10為底,100的對數
System.out.println("result1 = " + result1);
System.out.println("result2 = " + result2);
System.out.println("result3 = " + result3);
System.out.println("result4 = " + result4);
System.out.println("result5 = " + result5);
}
}
運行結果:
2.5 數字的舍入操作
在進行數學運算時,我們可能需要對小數進行舍入操作(例如:四舍五入),Math類為我們提供了以下四種關于小數舍入的方法:
| 方法名 | 返回類型 | 說明 |
|---|---|---|
ceil(x) |
double |
獲取大于或等于當前數值的最小整數 |
floor(x) |
double |
獲取小于或等于當前數值最大整數 |
rint(x) |
double |
獲取當前數值最接近的整數,如果有兩個相同接近的整數,取偶數 |
round(x) |
double |
四舍五入,舍入數字以第一位小數為基準 |
以下是這些數學函數在代碼中的應用:
/**
* 舍入函數的使用
*
* @author iCode504
* @date 2023-11-03
*/
public class MathDemo5 {
public static void main(String[] args) {
double number1 = 2.46;
double number2 = -2.34;
// 獲取大于或等于當前數值的最小整數
double result1 = Math.ceil(number1);
double result2 = Math.ceil(number2);
System.out.println("result1 = " + result1);
System.out.println("result2 = " + result2);
System.out.println("--------------------");
// 獲取小于或等于當前數值最大整數
double result3 = Math.floor(number1);
double result4 = Math.floor(number2);
System.out.println("result3 = " + result3);
System.out.println("result4 = " + result4);
System.out.println("--------------------");
// 獲取當前數值最接近的整數,如果有兩個相同接近的整數,取偶數
double result5 = Math.rint(number1);
double result6 = Math.rint(number2);
double result7 = Math.rint(5.5);
System.out.println("result5 = " + result5);
System.out.println("result6 = " + result6);
System.out.println("result7 = " + result7);
System.out.println("--------------------");
// 四舍五入,舍入數字以第一位小數為基準
double result8 = Math.floor(number1);
double result9 = Math.floor(number2);
System.out.println("result7 = " + result8);
System.out.println("result8 = " + result9);
}
}
運行結果:
2.6 隨機數
Math類中為我們提供了一個獲取隨機數的方法random(),它默認在\([0,1)\)范圍內生成小數。我們可以利用這個范圍,生成任意范圍的數字。
例如:利用Math.random()所給的范圍,生成\([15, 60]\)之間的隨機數。
首先,整數范圍\([15, 60]\)可以等價寫成\([15, 61)\)。
再獲取范圍差:\(61 - 15 = 46\),
利用不等式的性質,將原有的\([0, 1)\)乘以46得到\([0, 46)\),再將現有的范圍再加上15,即可獲得目標范圍:\([15, 61)\)
總結:從\([0,1)\)轉換到\([15,61)\)先乘以46,再加15即可。
以下上述案例在Java代碼中的實現:
/**
* Math.random()生成隨機數
*
* @author iCode504
* @date 2023-11-03
*/
public class MathDemo6 {
public static void main(String[] args) {
// 每次生成的隨機數值都不相同
double result1 = Math.random();
double result2 = Math.random();
double result3 = Math.random();
System.out.println("result1 = " + result1);
System.out.println("result2 = " + result2);
System.out.println("result3 = " + result3);
System.out.println("--------------------");
// 由于生成的是[15,60]之間的整數,需要將計算結果強制轉換int類型
int randomNumber1 = (int) (Math.random() * 46 + 15);
int randomNumber2 = (int) (Math.random() * 46 + 15);
int randomNumber3 = (int) (Math.random() * 46 + 15);
System.out.println("randomNumber1 = " + randomNumber1);
System.out.println("randomNumber2 = " + randomNumber2);
System.out.println("randomNumber3 = " + randomNumber3);
}
}
每次得到的結果都不相同:
三、隨機數類Random
前面我們學過Math.random()方法來生成隨機數,但是這個方法存在一個局限是它默認生成的范圍是\([0,1)\)之間的浮點數值,如果需要更大范圍的隨機數需要進行一定的計算并且需要進行強制類型轉換,可能會導致代碼可讀性變低。
而接下來要提到的Random類可以避免強制類型轉換的問題,并且包含Math.random()方法所不包含的一些特性。
3.1 隨機數相關的概念
偽隨機數:偽隨機數是計算機利用特定的算法計算出來的\([0,1)\)均勻分布的隨機序列。雖然偽隨機數并不是真正的隨機數,但是它們具有類似隨機數的統計特征:均勻性和獨立性。在計算偽隨機數時,如果使用的初始值(也稱作隨機數種子)不變,那么生成偽隨機數的序列也不會改變。偽隨機數可以使用程序大量生成。
隨機數種子:隨機數種子是在偽隨機數生成器中用于生成偽隨機數的初始數值,隨機數種子一般是數字。在偽隨機數生成器中,給定相同的種子值,將會生成相同的偽隨機數的序列。
3.2 隨機數類Random的使用
和前面講過的Scanner類一樣,Random類也在java.util包中。創建隨機數的方法如下:
1. 在類的上方導入Random類:
import java.util.Random;
2. 創建一個Random對象:有兩種方式:一種是給定隨機數,另外一種就是不給隨機數:
| 構造方法 | 說明 |
|---|---|
Random(long) |
傳入一個long類型的隨機數種子,后續生成一個固定的隨機數序列 |
Random() |
如果構造方法中沒有隨機數,計算機會給定一個隨機數種子。當然,后續生成的隨機數列就不是固定的 |
Random random1 = new Random(20); // 給定一個隨機數種子20,后續會生成一個固定的隨機數數列
Random random2 = new Random(); // 不直接給定隨機數種子,讓計算機自己分配一個種子,生成一個不固定的隨機數數列
3. 根據要生成的隨機數類型,調用隨機數方法,支持整數類型(int和long)、浮點型(float和double)和布爾類型(boolean)。方法列表如下:
| 方法名稱 | 說明 |
|---|---|
nextInt() |
生成int范圍內的隨機數 |
nextInt(int) |
生成1到int最大值范圍內(不包含int最大值)的隨機數 |
nextLong() |
生成long范圍內的隨機數 |
nextFloat() |
生成float范圍內的隨機數 |
nextDouble() |
生成double范圍內的隨機數 |
nextBoolean() |
隨機生成true或false
|
以下是上述方法的使用:
import java.util.Random;
/**
* 隨機數的應用
*
* @author iCode504
* @date 2023-11-04
*/
public class RandomDemo1 {
public static void main(String[] args) {
// 不使用隨機數種子
Random random1 = new Random();
int result1 = random1.nextInt(); // 生成int范圍內的隨機整數
int result2 = random1.nextInt(60); // 生成1到60范圍內的隨機整數
long result3 = random1.nextLong(); // 生成long范圍內的隨機整數
float result4 = random1.nextFloat(); // 生成float范圍內的隨機整數
double result5 = random1.nextDouble(); // 生成double范圍內的隨機整數
boolean result6 = random1.nextBoolean(); // 生成true或false
System.out.println("result1 = " + result1);
System.out.println("result2 = " + result2);
System.out.println("result3 = " + result3);
System.out.println("result4 = " + result4);
System.out.println("result5 = " + result5);
System.out.println("result6 = " + result6);
System.out.println("--------------------");
// 使用隨機數種子生成固定序列
Random random2 = new Random(20);
for (int i = 0; i < 5; i++) {
int randomValue = random2.nextInt();
System.out.println("randomValue" + (i + 1) + " = " + randomValue);
}
}
}
運行結果:
我們也可以使用Random解決上述生成隨機數問題:
import java.util.Random;
/**
* 使用Random類生成[15, 60]范圍內的整數
*
* @author iCode504
* @date 2023-11-04
*/
public class RandomDemo2 {
public static void main(String[] args) {
Random random = new Random(); // 不設置隨機種子
int result = random.nextInt(46) + 15;
System.out.println("result = " + result);
}
}
多運行幾次程序,我們發現生成的隨機數確實在\([15,60]\)范圍內:
以上是使用Random類生成隨機數,相對于Math.random()而言,生成隨機數可以省去強制類型轉換,相對方便了一些。
Random類是一個方便實用的工具類,它提供了各種方法來獲取不同類型和范圍的隨機數,適用于各種模擬、游戲、密碼學等方面應用。通過使用Random類,開發人員可以輕松地生成具有良好隨機性和不可預測性的偽隨機數,從而提高應用程序的靈活性和效率。
總結
以上是生活随笔為你收集整理的入门篇-其之八-常用类的简单使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HttpClient.PatchAsJs
- 下一篇: 听我一句劝,业务代码中,别用多线程。