Array类、Calendar类和System类的学习

一、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

扫描二维码关注公众号,回复: 101515 查看本文章

所以这里的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]


猜你喜欢

转载自blog.csdn.net/cangerwjd/article/details/80170664