一、Array类
Arrays:针对数组操作的工具类 (提供了一些针对数组排序和二分搜索法)
public static String toString(int[] a):可以将int类型的数组转换成字符串 ([元素1,元素2,元素3...])
public static void sort(int[] a)对指定的 int 型数组按数字升序进行排序
public static int binarySearch(int[] a,int key):二分搜索法: 在int类型的数组中查找key元素的索引
public class ArraysDemo { public static void main(String[] args) { //定义一个数组:静态初始化 int[] arr = {24,69,80,57,13} ; //public static String toString(int[] a):可以将int类型的数组转换成字符串 ([元素1,元素2,元素3...]) //直接用Arrays去调用 String str = Arrays.toString(arr) ; System.out.println("str:"+str);//[24, 69, 80, 57, 13] //public static void sort(int[] a)对指定的 int 型数组按数字升序进行排序 Arrays.sort(arr); String str2 = Arrays.toString(arr) ; System.out.println("str2:"+str2); //public static int binarySearch(int[] a,int key):二分搜索法: //在int类型的数组中查找key元素的索引 //需求:查找57元素对应的索引 Arrays.sort(arr); int index = Arrays.binarySearch(arr, 57) ; System.out.println("index:"+index); int index2 = Arrays.binarySearch(arr, 577) ; System.out.println("index2:"+index2); } }我们来分析一下toString方法的源码:
public static String toString(int[] a) { if (a == null) //对数组进行非空判断 return "null"; int iMax = a.length - 1; //arr.length-1 if (iMax == -1) return "[]"; StringBuilder b = new StringBuilder(); //创建了一个字符串缓冲区 b.append('['); //先追加了左中括号:[ for (int i = 0; ; i++) { b.append(a[i]); //给缓冲区中追加数组中的元素 if (i == iMax) return b.append(']').toString(); //返回并且并追加了右中括号:]并且将数据元素转换字符串 b.append(", "); //如果不是最后一个索引,那么中间追加逗号 } }
在实际的开发过程中,只要有引用类型,在对引用类型数据进行操作的时候,对引用类型的对象进行非空判断,防止空指针异常(NullPointerException)
binarySearch方法的源码:
public static int binarySearch(int[] a, int key) { return binarySearch0(a, 0, a.length, key); } /** a--->arr:指定的int类型的数组 fromIndex:指定索引开始:0 toIndex:arr.length 5 key:要查找的元素值 */ nt[] arr = {13,24,57,69,80} ; private static int binarySearch0(int[] a, int fromIndex, int toIndex,int key) { int low = fromIndex; //最小索引 int high = toIndex - 1;// 最大索引 4 while (low <= high) { //如果最小索引小于=最大索引 int mid = (low + high) >>> 1; >>> :无符号右移动(位运算符) //中间索引:mid = 2 ,3 ,4 位^:位异或 位&:位与 位|:位或 << :左移动 有符合的数据表示法(原码,反码,补码) 计算机底层运算数据的时候:通过补码进行运算的 int midVal = a[mid]; // 查找中间索引对应的元素:arr[2] = 57 69 80 if (midVal < key) //判断:中间索引对应的元素与要查找的值的大小比较 low = mid + 1; //low = mid + 1; mid = (取到最大的mid的值) 4+1 = 5 else if (midVal > key) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found. // return -(low+1) = -6 }
这里主要讲一下无符号右移:
>>是带符号右移
>>>是无符号右移
带符号右移就是将那个数转为2进制然后在前面补0或1如果是正数就补0,负数补1
例如11 >> 2,则是将数字11右移2位
计算过程:
11的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011,然后把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 0010。转换为十进制是2。
无符号右移与带符号右移的区别就是 无符号始终补0
所以这里的mid通过无符号右移得到的值依次位2,3,4.
二、Calendar类
Calendar类:日历类Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法
注意,Calendar类是一个抽象类,那么该如何实例化呢?
public static Calendar getInstance() :通过一个静态功能来创建日历了对象
Calendar类的常用方法:
public abstract void add(int field,int amount)根据日历的规则,为给定的日历字段添加或减去指定的时间量
public final void set(int year, int month,int date)设置日历字段 YEAR、MONTH 和 DAY_OF_MONTH 的值
这里还有一个Date类需要特别讲一下,也是一个重点,这个我们下次再讲。
我们通过一个小例子来学习一下Calendar类的这几个方法:
public class CalendarDemo2 { 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+"日"); //需求:5年后的10天前 c.add(Calendar.YEAR, 5); c.add(Calendar.DATE, -10); //获取年 year = c.get(Calendar.YEAR) ; date = c.get(Calendar.DATE) ; System.out.println(year+"年"+(month+1)+"月"+date+"日"); //public final void set(int year, int month,int date)设置日历字段 YEAR、MONTH 和 DAY_OF_MONTH 的值 c.set(2018, 5,20); // 获取年 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)设置年月日
set(录入year,2,1) ; //实际是3月1日
4)再利用add(int field,int amount) : 在这里只需要将日期往前退一天即可
public class CalendarTest { 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); System.out.println("二月有:"+c.get(Calendar.DATE)+"天"); } }
三、System类
System 类包含一些有用的类字段和方法。它不能被实例化。
常用的方法:
public static void gc()运行垃圾回收器。
public static void exit(int status)终止当前正在运行的 Java 虚拟机。参数用作状态码; 一般情况,需要终止Jvm,那么参0
public static long currentTimeMillis()返回以毫秒为单位的当前时间
首先创建一个实体类Person,为了更直观的看出垃圾回收器的执行过程,我们重写finalize方法,因为运行垃圾回收器实际上执行的就是finalize方法。
public class Person { 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 + "]"; } @Override protected void finalize() throws Throwable { System.out.println("开始回收不用的对象了:"+this); super.finalize(); } }
public class SystemDemo { public static void main(String[] args) { //创建一个Person类的对象 Person p = new Person("张三", 27) ; System.out.println(p); //让p对象不指定堆内存了 p = null ; System.gc(); //运行垃圾回收器,实质是执行的finalize()方法 } }
接下来看一下exit方法,学习一下如何终止Java虚拟机
public static void main(String[] args) { System.out.println("我们喜欢高圆圆...."); //public static void exit(int status) System.exit(0); //jvm已经退出了 System.out.println("我们也喜欢杨桃...."); }
运行发现只打印了"我们喜欢高圆圆...."这句话,因为此时已经终止了JVM。
currentTimeMillis()方法:
public static void main(String[] args) { //public static long currentTimeMillis()返回以毫秒为单位的当前时间 long time = System.currentTimeMillis() ; System.out.println("time:"+time); //单独使用,没有意义 //一般情况,来测试一段代码的执行效率 (后面:jdbc: PreparedStatement Statement 也可以用currentTimeMillis来测试速率 ) long start = System.currentTimeMillis() ; for(int x =0 ; x < 1000; x ++) { System.out.println("hello"+x); } long end = System.currentTimeMillis() ; System.out.println("共耗时:"+(end-start)+"毫秒"); }
arraycopy方法:
public static void arraycopy(Object src,int srcPos, Object dest,int destPos, int length)从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束
src:原数组dest:目标数组
srcPos :从原数组的哪个位置开始
destPos:到目标数组的哪个位置结束
length:长度
public class SystemDemo2 { public static void main(String[] args) { int[] arr1 = {11,22,33,44,55,66} ; int[] arr2 = {5,6,7,8,9,10} ; System.out.println(Arrays.toString(arr1)); System.out.println(Arrays.toString(arr2)); System.out.println("---------------------------"); System.arraycopy(arr1, 1, arr2, 2, 2); System.out.println(Arrays.toString(arr1)); System.out.println(Arrays.toString(arr2)); } }
运行结果:
[11, 22, 33, 44, 55, 66]
[5, 6, 7, 8, 9, 10]
---------------------------
[11, 22, 33, 44, 55, 66]
[5, 6, 22, 33, 9, 10]