Math类 包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
1、针对数学运算进行操作的类
2、常见方法(更多方法见API)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 成员变量: public static final double PI public static final double E 成员方法: public static int abs (int a) :绝对值 public static double ceil (double a) :向上取整 public static double floor (double a) :向下取整 public static int max (int a,int b) :最大值 public static int min (int a, int b) :最小值 public static double pow (double a,double b) :a的b次幂 public static double random () :随机数 [0.0 ,1.0 ) public static int round (float a) :四舍五入。 返回最接近参数的 int 。结果将舍入为整数:加上 1 /2 ,对结果调用 floor 并将所得结果强制转换为 int 类型。换句话说,结果等于以下表达式的值: (int )Math.floor(a + 0.5f ) public static long round (double a) :四舍五入。 返回最接近参数的 long 。结果将舍入为整数:加上 1 /2 ,对结果调用 floor 并将所得结果强制转换为 long 类型。换句话说,结果等于以下表达式的值: (long )Math.floor(a + 0.5d ) public static double sqrt (double a) :正平方根,返回正确舍入的 double 值的正平方根 System.out.println("max:" + Math.max(Math.max(12 , 23 ), 18 ));
案例:
A:猜数字小游戏
B:获取任意范围的随机数
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 public class MathDemo { public static void main (String[] args) { Scanner sc = new Scanner (System.in); System.out.println("请输入开始数:" ); int start = sc.nextInt(); System.out.println("请输入结束数:" ); int end = sc.nextInt(); for (int x = 0 ; x < 100 ; x++) { int num = getRandom(start, end); System.out.println(num); } } public static int getRandom (int start, int end) { int number1 = (int ) (Math.random() * end) + start; int number2 = (int ) (Math.random() * (end - start + 1 )) + start; int number3 = (int ) (Math.random() * (Math.abs(end - start) + 1 )) + Math.min(start, end); return number3; } }
Random类 1.用于产生随机数的类
如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。
2.构造方法:
A:Random():创建一个新的随机数生成器。此构造方法将随机数生成器的种子设置为某个值,该值与此构造方法的所有其他调用所用的值完全不同。
没有给种子,用的是默认种子,是当前时间的毫秒值 ,每次产生的随机数不同
B:Random(long seed): 使用单个 long 种子创建一个新的随机数生成器。该种子是伪随机数生成器的内部状态的初始值,该生成器可通过方法 protected int next(int bits) 维护。
指定种子,每次种子相同,随机数就相同
3.成员方法:
A:int nextInt() 返回int范围内的随机数
1 2 3 4 public int nextInt () { return next(32 ); }
B:int nextInt(int n) 返回[0,n)范围内的随机数
1 2 3 4 5 6 7 8 9 10 11 12 public class RandomDemo { public static void main (String[] args) { Random r = new Random (1111 ); for (int x = 0 ; x < 10 ; x++) { int num = r.nextInt(100 ) + 1 ; System.out.println(num); } } }
System类 1.System 类包含一些有用的 类 字段和方法。System 类不能被实例化。
在 System 类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。
解析:说明字段和方法都是跟类相关的,跟类相关不就是静态的么,说明没有构造方法 。
2.成员方法(更多方法见API)
1 2 3 4 A: public static void gc () :运行垃圾回收器 B: public static void exit (int status) :终止当前正在运行的 Java 虚拟机。参数用作状态码;根据惯例,非 0 的状态码表示异常终止。 C: public static long currentTimeMillis () :获取当前时间的毫秒值 D: public static void arraycopy (Object src,int srcPos,Object dest,int destPos,int length) :从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
案例:
A. 运行垃圾回收器
System.gc()可用于垃圾回收。当使用System.gc()回收某个对象所占用的内存之前,通过要求程序调用适当的方法来清理资源。在没有明确指定资源清理的情况下,Java提高了默认机制来清理该对象的资源,也就是调用Object类的finalize()方法。finalize()方法的作用是释放一个对象占用的内存空间时,会被JVM调用。而子类重写该方法,就可以清理对象占用的资源,该方法没有链式调用,所以必须手动实现。
从程序的运行结果可以发现,执行System.gc()前,系统会自动调用finalize()方法清除对象占有的资源,通过super.finalize()方式可以实现从下到上的finalize()方法的调用,即先释放自己的资源,再去释放父类的资源。
但是,不要在程序中频繁的调用垃圾回收,因为每一次执行垃圾回收,jvm都会强制启动垃圾回收器运行,这会耗费更多的系统资源,会与正常的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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class RandomDemo { public static void main (String[] args) { Person p = new Person ("林俊杰" , 60 ); System.out.println(p); p = null ; System.gc(); } } class Person { @Override protected void finalize () throws Throwable { System.out.println("当前的对象被回收了" + this ); super .finalize(); } private String name; private int age; public Person () { super (); } public Person (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } @Override public String toString () { return "Person [name=" + name + ", age=" + age + "]" ; } }
B. 退出jvm
public static void exit(int status)
终止当前正在运行的 Java 虚拟机。参数用作状态码;根据惯例,非 0 的状态码表示异常终止。
该方法调用 Runtime 类中的 exit 方法。该方法永远不会正常返回。
调用 System.exit(n) 实际上等效于调用:
Runtime.getRuntime().exit(n)
C. 获取当前时间的毫秒值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class SystemDemo { public static void main (String[] args) { System.out.println("我们喜欢林青霞(东方不败)" ); System.out.println("我们也喜欢赵雅芝(白娘子)" ); long start = System.currentTimeMillis(); for (int x = 0 ; x < 100000 ; x++) { System.out.println("hello" + x); } long end = System.currentTimeMillis(); System.out.println("共耗时:" + (end - start) + "毫秒" ); } }
D. 数组复制
1 2 3 4 5 6 7 8 9 public class SystemDemo { public static void main (String[] args) { int [] arr1 = { 11 , 22 , 33 , 44 , 55 }; int [] arr2 = { 6 , 7 , 8 , 9 , 10 }; System.arraycopy(arr1, 1 , arr2, 2 , 2 ); System.out.println(Arrays.toString(arr1)); System.out.println(Arrays.toString(arr2)); } }
BigInteger类 大数字
a. java.math.BigInteger:整数
b. java.math.BigDecimal:浮点数
1、针对大整数 的运算(BigInteger:可以让超过Integer范围内的数据进行运算)
2、构造方法
A:BigInteger(String s)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class BigIntegerDemo { public static void main (String[] args) { Integer i = new Integer (100 ); System.out.println(i); System.out.println(Integer.MAX_VALUE); Integer ii = new Integer ("2147483647" ); System.out.println(ii); BigInteger bi = new BigInteger ("2147483648" ); System.out.println("bi:" + bi); } }
3、成员方法(更多方法见API)
A: public BigInteger add(BigInteger val):加
B: public BigInteger subtract(BigInteger val):减
C: public BigInteger multiply(BigInteger val):乘
D: public BigInteger divide(BigInteger val):除
E: public BigInteger[] divideAndRemainder(BigInteger val):返回商和余数的数组
1 2 3 4 5 6 7 8 9 10 11 12 13 public class BigIntegerDemo { public static void main (String[] args) { BigInteger bi1 = new BigInteger ("100" ); BigInteger bi2 = new BigInteger ("50" ); System.out.println("add:" + bi1.add(bi2)); System.out.println("subtract:" + bi1.subtract(bi2)); System.out.println("multiply:" + bi1.multiply(bi2)); System.out.println("divide:" + bi1.divide(bi2)); BigInteger[] bis = bi1.divideAndRemainder(bi2); System.out.println("商:" + bis[0 ]); System.out.println("余数:" + bis[1 ]); } }
BigDecimal类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class BigDecimalDemo { public static void main (String[] args) { System.out.println(0.09 + 0.01 ); System.out.println(1.0 - 0.32 ); System.out.println(1.015 * 100 ); System.out.println(1.301 / 100 ); System.out.println(1.0 - 0.12 ); } }
1、浮点数据做运算,会丢失精度。所以,针对浮点数据 的操作建议采用BigDecimal。(金融相关的项目)
2、构造方法
A:BigDecimal(String s)
3、成员方法:
A: public BigDecimal add(BigDecimal augend):加
B: public BigDecimal subtract(BigDecimal subtrahend):减
C: public BigDecimal multiply(BigDecimal multiplicand):乘
D: public BigDecimal divide(BigDecimal divisor):除
E: public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode):商,几位小数,如何舍取
divisor - 此 BigDecimal 要除以的值。
scale - 要返回的 BigDecimal 商的标度。
roundingMode - 要应用的舍入模式。
F: public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode):商,几位小数,如何舍取
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 public class BigDecimalDemo { public static void main (String[] args) { System.out.println(0.09 + 0.01 ); System.out.println(1.0 - 0.32 ); System.out.println(1.015 * 100 ); System.out.println(1.301 / 100 ); BigDecimal bd1 = new BigDecimal ("0.09" ); BigDecimal bd2 = new BigDecimal ("0.01" ); System.out.println("add:" + bd1.add(bd2)); BigDecimal bd3 = new BigDecimal ("1.0" ); BigDecimal bd4 = new BigDecimal ("0.32" ); System.out.println("subtract:" + bd3.subtract(bd4)); BigDecimal bd5 = new BigDecimal ("1.015" ); BigDecimal bd6 = new BigDecimal ("100" ); System.out.println("multiply:" + bd5.multiply(bd6)); BigDecimal bd7 = new BigDecimal ("1.301" ); BigDecimal bd8 = new BigDecimal ("100" ); System.out.println("divide:" + bd7.divide(bd8)); System.out.println("divide:" + bd7.divide(bd8, 3 , BigDecimal.ROUND_HALF_UP)); System.out.println("divide:" + bd7.divide(bd8, 3 , 4 )); System.out.println("divide:" + bd7.divide(bd8, 8 , BigDecimal.ROUND_HALF_UP)); System.out.println("divide:" + bd7.divide(bd8, 3 , RoundingMode.HALF_UP)); } }
日期相关类 A. java.util.Date类:最常用的功能为获得系统的当前时间。
B. java.util.Calendar类:与日历相关的类。可以获得日期相关的信息,还可以进行日期的计算。
C. java.text.DateFormat及其子类:可以对String与Date进行相互的转换。
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 Date date = new Date (); System.out.println(date); DateFormat df = DateFormat.getDateInstance(); String s = df.format(date); System.out.println(s); s = "2008-8-8" ; try { date = df.parse(s); System.out.println(date); } catch (ParseException e) { System.out.println("日期不合法!!!" ); } Date date = new Date (); System.out.println(date); SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ); String s = sdf.format(date); System.out.println(s); s = "2008-8-8 8:8:8" ; try { date = sdf.parse(s); System.out.println(date); } catch (ParseException e) { System.out.println("日期不合法!!!" ); }
Date 类 Date 表示特定的瞬间,精确到毫秒。
A:构造方法
public Date():创建自 1970 年 1 月 1 日 00:00:00 GMT 到当前的默认毫秒值 的日期对象
public Date(long time):创建自 1970 年 1 月 1 日 00:00:00 GMT 到给定的毫秒值 的日期对象
1 2 3 4 5 6 7 8 9 10 11 public class DateDemo { public static void main (String[] args) { Date d1 = new Date (); System.out.println("d1:" + d1); long time = 1000 * 60 * 60 ; Date d2 = new Date (time); System.out.println("d2:" + d2); } }
B:成员方法
public long getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
public void setTime(long time):设置此 Date 对象,以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点。
1 2 3 4 5 6 7 8 9 10 11 public class DateDemo { public static void main (String[] args) { Date d = new Date (); long time = d.getTime(); System.out.println(time); System.out.println(System.currentTimeMillis()); System.out.println("d:" + d); d.setTime(1000 ); System.out.println("d:" + d); } }
C:日期和毫秒值的相互转换
案例:你来到这个世界多少天了?
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 MyYearOldDemo { public static void main (String[] args) throws ParseException { Scanner sc = new Scanner (System.in); System.out.println("请输入你的出生年月日(格式为yyyy-MM-dd):" ); String line = sc.nextLine(); SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd" ); Date d = sdf.parse(line); long myTime = d.getTime(); long nowTime = System.currentTimeMillis(); long time = nowTime - myTime; long day = time / 1000 / 60 / 60 / 24 / 365 ; System.out.println("你来到这个世界:" + day + "年" ); } }
针对日期进行格式化和针对字符串进行解析的类,但是是抽象类,所以使用其子类SimpleDateFormat
A: SimpleDateFormat的构造方法:
public SimpleDateFormat():用默认的模式 和默认语言环境的日期格式符号构造 SimpleDateFormat。
public SimpleDateFormat(String pattern): 用给定的模式 和默认语言环境的日期格式符号构造 SimpleDateFormat。
这个模式字符串该如何写呢? 通过查看API,我们就找到了对应的模式
y 年
M 年中的月份
d 月份中的天数
H 一天中的小时数(0-23)
m 小时中的分钟数
s 分钟中的秒数
yyyy-MM-dd HH:mm:ss 2017-05-01 12:12:12
yyyy年MM月dd日 HH:mm:ss 2017年05月01日 12:12:12
B:日期和字符串的转换
a:Date – String(格式化)
public final String format(Date date)
b:String – Date(解析)
public Date parse(String source)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class DateFormatDemo { public static void main (String[] args) throws ParseException { Date d = new Date (); SimpleDateFormat sdf1 = new SimpleDateFormat (); String s1 = sdf1.format(d); System.out.println(s1); SimpleDateFormat sdf2 = new SimpleDateFormat ("yyyy年MM月dd日 HH:mm:ss" ); String s2 = sdf2.format(d); System.out.println(s2); String str = "2008-08-08 12:12:12" ; SimpleDateFormat sdf3 = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ); Date dd = sdf3.parse(str); System.out.println(dd); } }
C:制作了一个针对日期操作的工具类。
日期类的时间从为什么是从1970年1月1日 I suspect that Java was born and raised on a UNIX system. UNIX considers the epoch (when did time begin) to be midnight, January 1, 1970. 是说java起源于UNIX系统,而UNIX认为1970年1月1日0点是时间纪元.
但这依然没很好的解释”为什么”,出于好奇,继续Google,总算找到了答案:
http://en.wikipedia.org/wiki/Unix_time
这里的解释是:
最初计算机操作系统是32位,而时间也是用32位表示。 System.out.println(Integer.MAX_VALUE); 2147483647 Integer在JAVA内用32位表 示,因此32位能表示的最大值是2147483647。 另外1年365天的总秒数是31536000, 2147483647/31536000 = 68.1
也就是说32位能表示的最长时间是68年,而实际上到2038年01月19日03时14分07 秒,便会到达最大时间,过了这个时间点,所有32位操作系统时间便会变为 10000000 00000000 00000000 00000000
也就是1901年12月13日20时45分52秒,这样便会出现时间回归的现象,很多软件便会运行异常了。
到这里,我想问题的答案已经出来了:
因为用32位来表示时间的最大间隔是68年,而最早出现的UNIX操作系统考虑到计算 机产生的年代和应用的时限综合取了1970年1月1日作为UNIX TIME的纪元时间(开始 时间),而java自然也遵循了这一约束。
至于时间回归的现象相信随着64为操作系统的产生逐渐得到解决,因为用64位操作 系统可以表示到292,277,026,596年12月4日15时30分08秒,相信我们的N代子孙,哪 怕地球毁灭那天都不用愁不够用了,因为这个时间已经是千亿年以后了。
最后一个问题:上面System.out.println(new Date(0)),打印出来的时间是8点而非0点, 原因是存在系统时间和本地时间的问题,其实系统时间依然是0点,只不过我的电脑时区 设置为东8区,故打印的结果是8点。
Calendar类 它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段 之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
1、日历类,封装了所有的日历字段值,通过统一的方法 根据传入不同的日历字段 可以获取值。
2、如何得到一个日历对象呢?
Calendar rightNow = Calendar.getInstance();// 使用默认时区和语言环境获得一个日历。返回的 Calendar 基于当前时间 ,使用了默认时区和默认语言环境。
本质返回的是子类对象
3、成员方法
A: public int get(int field):返回给定日历字段的值。日历类中的每个日历字段都是静态的成员变量,并且是int类型
B: public void add(int field,int amount): 根据日历的规则,为给定的日历字段添加或减去指定的时间量。
C: public final void set(int year,int month,int date): 设置日历字段 YEAR、MONTH 和 DAY_OF_MONTH 的值。
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 public class CalendarDemo { public static void main (String[] args) { Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int date = c.get(Calendar.DATE); System.out.println(year + "年" + (month + 1 ) + "月" + date + "日" ); c.add(Calendar.YEAR, -3 ); year = c.get(Calendar.YEAR); month = c.get(Calendar.MONTH); date = c.get(Calendar.DATE); System.out.println(year + "年" + (month + 1 ) + "月" + date + "日" ); c.add(Calendar.YEAR, 5 ); c.add(Calendar.DATE, -10 ); year = c.get(Calendar.YEAR); month = c.get(Calendar.MONTH); date = c.get(Calendar.DATE); System.out.println(year + "年" + (month + 1 ) + "月" + date + "日" ); c.set(2011 , 11 , 11 ); year = c.get(Calendar.YEAR); month = c.get(Calendar.MONTH); date = c.get(Calendar.DATE); System.out.println(year + "年" + (month + 1 ) + "月" + date + "日" ); } }
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class CalendarDemo { public static void main (String[] args) { Scanner sc = new Scanner (System.in); System.out.println("请输入年份:" ); int year = sc.nextInt(); Calendar c = Calendar.getInstance(); c.set(year, 2 , 1 ); c.add(Calendar.DATE, -1 ); System.out.println(c.get(Calendar.DATE)); } }
二分查找(二分法) 查找:
基本查找:数组元素无序(从头找到尾)
二分查找(折半查找):数组元素有序
数组高级二分查找原理图解:
代码:
注意:下面这种做法是有问题的。
因为数组本身是无序的,所以这种情况下的查找不能使用二分查找。
所以你先排序了,但是你排序的时候已经改变了我最原始的元素索引。
必须使用基本查找,除非需求不在意。
十大排序算法