3.1常用類(java學習筆記)包裝類及日期類


一、包裝類

java是一門面向對象的語言,秉承一切皆對象的思想。

可java中有一些基本數據類型並不是對象,有時可能需要將它們變為對象。

這時就需要用到我們的包裝類了。

基本數據類型 包裝類
int   Integer
char   Character
short Short
long Long
float Float
double Double
boolean Boolean
byte Byte

通過對應的包裝類可以讓基本屬性擁有對象的特性,之后可以使用相關的操作。

 

public class TestInteger {
public static void main(String[] args) {
int i = 10;
Integer I = new Integer(i);//轉化為Integer類型,也稱裝箱。
int temp = I.intValue(); //將I轉化為基本數據類型,也稱拆箱。
String str_i = Integer.toString(i);//將數字變字符串
int i_i = Integer.parseInt(str_i);//將字符串變數字
 System.out.println(str_i);
System.out.println(temp);
System.out.println(i_i);
System.out.println(I.MAX_VALUE);//輸出int能表示的最大值。
 }
}
運行結果:
10
10
10
2147483647

 

自動裝箱與自動拆箱

通過上面代碼我們可以看出,都是手動裝箱與拆箱的。

jdk檢查到兩邊類型符合時,會自動裝箱與拆箱無需手動拆箱。

public class TestInteger {
public static void main(String[] args) {
Integer I = 3; //自動裝箱 Integer I = new Integer(30;
int i = I; //自動拆箱 int i = I.intValue();
 System.out.println(I);
System.out.println(i);
System.out.println(I.MAX_VALUE);//輸出int能表示的最大值。
 }
}
運行結果:
3 3 2147483647

 

我們來看下下面這段代碼:

