08Java常用类3

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
/*
* 需求:请设计一个方法,可以实现获取任意范围内的随机数。
* 分析:
* A:键盘录入两个数据。
* int strat;
* int end;
* B:想办法获取在start到end之间的随机数
* 我写一个功能实现这个效果,得到一个随机数。(int)
* C:输出这个随机数
*/
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);
}
}

// 写一个功能两个明确:返回值类型:int 参数列表:int start,int end
public static int getRandom(int start, int end) {
// 1-100之间的随机数:int number = (int) (Math.random() * 100) + 1;
int number1 = (int) (Math.random() * end) + start;// 错误,获得的是 [start, end + start)范围的随机数
int number2 = (int) (Math.random() * (end - start + 1)) + start;// 有问题, 当 start > end 时, 如 start=100,end=95,获取的是[97, 100]范围的随机数
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
// nextInt方法源码
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();// 未给定种子,每次产生的随机数不同
Random r = new Random(1111);// 给定种子,每次产生的随机数相同
for (int x = 0; x < 10; x++) {
// int num = r.nextInt();// int范围内的随机数
int num = r.nextInt(100) + 1;// [1,100]内的随机数
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; // 让p不再指定堆内存
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.exit(0); // 后面代码将终止执行
System.out.println("我们也喜欢赵雅芝(白娘子)");
// System.out.println(System.currentTimeMillis());// 单独得到这样的实际目前对我们来说意义不大,那么,它到底有什么作用呢?

// 要求:请大家给我统计这段程序的运行时间
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));// [11, 22, 33, 44, 55]
System.out.println(Arrays.toString(arr2));// [6, 7, 22, 33, 10]
}
}

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) {
// 超过int范围内,Integer就不能再表示,所以就更谈不上计算了。
Integer i = new Integer(100);
System.out.println(i); // 100
System.out.println(Integer.MAX_VALUE); // 2147483647
Integer ii = new Integer("2147483647");
System.out.println(ii); // 2147483647
// Integer iii = new Integer("2147483648"); // NumberFormatException
// System.out.println(iii);
// 通过大整数来创建对象
BigInteger bi = new BigInteger("2147483648");
System.out.println("bi:" + bi); // bi:2147483648
}
}

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)); // add:150
System.out.println("subtract:" + bi1.subtract(bi2)); // subtract:50
System.out.println("multiply:" + bi1.multiply(bi2)); // multiply:5000
System.out.println("divide:" + bi1.divide(bi2)); // divide:2
BigInteger[] bis = bi1.divideAndRemainder(bi2);
System.out.println("商:" + bis[0]); // 商:2
System.out.println("余数:" + bis[1]); // 余数:0
}
}

BigDecimal类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
* 看程序写结果:结果和我们想的有一点点不一样,这是因为float类型的数据存储和整数不一样导致的。它们大部分的时候,都是带有有效数字位。
* 由于在运算的时候,float类型和double很容易丢失精度,演示案例。所以,为了能精确的表示、计算浮点数,Java提供了BigDecimal
* BigDecimal类:不可变的、任意精度的有符号十进制数,可以解决数据丢失问题。
*/
public class BigDecimalDemo {
public static void main(String[] args) {
System.out.println(0.09 + 0.01); // 0.09999999999999999
System.out.println(1.0 - 0.32); // 0.6799999999999999
System.out.println(1.015 * 100); // 101.49999999999999
System.out.println(1.301 / 100); // 0.013009999999999999
System.out.println(1.0 - 0.12); // 0.88
}
}

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); // 0.09999999999999999
System.out.println(1.0 - 0.32); // 0.6799999999999999
System.out.println(1.015 * 100); // 101.49999999999999
System.out.println(1.301 / 100); // 0.013009999999999999

BigDecimal bd1 = new BigDecimal("0.09");
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("add:" + bd1.add(bd2)); // add:0.10

BigDecimal bd3 = new BigDecimal("1.0");
BigDecimal bd4 = new BigDecimal("0.32");
System.out.println("subtract:" + bd3.subtract(bd4)); // subtract:0.68

BigDecimal bd5 = new BigDecimal("1.015");
BigDecimal bd6 = new BigDecimal("100");
System.out.println("multiply:" + bd5.multiply(bd6)); // multiply:101.500

