Java System类
System作为系统类,位于JDK的 java.lang包中。System类的构造器由private修饰,不允许被实例化,类中的方法也都是static修饰的静态方法。
Java不支持全局函数和变量,Java设计者将一些系统相关的重要方法和变量收集到了一个同一的类中,这就是System类。System类主要提供的功能有:标准输入流、标准输出流、标准错误输出流;环境变量;加载文件和库;快速复制数组的一部分等。
System类内部包含in、out和err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
currentTimeMillis - 返回毫秒数
// 13位long类型的毫秒值
// currentTimeMillis是一个本地方法,返回的是操作系统的时间
// 由于有的操作系统时间的最小精确度是10毫秒,所以这个方法可能会导致一些偏差
System.out.println(System.currentTimeMillis());
arraycopy - 数组拷贝
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
:参数含义:被复制的数组,被复制的起始位置,复制到的数组,复制到这个数组的起始位置,复制到这个数组的结束位置。注意二者的长度要匹配。
int[] array1 = { 0, 1, 2, 3, 4 };
int[] array2 = { 9, 9, 9, 9, 9 };
System.arraycopy(array1, 1, array2, 0, 4);
// 这时改变值也不会影响已经复制好的数组
array1[3] = 0;
for (int i = 0; i < 5; i++) {
// 1 2 3 4 9
System.out.print(array2[i] + " ");
}
getProperty - 获取系统属性
public static String getProperty(String key)
System.out.println(System.getProperty("file.encoding"));
key | 含义 |
---|---|
file.encoding | 获取编码格式 |
file.separator | 文件分隔符(在 UNIX 系统中是 / ) |
path.separator | 路径分隔符(在 UNIX 系统中是 : ) |
line.separator | 行分隔符(在 UNIX 系统中是 /n ) |
user.language | 获取语言 |
user.home | 用户的主目录 |
user.dir | 用户的当前工作目录 |
java.version | Java 运行时环境版本 |
java.vendor | Java运行时环境供应商 |
java.vendor.url | Java 供应商的 URL |
java.home | Java 安装目录 |
java.vm.specification.version | Java 虚拟机规范版本 |
java.vm.specification.vendor | Java 虚拟机规范供应商 |
java.vm.specification.name | Java 虚拟机规范名称 |
java.vm.version | Java 虚拟机实现版本 |
java.vm.vendor | Java 虚拟机实现供应商 |
java.vm.name | Java 虚拟机实现名称 |
java.specification.version | Java 运行时环境规范版本 |
java.specification.vendor | Java 运行时环境规范供应商 |
java.specification.name | Java 运行时环境规范名称 |
java.class.version | Java 类格式版本号 |
java.class.path | Java 类路径 |
java.library.path | 加载库时搜索的路径列表 |
java.io.tmpdir | 默认的临时文件路径 |
java.compiler | 要使用的 JIT 编译器的名称 |
java.ext.dirs | 一个或多个扩展目录的路径 |
os.name | 操作系统的名称 |
os.arch | 操作系统的架构 |
os.version | 操作系统的版本 |
user.name | 用户的账户名称 |
gc——运行垃圾回收器
public static void gc()
:启动一次垃圾回收
如果调用gc方法,会在对象被回收之前调用finalize()方法
System.gc();
exit——退出虚拟机
public static void exit(int status)
:参数为状态码,非 0 的状态码表示异常终止。
该方法永远不会正常返回,这是唯一一个能够退出程序并不执行finally的情况。退出虚拟机会直接杀死整个程序,已经不是从代码的层面来终止程序了,所以finally不会执行。
try {
System.out.println("try");
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 该语句不会输出
System.out.println("finally");
}
Java Character类
Character类用于对单个字符进行操作
。
方法 | 含义 |
---|---|
static boolean isLetter(char ch) | 判断字符是否为字母 |
static boolean isDigit(char ch) | 判断字符是否为数字 |
static boolean isWhitespace(char ch) | 判断字符是否为空白字符 |
static boolean isUpperCase(char ch) | 判断字符是否为大写字母 |
static boolean isLowerCase(char ch) | 判断字符是否为小写字母 |
static char toUpperCase(char ch) | 将小写字符转换为大写 |
static char toLowerCase(char ch) | 将大写字符转换为小写 |
static int getNumericValue(char ch) | 获取指定字符的unicode的值 |
static int getNumericValue(int codePoint) | 获取指定字符的unicode的值 |
static String toString(char ch) | char字符转换成String |
java.util
Timer定时器
import java.util.Timer;
// 会调用this("Timer-" + serialNumber(), isDaemon);
// 即它以Timer+序列号为该定时器的名字
// 默认无参构造器将会使该线程作为非守护线程
Timer timer = new Timer();
// 以name作为该定时器的名字
Timer timer = new Timer(String name);
// 是否将此定时器作为守护线程执行
Timer timer = new Timer(boolean isDeamon);
// 定时器名字, 是否为守护线程
Timer timer = Timer(String name, boolean isDaemon);
// 所有的task都是TimerTask的子类
// 所有time都是Date类型的日期
// 所有delay和period都是long类型的延迟时间, 单位为毫秒
timer.schedule(TimerTask task, Date time); // 在time时间执行task任务1次
timer.schedule(TimerTask task, long delay); // 在延迟delay毫秒后执行task任务1次
// 在firsttime时间执行task1次,之后定期period毫秒时间执行task
// 时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
timer.schedule(TimerTask task, Date firstTime, long period);
// 在延迟delay后执行task1次,之后定期period毫秒时间执行task
// 时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
timer.schedule(task, delay, period);
// 在firstTime时间执行task一次, 以后每隔period毫秒执行1次
// 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
timer.scheduleAtFixedRate(TimerTask task, Date firstTime, long period);
// 在delay毫秒后执行task一次, 以后每隔period毫秒执行1次
// 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
timer.scheduleAtFixedRate(TimerTask task, long delay, long period);
// 结束定时器
timer.cancel();
// 及时清除无效任务,避免内存泄漏
timer.purge();
schedule会表现出只从当前时间开始。scheduleAtFixedRate会把之前没有来得及执行的任务全都执行, 感觉像之前一直有在执行一样。
timer.schedule(task, time); timer.schedule(task, delay); 如果time时间为过去时间,则该任务会马上执行,如果为将来时间, 则会等待时间到来再执行。如果传入的是delay,则delay不可以为负数, 负数报错,正数代表未来的delay毫秒以后执行。
-
终止Timer线程
1.调用timer的cancle方法。
2.把timer线程设置成daemon线程,(new Timer(true)创建daemon线程),在jvm里,如果所有用户线程结束,那么守护线程也会被终止,不过这种方法一般不用。
3.当所有任务执行结束后,删除对应timer对象的引用,线程也会被终止。
4.调用System.exit方法终止程序。
问题
-
任务精确性
通过异步执行任务的方式提高执行时间的准确性
static ExecutorService threadPool = Executors.newCachedThreadPool();
public void run() {
// 建立线程池,提高线程的复用,避免线程创建与上下文切换所带来的开销
threadPool.execute(new Runnable() {
public void run() {
// 具体的操作
}
});
}
- 内存泄漏
当用户取消了一个任务以后,失效的任务依然会占据着queue队列,造成内存泄漏。
虽然TimeTask.cancel()提供了一个及时取消的接口,但却没有一个自动机制保证失效的任务及时回收(需要用户手动处理)。
解决:为了防止内存泄漏,Timer提供了一个接口purge()及时清除无效任务。
TimerTask
import java.util.TimerTask;
public class TestTask extends TimerTask {
@Override
public void run(){
// 具体逻辑...
}
}
代码示例
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TestTask extends TimerTask {
private static final long ONE_DAY = 24 * 60 * 60 * 1000;
@Override
public void run() {
long start = System.currentTimeMillis();
long end = start + 20 * 1000;
boolean temp = true;
while (System.currentTimeMillis() < (end + 1000) && temp) {
while (System.currentTimeMillis() > end) {
// 定时任务具体逻辑
// ...
System.out.println("定时任务开始");
temp = false;
break;
}
}
temp = true;
}
public void openTask() {
Calendar calendar = Calendar.getInstance();
// 设置定时任务开始的时间
calendar.set(Calendar.HOUR_OF_DAY, 2); // 0-24
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date date = calendar.getTime();
if (date.before(new Date())) {
date = this.addDay(date, 1);
System.out.println("重启后时间位于规定之后,到下个时间点开始");
}
Timer timer = new Timer();
TestTask task = new TestTask();
timer.schedule(task, date, ONE_DAY);
}
public Date addDay(Date date, int num) {
Calendar startDT = Calendar.getInstance();
startDT.setTime(date);
startDT.add(Calendar.DAY_OF_MONTH, num);
return startDT.getTime();
}
}
在监听器中开启即可:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class TestListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) { }
@Override
public void contextInitialized(ServletContextEvent arg0) {
// 服务器启动时开启任务
new TestTask().openTask();
}
}
Enumeration
java.util.Enumeration
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
// HttpServletRequest request
HttpSession session = request.getSession();
// 遍历session
System.out.println("遍历session的attribute");
Enumeration<String> eSession = session.getAttributeNames();
while (eSession.hasMoreElements()) {
String key = (String) eSession.nextElement();
String value = session.getAttribute(key).toString();
System.out.println(key + " = " + value);
}
System.out.println("--------------------------");
System.out.println("遍历request的attribute");
Enumeration<String> eRequest = request.getAttributeNames();
while (eRequest.hasMoreElements()) {
String key = (String) eRequest.nextElement();
String value = request.getAttribute(key).toString();
System.out.println(key + " = " + value);
}
System.out.println("--------------------------");
System.out.println("遍历request的param");
Enumeration<String> enumers = request.getParameterNames();
while (enumers.hasMoreElements()) {
String key = (String) enumers.nextElement();
String value = request.getParameter(key).toString();
System.out.println(key + " = " + value);
}
System.out.println("--------------------------");
Scanner
java.util.Scanner:通过 Scanner 类来获取用户的输入。
next() | nextLine() |
---|---|
一定要读取到有效字符后才可以结束输入。 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。 next() 不能得到带有空格的字符串 。 | 以Enter为结束符,nextLine()方法返回的是输入回车之前的所有字符。 可以获得空白。 |
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 这四种采用一种即可
if (sc.hasNext()) {
String ste = sc.next();
System.out.println(ste);
}
if(sc.hasNextLine()){
String ste = sc.nextLine();
System.out.println(ste);
}
// int
if (sc.hasNextInt()) {
int str = sc.nextInt();
System.out.println("Int:" + str);
}
// double
if (sc.hasNextDouble()) {
Double temp = sc.nextDouble();
System.out.println("Double:" + temp);
}
sc.close();
}
}
UUID
java.util.UUID
// 随机产生一个UUID对象(通用唯一识别码)
UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());
java.net
URLEncoder,URLDecoder
java.net.URLEncoder.encode(str, 编码方式);
java.net.URLDecoder.decode(str, 编码方式);
编码方式为字符串,忽略大小写。需要加解码的字符串不能为null。
编码方式 | 说明 |
---|---|
utf-8/UTF-8 | 字母,数字保持不变 汉字编码为3位:%xx%xx%xx 中文标点编码为3位:%xx%xx%xx 英文标点编码为1位:%xx |
gbk/GBK | 字母,数字保持不变 汉字编码为2位:%xx%xx 中文标点编码为2位:%xx%xx 英文标点编码为1位:%xx |
iso-8859-1/ISO-8859-1 iso8859-1/ISO8859-1 | 字母,数字保持不变 汉字编码为1位:%xx 中,英文标点编码为1位:%xx |
日期相关处理
Calendar类
java.util.Calendar
构造方法:
protected Calendar():由于修饰符是protected,所以无法直接创建该对象,需要通过别的途径生成对象。
成员方法:
方法 | 说明 |
---|---|
static Calendar getInstance() | 使用默认时区和区域设置获取日历,通过该方法生成Calendar对象。Calendar cr = Calendar.getInstance(); |
final void set(int year,int month,int date,int hourofday,int minute,int second) | 设置日历的年、月、日、时、分、秒。 该方法具有多个重载的方法。 |
int get(int field) | 返回给定日历字段的值,所谓字段就是年、月、日等等。 |
void setTime(Date date) | 使用给定的Date设置此日历的时间。 Date->Calendar |
Date getTime() | 返回一个Date表示此日历的时间。 Calendar->Date |
abstract void add(int field, int amount) | 按照日历的规则,给指定字段添加或减少时间量 。 |
long getTimeInMillies() | 以毫秒为单位返回该日历的时间值 |
boolean after(Object when) | Calendar表示的时间位于参数时间之后返回true,否则为false。 |
boolean before(Object when) | Calendar表示的时间位于参数时间之前返回true |
Calendar类的field:
field | 说明(Calendar.XXXX) |
---|---|
YEAR | 年 |
MONTH | 月,从0开始的,需要加1 |
DATE/DAY_OF_MONTH | 日 |
DAY_OF_YEAR | 一年的第多少天 |
HOUR | 时,12制 |
HOUR_OF_DAY | 时,24制 |
MINUTE | 分 |
SECOND | 秒 |
MILLISECOND | 毫秒 |
DAY_OF_WEEK_IN_MONTH | 某月中第几周 |
WEEK_OF_MONTH | 日历式的第几周 |
DAY_OF_WEEK | 周几 |
WEEK_OF_YEAR | 一年的第多少周 |
AM_PM | 返回1则表示是下午,返回0表示上午 |
SimpleDateFormat类
import java.text.SimpleDateFormat;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date()));
常用方法
比较两个日期的先后
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String startDate = "2000-01-01";
String endDate = "2001-01-01";
Date bt = sdf.parse(startDate);
Date et = sdf.parse(endDate);
if (bt.before(et)) {
System.out.println(startDate + "早于" + endDate);
} else {
System.out.println(startDate + "晚于" + endDate);
}
获取指定时间的年,月,日,时,分,秒,毫秒
Calendar cal = Calendar.getInstance();
// 年
int year = cal.get(Calendar.YEAR);
// 月,需要加一
int month = cal.get(Calendar.MONTH);
// 日
int day = cal.get(Calendar.DATE);
// 时
int hour = cal.get(Calendar.HOUR_OF_DAY);
// 分
int minute = cal.get(Calendar.MINUTE);
// 秒
int second = cal.get(Calendar.SECOND);
// System.currentTimeMillis()/1000%60
// 毫秒,0-999
int millisecond = cal.get(Calendar.MILLISECOND);
// 获得系统的时间,单位为毫秒,是一个13位的long
System.currentTimeMillis()
判断指定时间是星期几?
/**
* 输入日期获取星期几
*
* @param date
* 时间
* @return 星期几
*/
public static String getWeekOfDate(Date date) {
String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0) {
w = 0;
}
return weekDays[w];
}
/**
* 输入日期字符串获取星期几
*
* @param date
* 日期字符串:yyyy-MM-dd
* @return 星期几
*/
public static String getWeekOfDateStr(String datestr) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = sdf.parse(datestr);
} catch (Exception e) {
e.printStackTrace();
}
String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0) {
w = 0;
}
return weekDays[w];
}
今天之后几天,之前几天(年,月…)?
/**
* 示例:获取指定时间的加减时间段的时间
*/
public static void getDateStr() {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 当前时间3天后的时间
cal.add(Calendar.DAY_OF_MONTH, 3);
System.out.println(sdf.format(cal.getTime()));
// 当前时间3天前的时间
cal.setTime(new Date());
cal.add(Calendar.DAY_OF_MONTH, -3);
System.out.println(sdf.format(cal.getTime()));
// 当前时间3月后的时间
cal.setTime(new Date());
cal.add(Calendar.MONTH, 3);
System.out.println(sdf.format(cal.getTime()));
// 当前时间3小时后的时间
cal.setTime(new Date());
cal.add(Calendar.HOUR_OF_DAY, 3);
System.out.println(sdf.format(cal.getTime()));
}
指定时间是否位于指定区间?
/**
* 判断指定时间是否位于指定区间内(字符串)
*
* @param judgeDate
* 要判断的时间
* @param beginDate
* 开始时间
* @param endDate
* 结束时间
* @param format
* 日期格式化样式
* @return
*/
public static boolean isIn(String judgeDate, String beginDate, String endDate, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
try {
return isExist(sdf.parse(judgeDate), sdf.parse(beginDate), sdf.parse(endDate));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 判断指定时间是否位于指定区间内
*
* @param judgeDate
* 要判断的时间
* @param startDate
* 开始时间
* @param endDate
* 结束时间
* @return
*/
public static boolean isExist(Date judgeDate, Date startDate, Date endDate) {
if (judgeDate.getTime() == startDate.getTime() || judgeDate.getTime() == endDate.getTime()) {
return true;
}
Calendar date = Calendar.getInstance();
date.setTime(judgeDate);
Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
end.setTime(endDate);
if (date.after(start) && date.before(end)) {
return true;
} else {
return false;
}
}
根据年和月获取该月的天数
/**
* 根据年和月获取该月的天数
*
* @param year
* 年
* @param month
* 月
* @return 天数
*/
public static int getDaysByYearAndMonth(int year, int month) {
int days = 0;
boolean isLeapYear = false;
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
isLeapYear = true;
} else {
isLeapYear = false;
}
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 2:
if (isLeapYear) {
days = 29;
} else {
days = 28;
}
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
default:
break;
}
return days;
}
数值相关处理
Java Random类
Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。
位于java.util.Random。
boolean nextBoolean() //返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的boolean值。
void nextBytes(byte[] bytes) //生成随机字节并将其置于用户提供的 byte 数组中。
double nextDouble() //返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布的 double值。
float nextFloat() //返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布float值。
double nextGaussian() //返回下一个伪随机数,它是取自此随机数生成器序列的、呈高斯(“正态”)分布的double值,其平均值是0.0标准差是1.0。
int nextInt() //返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。
int nextInt(int n) //返回一个伪随机数,它是取自此随机数生成器序列的、在(包括和指定值(不包括)之间均匀分布的int值。
long nextLong() //返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 long 值。
void setSeed(long seed) //使用单个 long 种子设置此随机数生成器的种子。
Random r = new Random();
生成[0,1.0)区间的小数
double d1 = r.nextDouble();
直接使用nextDouble方法获得。
生成[0,5.0)区间的小数
double d2 = r.nextDouble() * 5;
因为nextDouble方法生成的数字区间是[0,1.0),将该区间扩大5倍即是要求的区间。
同理,生成[0,d)区间的随机小数,d为任意正的小数,则只需要将nextDouble方法的返回值乘以d即可。
生成[1,2.5)区间的小数
double d3 = r.nextDouble() * 1.5 + 1;
生成[1,2.5)区间的随机小数,则只需要首先生成[0,1.5)区间的随机数字,然后将生成的随机数区间加1即可。
同理,生成任意非从0开始的小数区间[d1,d2)范围的随机数字(其中d1不等于0),则只需要首先生成[0,d2-d1)区间的随机数字,然后将生成的随机数字区间加上d1即可。
生成任意整数
int n1 = r.nextInt();
直接使用nextInt方法即可。
生成[0,10)区间的整数
Random.nextInt(4)将产生0,1,2,3这4个数字中的任何一个数字,注意这里不是0-4,而是0-3。
int n2 = r.nextInt(10);
n2 = Math.abs(r.nextInt() % 10);
以上两行代码均可生成[0,10)区间的整数。
第一种实现使用Random类中的nextInt(int n)方法直接实现。
第二种实现中,首先调用nextInt()方法生成一个任意的int数字,该数字和10取余以后生成的数字区间为(-10,10),然后再对该区间求绝对值,则得到的区间就是[0,10)了。
同理,生成任意[0,n)区间的随机整数,都可以使用如下代码:
int n2 = r.nextInt(n);
n2 = Math.abs(r.nextInt() % n);
生成[0,10]区间的整数
int n3 = r.nextInt(11);
n3 = Math.abs(r.nextInt() % 11);
相对于整数区间,[0,10]区间和[0,11)区间等价,所以即生成[0,11)区间的整数。
生成[-3,15)区间的整数
int n4 = r.nextInt(18) - 3;
n4 = Math.abs(r.nextInt() % 18) - 3;
生成非从0开始区间的随机整数,可以参看上面非从0开始的小数区间实现原理的说明。
Java Math类
- 三角函数方法
public static double sin(double radians) // 正弦函数
public static double cos(double radians) // 余弦函数
public static double tan(double radians) // 正切函数
public static double toRadians(double degree) // 度转换成弧度
public static double toDegree(double radians) // 弧度转换成度
public static double asin(double a) // 反正弦
public static double acos(double a) // 反余弦
public static double atan(double a) // 反正切
- 指数函数方法
public static double exp(double x) // e^x
public static double log(double x) // ln(x)
public static double log10(double x) // log 10(x)
public static double pow(double a,double b) // a^b
public static double sqrt(double x) // √x
- 取整方法
public static double ceil(double x) // 向上取整
public static double floor(double x) // 向下取整
public static double rint(double x) // 返回值为最接近参数的double值。如果这两个整数的double值都同样接近,就取偶数
public static int round(float x) // 返回(int)Math.floor(x+0.5)
public static long round(double x) // 返回(long)Math.floor(x+0.5)
- min,max,abs,random方法
min(x1,x2) // 返回两个数的最小值
max(x1,x2) // 返回两个数的最大值
abs(x) // 返回一个数的绝对值
random() // 可以生成大于等于0.0且小于1.0的double型随机数
- 常量
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
随机数示例
1:Math.random()
java.lang.Math
// public static double random()
// 返回的数值是[0,1.0)的double型数值
int max = 100;
int min = 1;
// 返回符合在[min,max]范围的int型的整数
int random1 = (int) (Math.random() * (max - min) + min);
int random2 = min + (int) (Math.random() * (max - min + 1));
2:java.util.Random
nextInt(int n)方法返回的数值是[0,n)的int型数值
nextDouble(double n)方法返回的数值是[0,n)的任意小数
// 只随机一回
Random ra = new Random(10);
System.out.println(ra.nextInt(10));
// 每次都随机
Random rd = new Random();
System.out.println(rd.nextInt(10));
// 随机返回在[min,max]范围的int型的整数
int max = 100;
int min = 1;
int randomNum = ra.nextInt((max - min) + 1) + min;
3:java.util.concurrent.ThreadLocalRandom
ThreadLocalRandom.current().nextInt(min, max + 1);
保留小数,检查小数示例
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NumberUtil {
public static void main(String[] args) {
System.out.println(new NumberUtil().formatNumber("456.125974", 3));
System.out.println(new NumberUtil().formatNumber("456.12", 3));
System.out.println(new NumberUtil().checkStrIsNum("-192322.1212"));
System.out.println(new NumberUtil().checkStrIsNum("-192322a1212"));
System.out.println(new NumberUtil().checkStrIsNum("005"));
}
/**
* 保留指定的位数,最后的0不保留
*
* @param value
* 数值
* @param i
* 要保留的位数
* @return
*/
public String formatNumber(String value, int i) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(i, RoundingMode.HALF_UP);
// 去掉最后的0
BigDecimal noZeros = bd.stripTrailingZeros();
return noZeros.toString();
}
// 判断是否为数字
public boolean checkStrIsNum(String str) {
Pattern NUMBER_PATTERN = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
String bigStr;
try {
bigStr = new BigDecimal(str).toString();
} catch (Exception e) {
return false;
}
Matcher isNum = NUMBER_PATTERN.matcher(str);
if (!isNum.matches()) {
return false;
}
return true;
}
// 保留两位小数
public String format1(double value) {
DecimalFormat df = new DecimalFormat("0.00");
return df.format(value);
}
public String format2(double value) {
return String.format("%.2f", value).toString();
}
}
Runtime
能够获取程序在运行时的数据(总的堆内存空间,自由(剩余)堆内存空间),还可以启动进程。
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class RuntimeTest {
public static void main(String[] args) {
// 获取总空间
Runtime runtime = Runtime.getRuntime();
// 获取JVM总空间
long total = runtime.totalMemory();
// 获取JVM空闲空间
long free = runtime.freeMemory();
// 当前使用空间
long usedMemory = total - free;
// 获取当前使用率
double useRate = 1.0 * 100 * usedMemory / total;
/*
* BigDecimal:有效位的数进行精确的运算 MathContext(指定的精度, 舍入模式):根据上下文设置进行舍入
* RoundingMode:指定丢弃精度的数值运算的舍入行为
*/
BigDecimal bDecimal = new BigDecimal(useRate, new MathContext(3, RoundingMode.HALF_UP));
System.out.println("使用率:" + bDecimal + "%");
}
}