public class TestInteger {
public static void main(String[] args) {
Integer I1 = 127;
Integer I2 = 127;
Integer I3 = 129;
Integer I4 = 129;
Integer I5 = new Integer(127); System.
out.println(I1 == I2);//此處對象比較,比較的是地址值。 System.out.println(I3 == I4);
System.out.println(I1 == I5);//此處為false System.
out.println(System.identityHashCode(I1));//這里打印的hashCode,並不是對象存儲的地址。 System.out.println(System.identityHashCode(I2));//即使是不同對象,也可能有相同的hashCode, System.out.println(System.identityHashCode(I3));//此處只是想描述它們的地址是不同的,但我也不清楚如何獲得對象內存地址 System.out.println(System.identityHashCode(I4));//如果有哪位仁兄知道煩請告知,不勝感謝! System.out.println(I1.equals(I2));//此處比較的是數值,//這里用hashCode當做地址只是為了便於理解,但hashCode不是對象內存地址。 System.out.println(I3.equals(I4)); } }
運行結果:
true
false
false
366712642
366712642
1829164700
2018699554
true
true

 

 

我們可以看到I1 == I2,和 I3 == I4一個為false一個為true。

對此大家可能有疑問,這明顯不科學。我們來看I1,I2,I3,I4的地址。

代碼中打印的是hashCode並不是地址,這樣只是為了便於理解,就姑且把hashCode看做對象地址。

會發現I1和I2地址相同,I3,和I4地址不同,對象比較是比較地址所以才會造成這種結果。

 我們看下JDK源碼中的注釋

代表[-128,127]之間的值會被緩存,如果值在這個范圍內就直接引用已經創建好了的。

我們來看JDK源碼中的一部分,high = 127,low = -128;

他會將[-128,127]每一個都提前創建好一個對象。當自動裝箱時,會檢查是否在這個的范圍內,

如果是則直接引用已經創建好了的,如果不是則創建新的對象。

但要注意一點,用new Integer(10)創建無論是否在范圍內都會新建一個對象,所以 I1 == I5 為false。

 

 

二、Date

1.Date簡介

Date是時間的核心類,主要用於表示時間。其中表示時間的是一個long型的數值faseTime,單位是ms。

其中有一個基准,為1970-1-1 00:00:00為基准。

當fastTime為1000時代表過了1秒,既1970-1-1 00:00:01。

需要表示1970-1-1 00:01:00 既fastTime = 1000 * 60;

下面用代碼舉例說明:

import java.util.Date;
public class TestDate {
public static void main(String[] args) {
Date date_now = new Date();
Date date_test = new Date(60000);//此處是60s即一分鍾,60000的單位是ms
System.out.println(date_now);
System.out.println(date_test);
}
}
運行結果:
Sat Aug 18 21:54:02 CST 2018
Thu Jan 01 08:01:00 CST 1970

我們沒有向Date()中添加參數時,會默認傳遞一個當前時間。

如果傳遞了時間就按傳遞的參數來表示時間。

可我們在date_test中設置是60000應該是1分鍾,顯示的應該是1970-1-1 00:01:00,可最后運行顯示的是

1970-1-1 08:01:00,這是因為我們采用的是中國標准(CST)時間,而作為基准的是GMT時間,中間有八個小時的時差。

輸出改成date_test.toGMTString()就可以輸出GMT時間。1970-1-1 00:01:00

 

2.Date常用方法

 1.getTime()

返回表示當前時間的long型數。

public class TestDate {
public static void main(String[] args) {
Date date_now = new Date();
Date date_test = new Date(60000);
System.out.println(date_now);
System.out.println(date_now.getTime());//獲得代表當前時間的long型數值
System.out.println(date_test);
System.out.println(date_test.getTime());//獲得代表1970-1-1 00:01:00(GMT)時間的long型數組。
}
}
運行結果:
Sun Aug 19 11:16:14 CST 2018
1534648574913
Thu Jan 01 08:01:00 CST 1970
60000

 

2.setTime()

我們看下JDK源碼中也很容易理解,就是設置一個值。

public class TestDate {
public static void main(String[] args) {
Date date_test = new Date(60000);
date_test.setTime(0);//設置為基准時刻(GMT)
System.out.println(date_test);
System.out.println(date_test.getTime());//獲得代表當前時間的long型數值。
}
}
運行結果:
Thu Jan 01 08:00:00 CST 1970
0

 

3.after()和before()

after測試此日期是否在指定日期之后,是返回true,否返回false。

我們看下源碼中的: 

 return getMillisOf(this) > getMillisOf(when);

獲取此日期對象的毫秒值 > 獲取指定日期對象的毫秒值。

其實質就是比較日期的long型數值。

同樣before()也類似;

測試此日期是否在指定時間之前,是返回true,否返回false。

public class TestDate {
public static void main(String[] args) {
Date date_test = new Date(0);
Date date_now = new Date();
System.out.println(date_now.after(date_test));//當前日期是否在1970年基准時刻之后
System.out.println(date_now.before(date_test));//當前日期是否在1970年基准時刻之前
}
}
運行結果:
true
false

 

4.toString()

 

首先顯然這個重寫了Object類中的toString()方法。

我們看源碼中注釋部分的格式是否似曾相識?

我們來看這個:Thu Jan 01 08:00:00 CST 1970

我們會發現輸出時間時就是按照這種格式輸出的。

public class TestDate {
public static void main(String[] args) {
Date date_test = new Date(0);
System.out.println(date_test);
System.out.println(date_test.toString());//按指定格式輸出時間
}
}
運行結果:
Thu Jan 01 08:00:00 CST 1970 Thu Jan 01 08:00:00 CST 1970

我們會發現調用或者不調用tiString()輸出的格式都是一樣的,說明輸出時默認調用了toString()按照指定的格式打出時間。

 

三、DateFormat和SimpleDateFormat

從類名的翻譯來看就可以大概看出這兩個類是做什么的。

日期格式,簡單日期格式。可以看出這兩個類與日期格式有關

它們可以幫助我們按指定日期格式轉換。

由於DateFormat是抽象類無法直接創建對象,所以我們需要通過它的子類SimpleDateFormat創建對象。

 

1.format(Date);

format可以將日期轉化為指定格式的字符串。

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestSimpleDateFormat {
public static void main(String[] args) {
Date date = new Date();
DateFormat China_time = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss");//創建一個時間格式"yyyy-MM-dd hh-mm-ss"
String date_str = China_time.format(date);//將當前時間轉換為指定格式的字符串
 System.out.println(date_str);
}
}

 

運行結果:
2018-08-19 03-47-47
//即yyyy-MM-dd hh-mm-ss(年月日時分秒)

可以看到最后是按照我們指定的格式輸出。 我們可以自行定義格式比如(ss -mm-hh dd-MM-yy)秒分時日月年,並且年份顯示兩位(會自動顯示后兩位)。

我們來看這一句 DateFormat China_time = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss");其中有一個向上轉型。如果子類中重寫了父類的方法,那么調用的是子類的,反之調用的是父類的。(此處子類中有同名的方法但返回值不同故不構成重寫,調用的是父類(DateFormat)中的方法。

 

2.parse()

 將字符串轉換為指定格式的日期對象,輸入的字符串格式要和指定的格式相同。

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TestSimpleDateFormat {
    public static void main(String[] args) {
        Date date = new Date();
        DateFormat China_time = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss");//創建一個時間格式"yyyy-MM-dd hh-mm-ss"
        String date_str = "2018-8-19 16-18-00";//字符串格式必須和設定格式相同,不然會解析錯誤
        try {
            date = China_time.parse(date_str);//將當前字符串按指定格式轉換為時間。
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(date);
    } 
}
運行結果:
Sun Aug 19 16:18:00 CST 2018

下面有一張表代表了各個字母的含義:

 

 

四、Calendar與GregorianCalendar

 Calendar類是一個抽象類提供了時間的展示及計算功能,同樣需要通過其子類來創建。

1.get(int filed)

filed為指定屬性,指定什么就會根據方法的功能得到對應的數據。

例如指定field為Cnlendar.year就代表獲得當前日歷對象的年份。

import java.util.Calendar;
import java.util.GregorianCalendar;


public class TestCalendar {
    public static void main(String[] args) {
        Calendar now = new GregorianCalendar();//構造器沒有參數時默認傳遞當前時間
        Calendar c = new GregorianCalendar(2008,8,8); //構造器有很多重載的方法可以設置年月日時分秒等...
        
        int year = c.get(Calendar.YEAR);  //獲得該對象年份的值
        int month = c.get(Calendar.MONTH);//獲得該對象月份的值
        int day = c.get(Calendar.DAY_OF_MONTH); //獲得該對象在這個月中天數的值。
        
        int year_now = now.get(Calendar.YEAR);
        int month_now = now.get(Calendar.MONTH);
        int day_now = now.get(Calendar.DAY_OF_MONTH);
        
        System.out.println(year + "-" + month + "-" + day);//輸出設置時間年月日的值
        System.out.println(year_now + "-" + month_now + "-" + day_now);//輸出當前時間年月日的值。
    }
}
運行結果:
2008-8-8 2018-7-19
//我這里當前時間時2018-8-19

看到上述大家可能會有疑問,獲取當前月的值8月應該是8呀,為什么打印出來的確是7。

首先8月只是我們國內的說法,並不是通用的。國外沒有八月,只有August。

JDK源碼中0代表January即一月,11代表12月。所以但實際上代表八月的數值常量是7.

我們設置的8其實不是八月,我們設置的是數值8,數值8代表的是九月。

我們看下面一個例子。

import java.util.Calendar;
import java.util.GregorianCalendar;


public class TestCalendar {
    public static void main(String[] args) {
        Calendar c = new GregorianCalendar(2008,Calendar.AUGUST,8);//此處設置的是8月August
        
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);
        
        System.out.println(year + "-" + month + "-" + day);
    }
}
運行結果:
2008-7-8//最后運行是7.說明代表八月的常量是7

同樣星期天的常量值是1,星期一是2,。。。星期六是7

 

2.getTime(),getTimeMillis()

getTimeMillis()是返回當前日歷對象的時間值,返回的是一個long型的毫秒值。

 

getTime() 是返回一個時間類的對象,而且其中調用了getMillis(),並將其設置為時間。

 

import java.util.Calendar;
import java.util.GregorianCalendar;


public class TestCalendar {
    public static void main(String[] args) {
        Calendar c = new GregorianCalendar(2008,Calendar.AUGUST,8);//設置時間為2008-8-8 
        
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);
        
        System.out.println(c.getTimeInMillis());//獲取代表當前日歷對象的時間值
        System.out.println(c.getTime()); //將日歷對象時間設置為Date類對象的時間,並返回一個Date對象。簡單說就是將Calendar類對象轉換為Date類對象。
        System.out.println(year + "-" + month + "-" + day);
    }
}
運行結果:
1218124800000
Fri Aug 08 00:00:00 CST 2008
2008-7-8

 

