重新开始学Java——Random、Math、BigDecimal、MathContext、System、Runtime

这篇博客主要描述Random类与Math类,以及一些其他的类。分别讲述一些使用方法,以及这个类是做什么的。

java.util.Random

官方API声明如下:

public class Random extends Object implements Serializable

可以看到这个类是直接继承了java.lang.Object类的, 那么针对于这个类要说的就是以下几点:

An instance of this class is used to generate a stream of pseudorandom numbers.(此类的实例用于生成伪随机数流。)
The class uses a 48-bit seed, which is modified using a linear congruential formula.( 该类使用 48 位种子,使用线性等同公式对其进行修改。 )
If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers.(如果使用相同的种子创建两个 Random 实例,并且对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。)
Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.(实例java.util.Random是线程安全的。但是,java.util.Random 跨线程同时使用相同实例可能会遇到争用并因此导致性能不佳。相反ThreadLocalRandom,请考虑 在多线程设计中使用。)
Instances of java.util.Random are not cryptographically secure. Consider instead using SecureRandom to get a cryptographically secure pseudo-random number generator for use by security-sensitive applications.( 实例java.util.Random不具有加密安全性。相反SecureRandom,请考虑使用加密安全的伪随机数生成器供安全敏感应用程序使用。)

其实总结起来无非就是几点:

1、这个类用于生成对应的一个伪随机数。
2、其中有一个公式可以进行操作。
3、如果有相同的种子的话,那么可以生成同样的随机数。
4、java.util.Random是线程安全的, 但是如果要在多线程中使用的话,那么应该使用ThreadLocalRandom类。
5、java.util.Random是没有加密功能的(也就是说不安全),建议使用SecureRandom类。

Random 类的构造

Random():创建一个新的随机数生成器
Random(long seed):使用单个 long 种子创建一个新的随机数生成器

java.util.Random 类中生成随机数的方法:

protected int next(int bits) 生成下一个伪随机数。 注意有 protected 限制, 注
意使用范围。子类一般应重写此方法。
int nextInt() 返回下一个 int 类型随机数, 所生成的随机数大于或等于 0。
int nextInt(int n) 返回下一个 int 类型随机数, 所生成的随机数大于或等于 0 ,
并且小于 n。
long nextLong() 返回下一个 long 类型随机数, 所生成的随机数大于或等于 0 ,
并且小于 1.0。
float nextFloat() 返回下一个 float 类型随机数, 所生成的随机数在 0.0 和 1.0
之间均匀分布。
double nextDouble()返回下一个 double 类型的随机数,所生成的随机数是在 0.0
和 1.0 之间均匀分布的 double 值。
boolean nextBoolean(),返回下一个 boolean 类型的随机数,它是取自此随机数生
成器序列的均匀分布的 boolean 值。

java.util.Random 类中生成随机数的方法:

void setSeed(long seed),使用单个 long 种子设置此随机数生成器的种子。
void nextBytes(byte[] bytes),生成随机字节并将其置于用户提供的 byte 数组
中。
double nextGaussian(),返回下一个伪随机数,它是取自此随机数生成器序列的、
呈高斯(“正态” ) 分布的 double 值,其平均值是 0.0, 标准差是 1.0。

示例如下:

import java.util.Random;
/**
* 当种子不变时,多次运行得到的随机数是相同的
*/
public class TestRandom1 {
	public static void main(String[] args) {
		long seed = 100;
		Random = new Random();
		System.out.println(random.nextInt());
		System.out.println(random.nextDouble());
		System.out.println(random.nextInt(100));// 0~100之间,包括0,包括
		100
		Random random2 = new Random(seed);
		System.out.println(random2.nextInt());
	}
}

java.lang.Math

官方API声明如下:

public final class Math extends Object

官方API描述如下:

The class Math contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.(该类Math包含执行基本数值运算的方法,如基本指数,对数,平方根和三角函数。)

那么就可以理解成,Math类中声明了大量与数学运算有关的方法,如果想要进行数学运算的话,那么就可以使用这个类。 Math 类是 final 类型的, 因此不能有子类, Math 类的构造是 private类型的, 因此不能实例化。提供了诸多用于数学计算的静态方法。提供两个静态常量: E 自然对数、 PI 圆周率。具体的方法可以自行查看官方API。

