本文最后更新于:2025年4月6日
                  
                
              
            
            
              
                
                
本文中使用到的工具是Intellij IDEA和JDK 8,需要安装两款工具的请查看这两篇教程:点我查看安装JDK 8教程 、点我查看安装Intellij IDEA教程 。
 
一、控制台输入类Scanner 假设今天我想在瓜摊买一个西瓜(西瓜的重量是10斤),西瓜两块钱一斤,此时使用Java程序代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public  class  MyWatermelonDemo1  {public  static  void  main (String[] args)  {int  price  =  2 ;      int  weight  =  10 ;    int  totalPrice  =  price * weight;    "西瓜的价格是: "  + totalPrice + "元" );
运行结果:
然而现实生活中西瓜的单价和重量是变化的,我们需要手动输入单价和重量,再将输入的内容进行计算。如果在Java代码中实现这一功能,就需要使用到控制台输入类Scanner。
要想执行输入操作,需要创建一个Scanner类型的对象,Scanner类位于java.util包中(包的概念后续会讲到),需要我们在类的上方手动导入。
1 import  java.util.Scanner;
导入完成后,我们就可以在main方法中创建Scanner类型的对象了,在Scanner的构造器中还需要传入一个参数System.in表示从控制台输入,代码如下:
1 Scanner  scanner  =  new  Scanner (System.in);
此时我们就完成了scanner对象的创建,此时我们就可以调用Scanner类中的方法了,由于我们定义的是int类型的变量,此时我们就可以使用Scanner类中的nextInt()方法实现输入功能,例如:
1 int  price  =  scanner.nextInt();
在控制台输入的内容就会赋值给当前变量并且可以参与后续的运算。
以下是解决上述方案的完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import  java.util.Scanner;       public  class  MyWatermelonDemo2  {public  static  void  main (String[] args)  {Scanner  scanner  =  new  Scanner (System.in);"请输入西瓜的单价: " );int  price  =  scanner.nextInt();"请输入西瓜的重量(按斤计算): " );int  weight  =  scanner.nextInt();int  totalPrice  =  price * weight;"西瓜的单价是"  + price + "元, 重量是"  + weight + "斤, 价格是"  + totalPrice + "元" );1 
运行结果:
除了boolean和char类型以外,其他七种数据类型都可以调用nextXxx()方法,使用方式和上述过程完全相同:
基本数据类型 
调用方法 
 
 
bytenextByte() 
shortnextShort() 
intnextInt() 
longnextLong() 
floatnextFloat() 
doublenextDouble() 
除了能输入数字以外,Scanner类还提供了字符串输入的方法:next()和nextLine()。这两个方法都能在控制台输入字符串,二者的区别是:
next()方法读取字符串,直到遇到空格、制表符Tab 和回车Enter 为止,如果这三个符号后面还存在其他字符,next()方法都会省略。nextLine()方法读取字符串,直到遇到回车Enter 为止。即使当前行存在空格,也能正常输出。 
以下是两种方法的使用案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import  java.util.Scanner;public  class  MyWatermelonDemo3  {public  static  void  main (String[] args)  {Scanner  scanner  =  new  Scanner (System.in);"请使用nextLine()方法输入内容,按回车键结束: " );String  strValue1  =  scanner.nextLine();"使用nextLine()输出结果是: "  + strValue1);"请使用next()方法输入内容,按回车键结束: " );String  strValue2  =  scanner.next();"使用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中的一种。
以下是示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 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);"----------取绝对值----------" );"result1 = "  + result1);"result2 = "  + result2);"result3 = "  + result3);int  intValue2  =  30 ;int  intValue3  =  40 ;int  result4  =  Math.min(intValue2, intValue3);int  result5  =  Math.max(intValue2, intValue3);"----------取最小值、最大值----------" );"result4 = "  + result4);"result5 = "  + result5);
运行结果:
那么Math.abs()、Math.min()、Math.max()为什么只支持int、long、float、double四种类型。我们使用Ctrl 和鼠标左键点击abs()方法进入源码:
此时按Alt 和7 键,会列举出当前类所有的方法,此时我们在列表中直接输入abs搜索,发现只有四个结果:
此时我们依次点击进入查看源码,发现它们支持的数据类型只有int、long、float和double。以int类型的abs(int)方法为例,我们发现方法内部就是一个三元运算符组成的表达式:
1 2 3 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)方法为例,此时我们点击查看源码,发现这个方法体中也用到了三元表达式:
1 2 3 public  static  int  min (int  a, int  b)  {return  (a <= b) ? a : b;
如果a小于等于b,那么最小值就是a,反之为b。
而浮点类型的min(double, double)方法源码则在此基础上做了进一步判断:
1 2 3 4 5 6 7 8 9 10 11 public  static  double  min (double  a, double  b)  {if  (a != a)return  a;   if  ((a == 0.0d ) &&0.0d ) &&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$值。
1 2 3 4 5 6 7 8 9 10 11 12 public  class  MathDemo2  {public  static  void  main (String[] args)  {"圆周率的值是: "  + Math.PI);"自然对数的值是: "  + 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$,此时我们可以使用程序来检验一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public  class  MathDemo3  {public  static  void  main (String[] args)  {double  sinResult  =  Math.sin(Math.PI / 6 );double  cosResult  =  Math.cos(Math.PI / 3 );double  tanResult  =  Math.tan(Math.PI / 4 );"sinResult = "  + sinResult);"cosResult = "  + cosResult);"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$ 
 
以下是这些数学函数在代码中的应用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public  class  MathDemo4  {public  static  void  main (String[] args)  {int  number1  =  49 ;double  result1  =  Math.sqrt(number1);    int  number2  =  3 ;int  number3  =  4 ;double  result2  =  Math.pow(number2, number3);    double  result3  =  Math.exp(3 );       double  result4  =  Math.log(2  * Math.E);      double  result5  =  Math.log10(100 );       "result1 = "  + result1);"result2 = "  + result2);"result3 = "  + result3);"result4 = "  + result4);"result5 = "  + result5);
运行结果:
2.5 数字的舍入操作 在进行数学运算时,我们可能需要对小数进行舍入操作(例如:四舍五入),Math类为我们提供了以下四种关于小数舍入的方法:
方法名 
返回类型 
说明 
 
 
ceil(x)double获取大于或等于当前数值的最小整数 
 