 3.add(field,amount);

日期計算,這是很強大的一個方法。可以進行日期的計算,如加減一(年、月、日)。

field指定操作的屬性是年還是月還是日......,后面代表加減的數值。

import java.util.Calendar;
import java.util.GregorianCalendar;


public class TestCalendar {
    public static void main(String[] args) {
        Calendar c = new GregorianCalendar(2008,Calendar.AUGUST,8);//2008-8-8
        System.out.println(c.getTime());
        c.add(Calendar.YEAR, 1);//加一年
        c.add(Calendar.MONTH,1);//加一月
        c.add(Calendar.DAY_OF_MONTH, 2);//加兩天
        c.add(Calendar.DATE, -1); //減一天,DATE和DAY_OF_MONTH是一樣的,它們的常量值都是5;
        System.out.println(c.getTime());//最后加了一年一月一天。
    
    }
}
運行結果:
Fri Aug 08 00:00:00 CST 2008
Wed Sep 09 00:00:00 CST 2009

 

下面有一個小小例子,剛好可以鞏固下前面學的幾個時間類。

簡易日歷,輸入年月日,輸出對應的月份的日歷。

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Scanner;

public class TestDate {
    public static void main(String[] args) {
        Date date = new Date();             //創建一個時間對象,用於存放輸入時間。
        Scanner input = new Scanner(System.in);   //創建一個輸入
        System.out.println("請按提示格式輸入日期:例:(2000-1-1)");
        String inputDateString = input.nextLine();  //輸入時間的字符串格式必須與后面指定格式相同。
        DateFormat chinaTimeFormat = new SimpleDateFormat("yyyy-MM-dd");//注意此處格式
        try {
             date = chinaTimeFormat.parse(inputDateString);//將輸入的字符串轉換成時間對象
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        Calendar cn_InputDate = new GregorianCalendar();//創建兩個日歷對象。
        Calendar cn_PrinfDate = new GregorianCalendar();//一個用於存儲輸入日期,一個用於打印。
        cn_InputDate.setTime(date);//將輸入的時間設置到用於存放日期的日歷類。
        System.out.println("日\t一\t二\t三\t四\t五\t六");
        cn_PrinfDate.set(cn_InputDate.get(Calendar.YEAR), cn_InputDate.get(Calendar.MONTH), 1);//打印總是從1號開始,所以將輸入的日期設置為1。
        for(int i = 1; i < cn_PrinfDate.get(Calendar.DAY_OF_WEEK); i++){ //需要打印的空格數。即1號從星期幾開始。
            System.out.print("\t");//一個\t代表一個制表位八個空格。
        }
        for(int i = 1; i <= getMaxDaysOfMonth(cn_InputDate.get(Calendar.YEAR),cn_InputDate.get(Calendar.MONTH));i++){//日期從1號開始打印
            if(i == cn_InputDate.get(Calendar.DAY_OF_MONTH)){//如果當前要打印的i和輸入日期中的day相同就加個*
                    System.out.printf(i + "*\t"); //\t的作用可參考:https://blog.csdn.net/hju22/article/details/79773252    
            }else{
                System.out.printf(i + "\t");
            }
            if(cn_PrinfDate.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY){//如果周六打印完就換行。
                System.out.println();
            }
            cn_PrinfDate.add(Calendar.DAY_OF_MONTH, 1);//每打印一天,日期增加一天。
        }
        }

        private static int getMaxDaysOfMonth(int year, int month){ //獲取當前月份最大天數的函數。主要是判斷閏年與否   
        int M[] = {31,28,31,30,31,30,31,31,30,31,30,31};
        int M2[] = {31,29,31,30,31,30,31,31,30,31,30,31};
        if(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){
            return M2[month];//是閏年采用閏年的天數,反之采用非閏年天數。
        }else
        {
            return M[month];//由於剛好get(Calendar.MONTH)獲取到月份的數值是從0開始和數組的的下標對應。
        }
    }
} 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM