Java-009-数组和日期时间类(Date,Calendar)详解
一、数组
//Java 语言中提供的数组是用来存储固定大小的同类型元素。
//你可以声明一个数组变量,如 numbers[100] 来代替直接声明 100 个独立变量 number0,number1,....,number99
//①声明数组变量
/* dataType[] arrayRefVar; // 首选的方法 或 dataType arrayRefVar[]; // 效果相同,但不是首选方法 */ //实例 double[] myListA; // 首选的方法 double myListB[]; // 效果相同,但不是首选方法
//②创建数组 使用new操作符来创建数组
arrayRefVar = new dataType[arraySize]; /* 上面的语法语句做了两件事 一、使用 dataType[arraySize] 创建了一个数组 二、把新创建的数组的引用赋值给变量 arrayRefVar。 */ //数组变量的声明,和创建数组可以用一条语句完成 //dataType[] arrayRefVar = new dataType[arraySize]; //另外,你还可以使用如下的方式创建数组。 //dataType[] arrayRefVar = {value0, value1, ..., valuek}; //数组的元素是通过索引访问的。数组索引从 0 开始,所以索引值从 0 到 arrayRefVar.length-1。 //实例 // 数组大小 int size = 10; //定义数组 double[] myList = new double[size]; myList[0] = 5.6; myList[1] = 4.5; myList[2] = 3.3; myList[3] = 13.2; myList[4] = 4.0; myList[5] = 34.33; myList[6] = 34.0; myList[7] = 45.45; myList[8] = 99.993; myList[9] = 11123; //计算所有元素的总和 double total = 0; for (int i = 0 ; i < size ; i ++) { total += myList[i]; } System.out.println("总和为: " + total);//总和为: 11367.373
//③处理数组
//数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环或者 foreach 循环。 double[] myListC = {1.9, 2.9, 3.4, 3.5}; // 打印所有数组元素 for (int i = 0; i < myListC.length; i++) { System.out.println(myListC[i] + " "); } // 计算所有元素的总和 double sum = 0; for (int i = 0; i < myListC.length; i++) { sum += myListC[i]; } System.out.println("Total is " + sum);//Total is 11.7 // 查找最大元素 double max = myListC[0]; for (int i = 1; i < myListC.length; i ++){ if (myListC[i] > max) max = myList[i]; } System.out.println("Max is " + max);//Max is 4.5
//④foreach 循环 它能在不使用下标的情况下遍历数组。
// 打印所有数组元素 for (double element: myListC) { System.out.println("element = " + element); /* element = 1.9 element = 2.9 element = 3.4 element = 3.5 */ }
//⑤数组作为函数的参数 数组可以作为参数传递给方法。
//下面例子调用 printArray 方法打印出 3,1,2,6,4 和 2: JavaArray exampleOne = new JavaArray(); exampleOne.printArray(new int[]{3, 1, 2, 6, 4, 2}); public void printArray(int[] array){ for (int i = 0 ; i < array.length ; i++){ System.out.print(array[i] + " ");//3 1 2 6 4 2 } }
//⑥数组作为函数的返回值
public static int[] reverse(int[] list) { int[] result = new int[list.length]; for (int i = 0, j = result.length - 1; i < list.length; i++, j--) { result[j] = list[i]; } return result;// result 数组作为函数的返回值。 }
//⑦多维数组
//多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
String str[][] = new String[3][4]; //多维数组的动态初始化(以二维数组为例) //1. 直接为每一维分配空间,格式如下: //type arrayName = new type[arraylenght1][arraylenght2]; //type 可以为基本数据类型和复合数据类型,arraylenght1 和 arraylenght2 必须为正整数,arraylenght1 为行数,arraylenght2 为列数。 int a[][] = new int[2][3]; //解析:二维数组 a 可以看成一个两行三列的数组。 //2. 从最高维开始,分别为每一维分配空间,例如: String s[][] = new String[2][]; s[0] = new String[2]; s[1] = new String[3]; s[0][0] = new String("Good"); s[0][1] = new String("Luck"); s[1][0] = new String("to"); s[1][1] = new String("you"); s[1][2] = new String("!"); //多维数组的引用(以二维数组为例) //对二维数组中的每个元素,引用方式为 arrayName[index1][index2] //num[1][0]; //Arrays 类 //java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。 /* 具有以下功能: 给数组赋值:通过 fill 方法。 对数组排序:通过 sort 方法,按升序。 比较数组:通过 equals 方法比较数组中元素值是否相等。 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。 */ /* 1 public static int binarySearch(Object[] a, Object key) 用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 2 public static boolean equals(long[] a, long[] a2) 如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 3 public static void fill(int[] a, int val) 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 4 public static void sort(Object[] a) 对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 */
二、Java日期时间类
import java.util.Date; import java.text.*; import java.util.*; //java.util 包提供了 Date 类来封装当前的日期和时间。 Date 类提供两个构造函数来实例化 Date 对象。
//1.第一个构造函数使用当前日期和时间来初始化对象。 //Date() //2.第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。 //Date(long millisec) //Date对象创建以后,可以调用下面的方法。 //①boolean after(Date date) //若当调用此方法的Date对象在指定日期之后返回true,否则返回false。 //②boolean before(Date date) //若当调用此方法的Date对象在指定日期之前返回true,否则返回false。 //③Object clone( ) //返回此对象的副本。 //④int compareTo(Date date) //比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。 //int compareTo(Object obj) //若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。 //⑤boolean equals(Object date) //当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。 //⑥long getTime( )获取时间戳 //返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。 //⑦int hashCode( ) // 返回此对象的哈希码值。 //⑧void setTime(long time) //用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。 //⑨String toString( ) //把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
//一、获取当前日期时间
//1.初始化Date对象 Date date = new Date(); //2.使用toString() 函数显示日期时间 System.out.println("当前时间" + date.toString());//当前时间Wed Aug 08 09:09:51 CST 2018
//二、日期比较
//Java使用以下三种方法来比较两个日期 //A.使用 getTime() 方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。 //B.使用方法 before(),after() 和 equals()。例如,一个月的12号比18号早,则 new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回true。 //C.使用 compareTo() 方法,它是由 Comparable 接口定义的,Date 类实现了这个接口。
//三、使用 SimpleDateFormat 格式化日期
Date dNow = new Date(); SimpleDateFormat format = new SimpleDateFormat("\"E yyyy.MM.dd 'at' hh:mm:ss a zzz\""); System.out.println("CurrentDate : " + format.format(dNow)); //输出结果:CurrentDate : "Wed 2018.08.08 at 09:16:51 AM CST" //SimpleDateFormat ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); // 这一行代码确立了转换的格式,其中 yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。 //注意:有的格式大写,有的格式小写,例如 MM 是月份,mm 是分;HH 是 24 小时制,而 hh 是 12 小时制。
//四、日期和时间的格式化编码
//G 纪元标记 AD //y 四位年份 2001 //M 月份 July or 07 //d 一个月的日期 10 //h A.M./P.M. (1~12)格式小时 12 //H 一天中的小时 (0~23) 22 //m 分钟数 30 //s 秒数 55 //S 毫秒数 234 //E 星期几 Tuesday //D 一年中的日子 360 //F 一个月中第几周的周几 2 (second Wed. in July) //w 一年中第几周 40 //W 一个月中第几周 1 //a A.M./P.M. 标记 PM //k 一天中的小时(1~24) 24 //K A.M./P.M. (0~11)格式小时 10 //z 时区 Eastern Standard Time //' 文字定界符 Delimiter //" 单引号 `
//五、使用printf格式化日期
//printf 方法可以很轻松地格式化时间和日期。使用两个字母格式,它以 %t 开头并且以下面表格中的一个字母结尾。
//c 包括全部日期和时间信息 星期六 十月 27 14:21:20 CST 2007
//F "年-月-日"格式 2007-10-27
//D "月/日/年"格式 10/27/07
//r "HH:MM:SS PM"格式(12时制) 02:25:51 下午
//T "HH:MM:SS"格式(24时制) 14:28:16
//R "HH:MM"格式(24时制) 14:28
//实例 // 初始化 Date 对象 Date dateInfo = new Date(); //c的使用 System.out.printf("全部日期和时间信息:%tc%n",dateInfo); //全部日期和时间信息:星期三 八月 08 09:23:26 CST 2018 //f的使用 System.out.printf("年-月-日格式:%tF%n",dateInfo); //年-月-日格式:2018-08-08 //d的使用 System.out.printf("月/日/年格式:%tD%n",dateInfo); //月/日/年格式:08/08/18 //r的使用 System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",dateInfo); //HH:MM:SS PM格式(12时制):09:23:26 上午 //t的使用 System.out.printf("HH:MM:SS格式(24时制):%tT%n",dateInfo); //HH:MM:SS格式(24时制):09:23:26 //R的使用 System.out.printf("HH:MM格式(24时制):%tR",dateInfo); //HH:MM格式(24时制):09:23 //如果你需要重复提供日期, 可以利用一个格式化字符串指出要被格式化的参数的索引。 //索引必须紧跟在%后面,而且必须以$结束 // 使用toString()显示日期和时间 System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", dateInfo);//Due date: 八月 08, 2018 //或者,你可以使用 < 标志。它表明先前被格式化的参数要被再次使用 // 显示格式化时间 System.out.printf("%s %tB %<te, %<tY", "Due date:", dateInfo);//Due date: 八月 8, 2018 //定义日期格式的转换符可以使日期通过指定的转换符生成新字符串 //b的使用,月份简称 String str=String.format(Locale.US,"英文月份简称:%tb",date); System.out.println(str); //2018英文月份简称:Aug System.out.printf("本地月份简称:%tb%n",date); //本地月份简称:八月 //B的使用,月份全称 str=String.format(Locale.US,"英文月份全称:%tB",date); System.out.println(str); //英文月份全称:August System.out.printf("本地月份全称:%tB%n",date); //本地月份全称:八月 //a的使用,星期简称 str=String.format(Locale.US,"英文星期的简称:%ta",date); System.out.println(str); //英文星期的简称:Wed //A的使用,星期全称 System.out.printf("本地星期的简称:%tA%n",date); //本地星期的简称:星期三 //C的使用,年前两位 System.out.printf("年的前两位数字(不足两位前面补0):%tC%n",date); //年的前两位数字(不足两位前面补0):20 //y的使用,年后两位 System.out.printf("年的后两位数字(不足两位前面补0):%ty%n",date); //年的后两位数字(不足两位前面补0):18 //j的使用,一年的天数 System.out.printf("一年中的天数(即年的第几天):%tj%n",date); //一年中的天数(即年的第几天):220 //m的使用,月份 System.out.printf("两位数字的月份(不足两位前面补0):%tm%n",date); //两位数字的月份(不足两位前面补0):08 //d的使用,日(二位,不够补零) System.out.printf("两位数字的日(不足两位前面补0):%td%n",date); //两位数字的日(不足两位前面补0):08 //e的使用,日(一位不补零) System.out.printf("月份的日(前面不补0):%te",date); //月份的日(前面不补0):8
//六、解析字符串为时间
//SimpleDateFormat 类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串 SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); String input = args.length == 0 ? "2018-8-8" : args[0]; System.out.print(input + " Parses as ");//2018-8-8 Parses as Date t; try { t = ft.parse(input); System.out.println(t);//Wed Aug 08 00:00:00 CST 2018 } catch (ParseException e) { System.out.println("Unparseable using " + ft); }
//七、Java 休眠(sleep)
//1.sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。 //你可以让程序休眠一毫秒的时间或者到您的计算机的寿命长的任意段时间。 try { System.out.println(new Date( ) + "\n"); Thread.sleep(1000*3); // 休眠3秒 System.out.println(new Date( ) + "\n");//Wed Aug 08 09:39:54 CST 2018 } catch (Exception e) { System.out.println("Got an exception!"); } //2.如何测量时间间隔(以毫秒为单位) try { long start = System.currentTimeMillis( ); System.out.println(new Date( ) + "\n"); Thread.sleep(5*60*10); System.out.println(new Date( ) + "\n"); long end = System.currentTimeMillis( ); long diff = end - start; System.out.println("Difference is : " + diff);//Difference is : 3005 } catch (Exception e) { System.out.println("Got an exception!"); }
//八、Calendar类
//设置和获取日期数据的特定部分呢,比如说小时,日,或者分钟? 我们又如何在日期的这些部分加上或者减去值呢? 答案是使用Calendar 类
//Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可
//1.创建一个代表系统当前日期的Calendar对象 Calendar c = Calendar.getInstance();//默认是当前日期 //2.创建一个指定日期的Calendar对象 //使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。 //创建一个代表2009年6月12日的Calendar对象 Calendar c1 = Calendar.getInstance(); c1.set(2009, 6 - 1, 12); //3.Calendar类对象字段类型 //Calendar.YEAR 年份 //Calendar.MONTH 月份 //Calendar.DATE 日期 //Calendar.DAY_OF_MONTH 日期,和上面的字段意义完全相同 //Calendar.HOUR 12小时制的小时 //Calendar.HOUR_OF_DAY 24小时制的小时 //Calendar.MINUTE 分钟 //Calendar.SECOND 秒 //Calendar.DAY_OF_WEEK 星期几 //4.Calendar类对象信息的设置 //把 c1对象代表的日期设置为10号,其它所有的数值会被重新计算 c1.set(Calendar.DATE,10); //把c1对象代表的年份设置为2008年,其他的所有数值会被重新计算 c1.set(Calendar.YEAR,2008); //Add设置 Calendar c2 = Calendar.getInstance(); //把c2对象的日期加上10,也就是c1也就表示为10天后的日期,其它所有的数值会被重新计算 c2.add(Calendar.DATE, 10); //把c2对象的日期减去10,也就是c1也就表示为10天前的日期,其它所有的数值会被重新计算 c1.add(Calendar.DATE, -10); //Calendar类对象信息的获得 // 获得年份 int year = c1.get(Calendar.YEAR); // 获得月份 int month = c1.get(Calendar.MONTH) + 1; // 获得日期 int dateD = c1.get(Calendar.DATE); // 获得小时 int hour = c1.get(Calendar.HOUR_OF_DAY); // 获得分钟 int minute = c1.get(Calendar.MINUTE); // 获得秒 int second = c1.get(Calendar.SECOND); // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推) int day = c1.get(Calendar.DAY_OF_WEEK);
//九、GregorianCalendar类
//Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。
//Calendar 的getInstance()方法返回一个默认用当前的语言环境和时区初始化的GregorianCalendar对象。GregorianCalendar定义了两个字段:AD和BC。这是代表公历定义的两个时代。
//下面列出GregorianCalendar对象的几个构造方法: //1 GregorianCalendar() //在具有默认语言环境的默认时区内使用当前时间构造一个默认的 GregorianCalendar。 //2 GregorianCalendar(int year, int month, int date) //在具有默认语言环境的默认时区内构造一个带有给定日期设置的 GregorianCalendar //3 GregorianCalendar(int year, int month, int date, int hour, int minute) //为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。 //4 GregorianCalendar(int year, int month, int date, int hour, int minute, int second) // 为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。 //5 GregorianCalendar(Locale aLocale) //在具有给定语言环境的默认时区内构造一个基于当前时间的 GregorianCalendar。 //6 GregorianCalendar(TimeZone zone) //在具有默认语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。 //7 GregorianCalendar(TimeZone zone, Locale aLocale) // 在具有给定语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。 //这里是GregorianCalendar 类提供的一些有用的方法列表: //1 void add(int field, int amount) //根据日历规则,将指定的(有符号的)时间量添加到给定的日历字段中。 //2 protected void computeFields() //转换UTC毫秒值为时间域值 //3 protected void computeTime() //覆盖Calendar ,转换时间域值为UTC毫秒值 //4 boolean equals(Object obj) //比较此 GregorianCalendar 与指定的 Object。 //5 int get(int field) //获取指定字段的时间值 //6 int getActualMaximum(int field) //返回当前日期,给定字段的最大值 //7 int getActualMinimum(int field) //返回当前日期,给定字段的最小值 //8 int getGreatestMinimum(int field) // 返回此 GregorianCalendar 实例给定日历字段的最高的最小值。 //9 Date getGregorianChange() //获得格里高利历的更改日期。 //10 int getLeastMaximum(int field) //返回此 GregorianCalendar 实例给定日历字段的最低的最大值 //11 int getMaximum(int field) //返回此 GregorianCalendar 实例的给定日历字段的最大值。 //26 void setTimeZone(TimeZone value) //用给定时区值设置当前时区。 //实例:判断当前年份是否是闰年 String months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int yearF; // 初始化 Gregorian 日历 // 使用当前时间和日期 // 默认为本地时间和时区 GregorianCalendar gcalendar = new GregorianCalendar(); // 显示当前时间和日期的信息 System.out.print("Date: "); System.out.print(months[gcalendar.get(Calendar.MONTH)]); System.out.print(" " + gcalendar.get(Calendar.DATE) + " "); System.out.println(yearF = gcalendar.get(Calendar.YEAR)); System.out.print("Time: "); System.out.print(gcalendar.get(Calendar.HOUR) + ":"); System.out.print(gcalendar.get(Calendar.MINUTE) + ":"); System.out.println(gcalendar.get(Calendar.SECOND)); // 测试当前年份是否为闰年 if(gcalendar.isLeapYear(yearF)) { System.out.println("当前年份是闰年"); } else { System.out.println("当前年份不是闰年"); //结果:当前年份不是闰年 }
//注意:
①Calender的月份是从0开始的,但日期和年份是从1开始的
Calendar c3 = Calendar.getInstance(); c3.set(2017, 1, 1); System.out.println(c3.get(Calendar.YEAR) +"-"+c3.get(Calendar.MONTH) +"-"+c3.get(Calendar.DATE)); //2017-1-1 c3.set(2017, 1, 0); System.out.println(c3.get(Calendar.YEAR) +"-"+c3.get(Calendar.MONTH) +"-"+c3.get(Calendar.DATE)); //2017-0-31 //可见,将日期设为0以后,月份变成了上个月,但月份可以为0
//②把月份改为2试试:
Calendar c4 = Calendar.getInstance(); c4.set(2017, 2, 1); System.out.println(c4.get(Calendar.YEAR) +"-"+c4.get(Calendar.MONTH) +"-"+c4.get(Calendar.DATE)); //2017-2-1 c4.set(2017, 2, 0); System.out.println(c4.get(Calendar.YEAR) +"-"+c4.get(Calendar.MONTH) +"-"+c4.get(Calendar.DATE)); //2017-1-28 //可以看到上个月的最后一天是28号,所以Calendar.MONTH为1的时候是2月
//③既然日期设为0表示上个月的最后一天,那是不是可以设为负数呢?
c4.set(2017, 2, 1); System.out.println(c4.get(Calendar.YEAR) +"-"+c4.get(Calendar.MONTH) +"-"+c4.get(Calendar.DATE)); //2017-2-1 c4.set(2017, 2, -10); System.out.println(c4.get(Calendar.YEAR) +"-"+c4.get(Calendar.MONTH) +"-"+c4.get(Calendar.DATE)); //2017-1-18 //果然可以,所以日期才可以自由加减。 //月份也可以是负数,规则与日期一样 //实测将年份设为非正数时,会自动变为绝对值+1