floor(x)double获取小于或等于当前数值最大整数 
 
rint(x)double获取当前数值最接近的整数,如果有两个相同接近的整数,取偶数 
 
round(x)double四舍五入,舍入数字以第一位小数为基准 
 
以下是这些数学函数在代码中的应用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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);"result1 = "  + result1);"result2 = "  + result2);"--------------------" );double  result3  =  Math.floor(number1);double  result4  =  Math.floor(number2);"result3 = "  + result3);"result4 = "  + result4);"--------------------" );double  result5  =  Math.rint(number1);double  result6  =  Math.rint(number2);double  result7  =  Math.rint(5.5 );"result5 = "  + result5);"result6 = "  + result6);"result7 = "  + result7);"--------------------" );double  result8  =  Math.floor(number1);double  result9  =  Math.floor(number2);"result7 = "  + result8);"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代码中的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public  class  MathDemo6  {public  static  void  main (String[] args)  {double  result1  =  Math.random();double  result2  =  Math.random();double  result3  =  Math.random();"result1 = "  + result1);"result2 = "  + result2);"result3 = "  + result3);"--------------------" );int  randomNumber1  =  (int ) (Math.random() * 46  + 15 );int  randomNumber2  =  (int ) (Math.random() * 46  + 15 );int  randomNumber3  =  (int ) (Math.random() * 46  + 15 );"randomNumber1 = "  + randomNumber1);"randomNumber2 = "  + randomNumber2);"randomNumber3 = "  + randomNumber3);
每次得到的结果都不相同:
三、随机数类Random 前面我们学过Math.random()方法来生成随机数,但是这个方法存在一个局限是它默认生成的范围是$[0,1)$之间的浮点数值,如果需要更大范围的随机数需要进行一定的计算并且需要进行强制类型转换,可能会导致代码可读性变低。
而接下来要提到的Random类可以避免强制类型转换的问题,并且包含Math.random()方法所不包含的一些特性。
3.1 随机数相关的概念 伪随机数:伪随机数是计算机利用特定的算法计算出来的$[0,1)$均匀分布的随机序列。虽然伪随机数并不是真正的随机数,但是它们具有类似随机数的统计特征:均匀性和独立性。在计算伪随机数时,如果使用的初始值(也称作随机数种子)不变,那么生成伪随机数的序列也不会改变。伪随机数可以使用程序大量生成。
随机数种子:随机数种子是在伪随机数生成器中用于生成伪随机数的初始数值 ,随机数种子一般是数字。在伪随机数生成器中,给定相同的种子值,将会生成相同的伪随机数的序列。
3.2 随机数类Random的使用 和前面讲过的Scanner类一样,Random类也在java.util包中。创建随机数的方法如下:
1. 在类的上方导入Random类:
1 import  java.util.Random;
2. 创建一个Random对象:有两种方式:一种是给定随机数,另外一种就是不给随机数:
构造方法 
说明 
 
 
Random(long)传入一个long类型的随机数种子,后续生成一个固定的随机数序列 
 
Random()如果构造方法中没有随机数,计算机会给定一个随机数种子。当然,后续生成的随机数列就不是固定的 
 
1 2 Random  random1  =  new  Random (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 
 
以下是上述方法的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import  java.util.Random;public  class  RandomDemo1  {public  static  void  main (String[] args)  {Random  random1  =  new  Random ();int  result1  =  random1.nextInt();            int  result2  =  random1.nextInt(60 );      long  result3  =  random1.nextLong();          float  result4  =  random1.nextFloat();        double  result5  =  random1.nextDouble();      boolean  result6  =  random1.nextBoolean();    "result1 = "  + result1);"result2 = "  + result2);"result3 = "  + result3);"result4 = "  + result4);"result5 = "  + result5);"result6 = "  + result6);"--------------------" );Random  random2  =  new  Random (20 );for  (int  i  =  0 ; i < 5 ; i++) {int  randomValue  =  random2.nextInt();"randomValue"  + (i + 1 ) + " = "  + randomValue);
运行结果:
我们也可以使用Random解决上述生成随机数问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import  java.util.Random;public  class  RandomDemo2  {public  static  void  main (String[] args)  {Random  random  =  new  Random ();   int  result  =  random.nextInt(46 ) + 15 ;"result = "  + result);
多运行几次程序,我们发现生成的随机数确实在$[15,60]$范围内:
以上是使用Random类生成随机数,相对于Math.random()而言,生成随机数可以省去强制类型转换,相对方便了一些。
Random类是一个方便实用的工具类,它提供了各种方法来获取不同类型和范围的随机数,适用于各种模拟、游戏、密码学等方面应用。通过使用Random类,开发人员可以轻松地生成具有良好随机性和不可预测性的伪随机数,从而提高应用程序的灵活性和效率。