示例如下:

public class TestMath {
	public static void main(String[] args) {
		System.out.println("自然对数的底数: "+Math.E);
		System.out.println("圆周率: "+ Math.PI);
		double d = 3.14;
		// Math.round(x) 返回最接近参数x 的一个整数值
		System.out.println(d+ "四舍五入: "+ Math.round(d));
		// floor 舍去小数部分后,返回一个double类型的值
		System.out.println(d+ ": "+ Math.floor(d));
		double d1 = 3.50000000000000001;
		// Math.round(x) 返回最接近参数x 的一个整数值
		System.out.println(d1+ "四舍五入: "+ Math.round(d1));
		System.out.println(d1+ ": "+ Math.floor(d1));
		double d4 = Math.pow(5, 2);// 求幂
		System.out.println(d4);
		double d5 = Math.pow(81, 0.5);// 开几次方
		System.out.println(d5);
	}
}

java.math.BigDecimal

为什么要使用BigDecimal

float 和 double 的缺陷:浮点数精度难以控制, 不能实现精确计算 (尤其是早期 JDK), 严重不能满足涉及财务、 天文等需要精确计算的行业需求。

BigDecimal 表示不可变的、 任意精度的有符号十进制数。 BigDecimal 由任意精度的整数非标度值 和 32 位的整数标度组成: 如果为零或正数, 则标度是小数点后的位数;如果为负数, 则将该数的非标度值乘以 10 的负 scale 次幂。 因此,BigDecimal 表示的数值是 unscaledValue × 10 –scale 。(–scale这里是上标)

选择 float 、 double 还是 BigDecimal ?

如果允许存在适当误差, 则可以使用 float 或 double 类型;如果需要进行精确运 算, 则应该使用 java.math.BigDecimal 类。

构造方法

构造方法如下:

BigDecimal( String val )
BigDecimal( long val )
BigDecimal( int val )
BigDecimal( double val )
BigDecimal( char[] in )

以上是常用的构造,但是在API中可以看到构造方法有很多,这里就不单独去说了。以后用到哪个就上官方API中进行查找。

示例如下:

import java.math.BigDecimal;
/**
* 构造BigDecimal 对象
* BigDecimal( double d ):该构造构造出来的BigDecimal 对象,
* 表示double数值val的二进制浮点值准确的十进制表示形式
*BigDecimal( double d ) :根据给定的字符串闯将BigDecimal对象
* 根据val 来确定非标度值( unscaleValue)和标度值( scale)
* BigDecimal(char[] array, 0,array.length)
* 根据参数传入的char数组array,从它的 offse 开始,取length 个来构
造BigDecimal
* BigDecimal(char[] array)
* 根据参数传入的char数组array构造BigDecimal对象
*/
public class TestDecimalB {
	public static void main(String[] args) {
		final String s = "2.9";
		double d = Double.parseDouble(s);
		System.out.println("double : "+ d);
		BigDecimal bd = new BigDecimal(d);
		System.out.println("根据double值穿件的BigDecimal 对象 : \n" + bd);
		BigDecimal bd2 = new BigDecimal(s);// 29乘以10的-( 1 )
		System.out.println("根据String 创建的BigDecimal对象"+bd2);
		char[] chares = s.toCharArray();
		for (int i = 0; i < chares.length; i++) {
		System.out.println(chares[i]);
		}
		bd2 = new BigDecimal(chares, 0,chares.length);
		System.out.println("根据char数组创建的BigDecimal对象: "+ bd2);
	}
}

