一、装包类
包装:是对被包装对象的一个增强。
jdk中,有很多包装类,如:
8大基本数据类型:它没有属性,也没有方法,现在想给8个大基本数据类型增强功能,让它们和对象一样的使用(可以使用属 性和方法),因而需要将8大基本数据类型做包装。
基本数据类型 包装类型
byte: Byte
short: Short
int: Integer
long: Long
float: Float
double: Double
char: Character
boolean: Boolean
(1) 包装类的理解:
为了满足Java语言面向对象的这一特性,上述基本数据类型中的每一个在java.lang包中都有一个包装类,即将每个基本类型都包装成了一个类。常用的包装类可以分为三类:Character、Number、Boolean,具体见上表所示。
这里总结一下包装类的一些特性:
1.所有包装类都可以将与之对应的基本数据类型作为参数来创建它们的实例对象
2. 除了Character类之外,其他包装类都可以将一个字符串作为参数来构造它们的实例
3.Boolean类的构造方法参数为String类型时,若该字符串为true(不论大小写),则该对象表示true,否则表示false
4.当包装类Number构造方法的参数为String类型时,字符串不能为null,并且该字符串必须能够解析为基本类型的数据
(2) 包装类的作用
总的来说,包装类有以下一些用途:
1.集合不允许存放基本数据类型,故常用包装类
2.包含了每种基本数据类型的相关属性,如最大值、最小值、所占位数等
3.作为基本数据类型对应的类类型,提供了一系列实用的对象操作,如类型转换、进制转换等等
int a=0;String result=Integer.toString(a);
【强制】所有的相同类型的包装类对象之间值的比较全部使用equals方法比较
说明 对于Integer var= ?在-128至127范围内的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象。这是一个大坑,推荐使用equals方法进行判断。
下面是一个例子:
上面传的是字符串,内部是字符串转数字生成对象,所以是两个不同的对象,下面是传数字,Integer有缓存,缓存大小是可以手动设置的。
(3) 什么叫自动装箱和拆箱?
装箱:将基本类型转换成包装类对象int i=10;Integer x=new Integer(i);
手动装箱Integer y=10;
自动装箱拆箱:将包装类对象转换成基本类型的值Integer j=new Integer(8);int m=j.intValue();//手动拆箱int n=j;//自动拆箱
二 、String
字面量,常量,变量的区别?
int a;//变量
int b=10;//常量,10为字面量
String str="hello";//str为变量,hello为字面量|
对象字面量就是引号引起来的部分,必须是等号右边的部分。虽然这样的解释不太好,但是确实如此,这就是字面量。
有些数据在程序运行中可以变化或者被赋值,这称为变量。
有些数据可以在程序使用之前预先设定并在整个运行过程中没有变化,这称为常量。
变量与常量的区别
它们在内存中的存储方式是一样的。只是常量不允许改变,就像只读文件一样。
变量、常量与字面量的区别
字面量是指由字母,数字等构成的字符串或者数值,它只能作为右值出现,(右值是指等号右边的值,如:int a=123这里的a为左值,123为右值。)
常量和变量都属于变量,只不过常量是赋过值后不能再改变的变量,而普通的变量可以再进行赋值操作。
在API中是这样描述:
String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。 字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。
String的成员变量
从源码看出String底层使用一个字符数组来维护的。
成员变量可以知道String类的值是final类型的,不能被改变的,所以只要一个值改变就会生成一个新的String类型对象,存储String数据也不一定从数组的第0个元素开始的,而是从offset所指的元素开始。
字符串常量池
在字符串中,如果采用直接赋值的方式(String str="Lance")进行对象的实例化,则会将匿名对象“Lance”放入对象池,每当下一次对不同的对象进行直接赋值的时候会直接利用池中原有的匿名对象,
这样,所有直接赋值的String对象,如果利用相同的“Lance”,则String对象==返回true;
创建字符串对象两种方式的区别
1.直接赋值方式创建对象是在方法区的常量池
String str="hello";//直接赋值的方式
2. 通过构造方法创建字符串对象是在堆内存
String str=new String("hello");//实例化的方式
总结:两种实例化方式的区别
(1)直接赋值(String str="hello"):只开辟一块内存空间,并且会自动入池,不会产生垃圾。
(2)构造方法(String str=new String("hello");):会开辟两块堆内存空间,其中一块堆内存会变成垃圾被系统回收,而且不能够自动入池,需要通过 Public String intern();方法进行手工入池。
在实际开发过程中不会采用构造方法进行字符串的实际化。
equals与==的区别?为什么要重写equals时也要重写hashcode()方法?
java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==),比较的是他们的值。 2.引用数据类型(类) 当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。; 对于复合数据类型之间进行equals比较,在没有重写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
为什么要重写equals?
两个对象hashcode值不同(不相等),但属性可能相同,这样我们需要一个方法来比较对象的属性值。
为什么要重写equals时也要重写hashcode()方法?
ashCode方法也是可以用来比较两个对象是否相等的。但是我们很少使用,应该说是很少直接使用。hashCode方法返回的是一个int值,可以看做是一个对象的唯一编码,如果两个对象的hashCode值相同,我们应该认为这两个对象是同一个对象。
一般如果使用java中的Map对象进行存储时,他会自动调用hashCode方法来比较两个对象是否相等。
所以如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。
1.重写equals方法时需要重写hashcode()方法,主要针对Map、Set集合使用;
a: Map、Set等集合类型存放的对象必须是唯一的;
b: 集合类判断两个对象是否相等,是先判断equals是否相等,如果equals返回TRUE,还要再判断HashCode返回值是否ture,只有两者都返回ture,才认为该两个对象是相等的。
即,map,set集合中存放的内容必须唯一,要剔除掉两个不同的对象但对象的属性值是相同的
2、由于Object的hashCode返回的是对象的hash值,所以即使equals返回TRUE,集合也可能判定两个对象不等,所以必须重写hashCode方法,以保证当equals返回TRUE时,hashCode也返回Ture,这样才能使得集合中存放的对象唯一。
String中常用的方法:
1. length():求字符串的长度
2.charAt(int index):取字符串中指定下标的一个元素
3. codePointAt(int index):index 处字符的代码点值String a=“abc”str1.codePointAt(0);//974.codePointBefore(int index):给定索引前一位的 Unicode 代码点
5..ToLower() //转为小写字符串"AbC"-->"abc"
6..ToUpper() //转为大写"AbC" -->"ABC"
7.Trim() //去掉字符串首尾的空格" abc "-->"abc"
8.Equals(string value,StringComparison comparisonType); //相等判断
9.CompareTo(string value) //与value比较大小.
10.Split(params char [] separator) //separator 是分隔字符,如:','、'|' 等
11.contains(字串):判断字串是否在原来的字符串中,如果存在则返回true,否则返回false
12.endsWith(字符串):判断是否以给定的字符串结尾
StringBuffer:
1.Stringbuffer对象的初始化:
1.不可以直接赋值
StringBuffer s = “abc”; //赋值类型不匹配
2.StringBuffer和String属于不同的类型,也不能直接进行强制类型转换
String s = “abc”;
StringBuffer sb1 = new StringBuffer(“123”);
StringBuffer sb2 = new StringBuffer(s); //String转换为StringBuffer
String s1 = sb1.toString(); //StringBuffer转换为String
3.StringBuffer的常用方法
StringBuffer类中的方法主要偏重于对于字符串的变化,例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。
a、append方法
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。
b、deleteCharAt方法
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。
c、insert方法
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。
d、reverse方法
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。
e、setCharAt方法
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
f、trimToSize方法
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。
String和StringBuffer的区别?
String类是字符串常量,是不可更改的常量。而StringBuffer是字符串变量,它的对象是可以扩充和修改的。String可以通过字符串连接符+或调用concat方法动态改变字符长度,但是会重新生成对象,效率不高。而StringBuffer内部使用了字符缓冲区,追加元素时,是直接操纵内部的缓冲区,不会改变StringBuffer对象本身,因此不会产生新的对象,效率略高。
StringBuilder:
StringBuilder和StringBuffer基本一致,但是StringBuiler是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
总结:String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
日期类:
一、Date类:在java.util包下,类 Date 表示特定的瞬间,精确到毫秒。从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和分析日期字符串。Date 中的相应方法已废弃。所以Date主要用来生成时间(是网上见解,我也是这样认为的)。
(1)Date有两个构造方法:
(1)Date():分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)。
(2)Date(long date)基本上没用不用记。
eg:Date date=new Date(); System.out.println(date);输出:Tue Jun 16 20:51:24 CST
(2)Date常用方法:
boolean after(Date when) 测试此日期是否在指定日期之后
boolean before(Date when) 测试此日期是否在指定日期之前
int compareTo(Date anotherDate) 比较两个日期的顺序
DateFormat类:
在java.text包下,DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。很多java培训的视频里面都讲过,这个类是抽象类,所以不能构造方法来实例化,可以用getDateInstance()和getDateTimeInstance()这两个静态函数来进行实例化。这两个的区别是一个返回的是日期,一个返回的是日期+时间.同时,getDateInstance(int style),getDateInstance(int style, Locale aLocale)等方法也挺好用的。关于style值:
FULL: 长度最长 比如:2013年1月9日 星期三 LONG: 长度更长 比如:January 9, 2013
MEDIUM:长度比SHORT长 比如:Jan 9,2013 SHORT: 完全为数字,比如:13/1/9
eg:DateFormat d1=DateFormat.getDateInstance();
SimpleDateFormat类
在java.text包下,它是DateFormat类的直接子类,继承DateFormat类。我是这么理解SimpleDateFormat类的,它相对于Datef类更接地气,你可以随意给他指定一个形式的日期,进行更改。SimpleDateFormat类主要功能是完成日期之间格式的转换,而且在转换过程中需要采用如下步骤:1.指定一个模板,并根据这个模板,取出第一个所有的时间数字。2.所有的时间数字将采用Date类保存。3.将所有的时间数字重新进行格式转换。模板如下表,注意区分大小写
日期 | 模板 | 描述 |
年 | Y | 表示年:yyyy |
月 | M | 表示月:MM |
日 | d | 表示日:dd |
时 | HH | 表示时:HH |
分 | mm | 表示分:mm |
秒 | ss | 表示秒:ss |
毫秒 | S | 毫秒:SSS |
二、Calendar类:
在java.util包下,Calendar 类是一个抽象类,它为“特定瞬间”与一组诸如 “YEAR”、
“MONTH”、“DAY_OF_MONTH”、“HOUR ”等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
Calendar实例化有两种方式,第一种是 Calendar nowTime = new GregorianCalendar();,
第二种是Calendar calendar=Calendar.getInstance();
eg:Calendar c=Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR)+"年"+(c.get(Calendar.MONTH)+1)+"月"+
c.get(Calendar.DATE)+"日"+c.get(Calendar.HOUR)+"点"); // 输出:2015年6月16日9点
常用的方法:
add(int date,int num);//返回num前后的日期//date表示日期字段,num表示添加的天数;
get(int date);//通过获取字段,返回具体的信息;