欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

3.1常用类(java学习笔记)包装类及日期类

程序员文章站 2022-03-18 15:38:05
一、包装类 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;
system.out.println(i1 == i2);//此处对象比较,比较的是地址值。
system.out.println(i3 == i4);
system.out.println(system.identityhashcode(i1));//打印对象地址
system.out.println(system.identityhashcode(i2));
system.out.println(system.identityhashcode(i3));
system.out.println(system.identityhashcode(i4));
system.out.println(i1.equals(i2));//此处比较的是值
system.out.println(i3.equals(i4));
}
}
运行结果:
true
false
366712642
366712642
1829164700
2018699554
true
true

我们可以看到i1 == i2,和 i3 == i4一个为false一个为true。

对此大家可能有疑问,这明显不科学。我们来看i1,i2,i3,i4的地址。

会发现i1和i2地址相同,i3,和i4地址不同,对象比较是比较地址所以才会造成这种结果。

 我们看下jdk源码中的注释

3.1常用类(java学习笔记)包装类及日期类

代表[-128,127]之间的值会被存,这样就不用通过构造来创建了,而是使代表这些值的对象指向同一个地址。

例如上面的i1和i2地址是相同的。

 

二、date

1.date简介

date是时间的核心类,主要用于表示时间。其中表示时间的是一个long型的数值fasetime,可以精确到毫秒。

其中有一个基准,为1970-1-1 00:00:00为基准。

当fasttime为1000时代表过了1秒,既1970-1-1 00:00:00。

需要表示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);
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()中添加参数时,会默认传递一个当前时间。

如果传递了时间就按传递的参数来表示实际。

3.1常用类(java学习笔记)包装类及日期类

可我们在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()

3.1常用类(java学习笔记)包装类及日期类

我们看下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()

3.1常用类(java学习笔记)包装类及日期类

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

我们看下源码中的: 

 return getmillisof(this) > getmillisof(when);

获取此日期对象的毫秒值 > 获取指定日期对象的毫秒值。

其实质就是比较日期的long型数值。

同样before()也类似;

3.1常用类(java学习笔记)包装类及日期类

测试此日期是否在指定时间之前,是返回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()

 3.1常用类(java学习笔记)包装类及日期类

首先显然这个重写了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

下面有一张表代表了各个字母的含义:

3.1常用类(java学习笔记)包装类及日期类

 

 

四、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即一月,故我们当前时间为8月,但实际上表示八月的数值是7.

我们设置的八月其实不是八月,我们设置的是数值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.

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

 

2.gettime(),gettimemillis()

gettimemillis()是返回当前日历对象的时间值,返回的是一个long型的毫秒值。

3.1常用类(java学习笔记)包装类及日期类

 

gettime() 是返回一个时间类的对象,而且其中调用了getmillis(),并将其设置为时间。

 3.1常用类(java学习笔记)包装类及日期类

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开始和数组的的下标对应。
        }
    }
} 

3.1常用类(java学习笔记)包装类及日期类