BigDecimal bd7 = new BigDecimal("1.301");
BigDecimal bd8 = new BigDecimal("100");
System.out.println("divide:" + bd7.divide(bd8)); // divide:0.01301
System.out.println("divide:" + bd7.divide(bd8, 3, BigDecimal.ROUND_HALF_UP)); // divide:0.013
System.out.println("divide:" + bd7.divide(bd8, 3, 4)); // divide:0.013
System.out.println("divide:" + bd7.divide(bd8, 8, BigDecimal.ROUND_HALF_UP)); // divide:0.01301000

System.out.println("divide:" + bd7.divide(bd8, 3, RoundingMode.HALF_UP)); // divide:0.013
}
}

日期相关类

  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); // Sat Apr 01 11:32:05 CST 2017
// 将Date转换为String(格式化)
DateFormat df = DateFormat.getDateInstance();
String s = df.format(date);
System.out.println(s); // 2017-4-1
// 将String转换为Date(解析)
s = "2008-8-8";
try {
date = df.parse(s);
System.out.println(date); // Fri Aug 08 00:00:00 CST 2008
} catch (ParseException e) {
System.out.println("日期不合法!!!");
}
/*********************************************************************/
Date date = new Date();
System.out.println(date);// Sat Apr 01 11:38:09 CST 2017
// 将Date转换为String(格式化)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(date);
System.out.println(s);// 2017-04-01 11:38:09
// 将String转换为Date(解析)
s = "2008-8-8 8:8:8";
try {
date = sdf.parse(s);
System.out.println(date);// Fri Aug 08 08:08:08 CST 2008
} 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); // d:Sat Apr 01 09:10:13 CST 2017
// long time = System.currentTimeMillis();
long time = 1000 * 60 * 60; // 1小时
Date d2 = new Date(time);
System.out.println("d2:" + d2); // d2:Thu Jan 01 09:00:00 CST 1970
// 不是 01:00:00 是因为我们使用的是北京时间,北京时间是中国采用北京东八时区的区时作为标准时间
}
}

  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); // 1491009637592
System.out.println(System.currentTimeMillis()); // 1491009637592
System.out.println("d:" + d); // d:Sat Apr 01 09:20:37 CST 2017
d.setTime(1000);
System.out.println("d:" + d); // d:Thu Jan 01 08:00:01 CST 1970
}
}

  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
/*
* 算一下你来到这个世界多少年?
* 分析:
* A:键盘录入你的出生的年月日
* B:把该字符串转换为一个日期
* C:通过该日期得到一个毫秒值
* D:获取当前时间的毫秒值
* E:用D-C得到一个毫秒值
* F:把E的毫秒值转换为年
* /1000/60/60/24/365
*/
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();
// 用D-C得到一个毫秒值
long time = nowTime - myTime;
// 把E的毫秒值转换为年
long day = time / 1000 / 60 / 60 / 24 / 365;
System.out.println("你来到这个世界:" + day + "年");
}
}

DateFormat

针对日期进行格式化和针对字符串进行解析的类,但是是抽象类,所以使用其子类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); // 17-5-1 上午9:50

// 给定模式
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
// DateFormat类的 public final String format(Date date)
String s2 = sdf2.format(d);
System.out.println(s2); // 2017年05月01日 09:52:15

// String -- Date
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); // Fri Aug 08 12:12:12 CST 2008
}
}

  C:制作了一个针对日期操作的工具类。

img

日期类的时间从为什么是从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 + "日"); // 2017年4月1日
// Month 值是基于 0 的。例如,0 表示 January。
/*********************************************************************************/
// 三年前的今天
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 + "日"); // 2014年4月1日
/*********************************************************************************/
// 5年后的10天前
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 + "日"); // 2019年3月22日
/*********************************************************************************/
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 + "日"); // 2011年12月11日
}
}
  1. 案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* 计算任意一年的二月有多少天
* 分析:
* A:键盘录入任意的年份
* B:设置日历对象的年月日
* 年就是A输入的数据
* 月是2
* 日是1
* C:把时间往前推一天,就是2月的最后一天
* D:获取这一天输出即可
*/
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); // 其实是这一年的3月1日
c.add(Calendar.DATE, -1); // 把时间往前推一天,就是2月的最后一天
System.out.println(c.get(Calendar.DATE));
}
}

二分查找(二分法)

查找:

基本查找:数组元素无序(从头找到尾)

二分查找(折半查找):数组元素有序

数组高级二分查找原理图解:

img

代码:

img

注意:下面这种做法是有问题的。

因为数组本身是无序的,所以这种情况下的查找不能使用二分查找。

所以你先排序了,但是你排序的时候已经改变了我最原始的元素索引。

必须使用基本查找,除非需求不在意。

img

十大排序算法