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

来源:https://www.cnblogs.com/huang-changfan/archive/2018/08/19/9495067.html
-Advertisement-
Play Games

一、包裝類 java是一門面向對象的語言,秉承一切皆對象的思想。 可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)){
            return M2[month];//是閏年採用閏年的天數,反之採用非閏年天數。
        }else
        {
            return M[month];//由於剛好get(Calendar.MONTH)獲取到月份的數值是從0開始和數組的的下標對應。
        }
    }
} 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這兩天翻了一下機器學習實戰這本書,演算法是不錯,只是代碼不夠友好,作者是個搞演算法的,這點從代碼上就能看出來。可是有些地方使用numpy搞數組,搞矩陣,總是感覺怪怪的,一個是需要使用三方包numpy,雖然這個包基本可以說必備了,可是對於一些新手,連pip都用不好,裝的numpy也是各種問題,所以說能不用 ...
  • ORACLE公司傳奇 ORACLE公司之起源 很難想象,ORACLE 公司的這一段傳奇居然要從 IBM 公司開始。 1970年的6月,IBM 公司的研究員埃德加·考特 (Edgar Frank Codd) 在 Communications of ACM 上發表了那篇著名的《大型共用資料庫數據的關係模 ...
  • 今天發現了智障的真我。 剛入門flask,建了一個文件命名叫flask.py 在virtualenv的容器里運行該py文件,報錯cannot import name 'Flask' from 'flask'。 這是因為它導入的模塊不是我用pip安裝那個,而是自己這個自定義模塊flask.py,首先去 ...
  • Matlab繪圖 強大的繪圖功能是Matlab的特點之一,Matlab提供了一系列的繪圖函數,用戶不需要過多的考慮繪圖的細節,只需要給出一些基本參數就能得到所需圖形,這類函數稱為高層繪圖函數。此外,Matlab還提供了直接對圖形句柄進行操作的低層繪圖操作。這類操作將圖形的每個圖形元素(如坐標軸、曲線 ...
  • 友元基本概念: 1,把一個一般函數聲明為一個類的友元函數 2,把一個類A的某幾個成員函數聲明為某個類B的友元函數 3,把一個類A聲明為一個類B的友元類。 友元的作用:可以訪問類B里所有的成員變數和成員方法,不管是public,protected,還是private。 1,把一個一般函數show聲明為 ...
  • 一. 問題 二. 產生問題原因 基於maven的項目,使用各種maven plugin來完成開發中的各種工作,例如編譯代碼,打包,部署等等… 每個plugin包含許多的goal,用來做特定的事情。典型的基於java的maven項目就有 clean compile test package deplo ...
  • 經過三次重寫,和合計30多個小時的開發,終於把這個簡單的邏輯做完了。(自己太笨) 因為剛剛接觸C,寫的代碼實現方式肯定有不對的地方,邏輯上可能也有疏漏,如果有看官發現問題還望及時給予指正,謝謝。 一、整體概括: 1.1目標: 維護一個單獨的緩存空間,該空間是低一級存儲的緩存。緩存的大小比低級存儲的大 ...
  • 原創 http://acm.hdu.edu.cn/showproblem.php?pid=1003 題目要求求出一個序列裡面的最大序列和,序列要求是連續的,給出最大序列和,序列首元素下標和尾元素下標,按特定的格式輸出。 解題思路: 動態規劃,我們可以將所有序列按以序列中的元素a[i](i=1~n)結 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...