import java.math.BigDecimal;
import java.math.BigInteger;
/**
* 自己指定非标度值( unscaredValue)和标度值(scale)来构造BigDecimal 对象
* BigDecimal(BigInteger unscaledVal, int scale)
* 将 BigInteger 非标度值和 int 标度转换为 BigDecimal。
* BigDecimal(BigInteger unscaledVal, int scale, MathContext mc)
* 将 BigInteger 非标度值和 int 标度转换为 BigDecimal(根据上下文设置进行舍入)
* BigInteger(String val) :参数val 必须是表示十进制整数的字符串
* BigInteger(String val, int radix) : 参数val必须是表示整数的字符串(某种进制形式),参数radix表示基数(多少进制)
*/
public class TestDecimalC {
	public static void main(String[] args) {
		BigInteger unscaledVal = new BigInteger("9ebb",16);// 确定非标度值
		int scale = 3;// 确定标度值
		// dec 表示的是 unscaleValue 乘以10 的 -scale 方 得到的数值
		BigDecimal dec = new BigDecimal(unscaledVal, scale);
		System.out.println(dec);
	}
}
BigDecimal 中的一些方法

java.math.BigDecimal 类中静态方法:

static BigDecimal valueOf( double val ): 将 double 转换为 BigDecimal
static BigDecimal valueOf( long val ): 将 long 转换为 BigDecimal
static BigDecimal valueOf( long unscaledVal, int scale ): 将 long 非标度值和int 标度转换为 BigDecimal

java.math.BigDecimal 类中算术计算方法

BigDecimal add( BigDecimal augend ) : 加法(参数是加数)
BigDecimal divide( BigDecimal divisor ) : 除法(参数是除数)
BigDecimal multiply( BigDecimal multiplicand ) : 乘法(参数是乘数)
BigDecimal subtract( BigDecimal subtrahend ) : 减法(参数是减数)
BigDecimal plus() : 返回自身值(符号与本身相同)
BigDecimal negate() : 求相反数
BigDecimal pow(int n) : 计算 this 的 n 次方
BigDecimal abs() : 求取绝对值
BigDecimal max(BigDecimal val) : 求 this 和 vale 中的较大者
BigDecimal min(BigDecimal val) : 求 this 和 vale 中的较小者
BigDecimal movePointLeft(int n) : 把小数点左移 n 位
BigDecimal movePointRight(int n) : 把小数点右移 n 位
int scale() : 返回此 BigDecimal 的标度
int signum() 返回此 BigDecimal 的正负号函数

示例如下:

import java.math.BigDecimal;
public class TestDecimalD {
	public static void main(String[] args) {
		double a =2.2;
		double b =1.1;
		double c = a-b;
		System.out.println(c);
		BigDecimal bd = new BigDecimal("3.9");
		System.out.println("被减数"+bd);
		BigDecimal bd2 = new BigDecimal("1.3");
		System.out.println("减数"+bd2);
		// 减法运算
		BigDecimal bd3 = bd.subtract(bd2);
		System.out.println(bd3);
		BigDecimal bd4 = bd.divide(bd2);
		System.out.println(bd4);
	}
}
import java.math.BigDecimal;
public class TestDecimalE {
	public static void main(String[] args) {
		BigDecimal dec = new BigDecimal("-250");
		System.out.println(dec);// -250
		BigDecimal dec1 = dec.plus();// -250 返回一个与自身符号相同的、绝对值相同的数
		System.out.println(dec1);
		BigDecimal dec2 = dec.negate();//250 返回一个与自身符号相反、绝对值相同的数
		System.out.println(dec2);
		BigDecimal dec3 = dec.pow(2);// 求 n 次方(负数的奇数次是负数,偶数次方是整数)
		System.out.println(dec3);
		BigDecimal dec4 = dec.abs();// 求绝对值
		System.out.println(dec4);
	}
}
/**
*1、建议使用valueOf 来获得BigDecimal类的实例
*2、移动小数点: movePointLeft( int n )、 movePointRight( int n )
*/
import java.math.BigDecimal;
public class TestDecimalF {
	public static void main(String[] args) {
		BigDecimal dec = BigDecimal.valueOf(314,2);
		System.out.println(dec);
		System.out.println("非标度值: " + dec.unscaledValue());
		System.out.println("标度值: "+ dec.scale());
		BigDecimal d1 = dec.movePointLeft(2);// 小数点向左移动2位,缩小100倍
		System.out.println(d1);
		BigDecimal d2 = dec.movePointRight(3);// 小数点向右移动3位,扩大
		1000倍
		System.out.println(d2);
	}
}
/**
* 实现精确计算,并将精度与舍入模式进行控制
*/
public class TestDecimalG {
	public static void main(String[] args) {
		final int precision = 20;// 精度
		RoundingMode = RoundingMode.HALF_UP;
		// 确定了精度和舍入模式
		final MathContext context = new
		MathContext(precision,roundingMode);
		BigDecimal dec1 = BigDecimal.valueOf(39,2);
		System.out.println("被除数: " + dec1);
		BigDecimal dec2 = BigDecimal.valueOf(11,2);
		System.out.println("被除数: " + dec2);
		// 对于除法,如果除不尽,就要抛出ArithmeticException异常
		// BigDecimal result = dec1.divide(dec2);// ArithmeticException 算数异常
		// 当指定上下文对象后,就不再抛出异常了(因为确定了精度和舍入模式)
		BigDecimal result = dec1.divide(dec2,context);
		System.out.println(result);
		// 指定舍入模式( 精度与被除数相同)
		BigDecimal result2 = dec1.divide(dec2,RoundingMode.HALF_UP);
		System.out.println(result2);
	}
}

在这里需要注意了, MathContext这个类经常是服务于BigDecimal类的。所以经常看到联合使用。

数字格式化

经常有特定的需求进行数字格式化的操作。比如说金钱的表现方式等。具体使用示例如下:

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
/**
* 数字格式化
* 需求:
* 1、专业学号的后三位 从1开始 到999 注:要用for循环来做的话,那么100以
下的数字,就会有2位或1位
* 2、将特定格式的字符串解析为 数字
*/
public class TestNumberFormat {
	public static void main(String[] args) throws ParseException {
	for (int i = 0; i < 1000; i++) {
		String s = "";
		if(i<10){
			s = "00" + i;
		}else if( i<100){
			s = "0"+i;
		}else{
			s = "" + i;
		}
		System.out.print(s +"\t");
	}
	System.out.println();int i = 1; // 出来的形式 要“001”;
	String pattern = "0000";
	NumberFormat nf = new DecimalFormat(pattern);
	String s = nf.format(i); // 将数字格式化为特定格式
	System.out.println(s);
	s = "0010";
	Number n = nf.parse(s);// 将特定格式的字符串解析为Number
	System.out.println(n);
	String money = "¥1,000,000";
	NumberFormat parser = new DecimalFormat("¥0,000,000");
	Number m = parser.parse(money);
	System.out.println(m);
	}
}

那么在使用NumberFormat这个类就是轻松解决数字格式化的问题。

System 类

System 类提供了一些静态属性和静态方法用于当前程序和系统的交互;该类是个 final 类型的类, 不是抽象类, 但不能实例化: 因为该类的构造方法被 private 修饰。

System 中定义的静态常量
static InputStream in : "标准"输入流
static PrintStream err : "标准"错误输出流
static PrintStream out : "标准"输出流

但是要注意,这里的输出流,依旧是间接继承了java.io.OutputStream类,在使用上按照正常的流使用就可以了。(前提是会流。) 示例如下:

import java.util.Scanner;
public class TestSystem1 {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);// “标准”输入流
		System.err.println("请输入你的姓名");// System.err“标准”错误输出流
		String name = s.nextLine();
		System.out.println("你的名字是"+name);// System.out “标准”输出流
		s.close();
	}
}

System 中的一些方法

System 中定义的静态方法(现阶段可以使用的方法)
long currentTimeMillis() 返回以毫秒为单位的当前时间
void exit(int status) 终止当前正在运行的 Java 虚拟机
void gc() 运行垃圾回收器
long nanoTime() 返回系统计时器的当前值(以毫微秒为单位)

示例如下:

public class TestSystem2 {
	public static void main(String[] args) {
		long timefirst = System.currentTimeMillis();
		System.out.println(timefirst);
		int[] source = {1,2,3,4,5};System.out.println(source);
		int[] dest = new int[10];
		System.out.println( Arrays.toString( source ) ) ;
		/** 复制数组*/
		System.arraycopy(source, 0, dest, 3, source.length);
		System.out.println( Arrays.toString( dest ) ) ;
		// 将 dest 的3 开始的 3个元素 复制到 dest的 0 开始的三个位置上去
		System.arraycopy(dest, 3, dest, 0, 3);
		System.out.println( Arrays.toString( dest ) ) ;
		/** 获得某个对象在内存中的地址( 其实就是Object的hashCode返回的那个值 )*/
		String hex = Utils.toHex(System.identityHashCode(source) );
		System.out.println(hex);
		String s = new String("hello,world");
		System.out.println(s.hashCode());
		System.out.println(Utils.toHex(System.identityHashCode(s)));
		s = s.intern();// 规范化表示形式
		System.out.println(s.hashCode());
		System.out.println(Utils.toHex(System.identityHashCode(s)));
		/**获得程序执行到某一行时 对应的时间(自历元至此所经历的毫秒数)
		**/
		long time = System.currentTimeMillis();
		System.out.println(time);/** 返回最准确的可用系统计时器的当前值,以毫微秒为单位 */
		long nano = System.nanoTime();
		System.out.println(nano);
		/** 直接让 JVM 退出的方法*/
		// System.exit( int staus ) 
		// 如果status 是 0 表示正常退出,否则都表示不正常退出
		for (int i = 0; i < 100; i++) {
			if(i == 81){
				//break; // 跳出循环,循环之后的代码继续
				System.exit(0);// 直接终止JVM进程,循环之后的代码没有机会执行
			}
		}
		System.out.println("GoodBye");
	}
}

当然,这里提供了很多针对于系统方面的方法,可以自行上API中查阅。这里仅仅列出了比较常用的方法。

Runtime 类

Runtime 类代表当前 Java 程序的运行时环境,每个 Java 程序都有与之对应的 Runtime 实例,通过该类的实例, 应用程序也可以与系统进行交互,同 System 类, 该类构造也被私有, 因此不能被实例化,其中大多数方法是非静态的, 因此需要使用实例来访问。

获取的 Runtime 实例: static Runtime getRuntime()

访问运行时环境:

int availableProcessors() : 返回可用的 CPU 的个数
long freeMemory() : 返回 Java 虚拟机中的空闲内存量
long maxMemory() : 返回 Java 虚拟机试图使用的最大内存量
long totalMemory() : 返回 Java 虚拟机中的内存总量

例子:

public class TestRuntime {
	public static void main(String[] args) {
		// 获得一个Runtime实例
		Runtime r = Runtime.getRuntime();
		System.out.println("逻辑处理器的个数: "+ r.availableProcessors() );
		System.out.println("freeMemory"+ r.freeMemory() );
		System.out.println("totaMemory: " + r.totalMemory() );
		System.out.println("maxMemory : "+ r.maxMemory());
	}
}

运行系统命令: Process exec(String command):在单独的进程中执行指定的字符串命令

public class TestRuntime2 {
	public static void main(String[] args) throws IOException {
		// 获得一个Runtime实例
		Runtime r = Runtime.getRuntime();
		//String command = "notepad"; // 执行会导致打开记事本
		String command = "explorer"; // 开启资源管理器
		r.exec(command);
	}
}

运行一个 CMD 中的命令

public class TestRuntime3 {
	public static void main(String[] args) throws IOException {
		// 获得一个Runtime实例
		Runtime r = Runtime.getRuntime();
		// copy 是 在cmd 环境下执行的命令
		// copy 后面的第一个部分是源头,第二个部分是目的地
		// 在Windows下 路径必须是 \\ 形式 不能是 / 形式,否则可能命令执行失败
		String command = "cmd /C copy C:\\Person.java c:\\hello.java"; // 在cmd 执行dos命令
		r.exec(command);
	}
}

关机、重启、注销命令

public class TestRuntime4 {
	public static void main(String[] args) throws IOException {
		// 获得一个Runtime实例Runtime r = Runtime.getRuntime();
		String command = "cmd /C start call shutdown -R -f -t 0";
		r.exec(command);
	}
}

仅仅使用于Windows系统

关机命令 cmd /c start call shutdown -S -f -t 0
重启命令 cmd /c start call shutdown -R -f -t 0 
注销命令 cmd /c start call shutdown -L -f -t 0

转载于:https://my.oschina.net/lujiapeng/blog/3083996

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值