JAVA基础03-Object类,常用类,基本的数据结构, Collection常用体系,泛型-泛型通配符
1.object類(lèi)
1.概述
java.lang.object類(lèi)是java語(yǔ)言中的根類(lèi),即所有類(lèi)的超類(lèi)(基類(lèi))他描述的所有的方法子類(lèi)都可以使用,在對(duì)象實(shí)例化的時(shí)候最終找到的類(lèi)就是object
如果一個(gè)類(lèi)沒(méi)有特別指定父類(lèi),那么默認(rèn)則繼承自object類(lèi)例如
public class Test01 /*extends object*/ {}object 類(lèi)當(dāng)中包含方法有11個(gè)
- public String tostring(); 返回該對(duì)象的字符串表示
- public boolean equals(Object obj):指示其他某個(gè)實(shí)例,是否與此實(shí)例相等
2.toString方法
1.摘要
介紹:
toString方法返回該對(duì)象的字符串表示, 其實(shí)該字符串內(nèi)容就是對(duì)象的類(lèi)型+@+內(nèi)存地址值.
由于toString方法返回的結(jié)果是內(nèi)存地址, 我們經(jīng)常按照對(duì)象的屬性得到相應(yīng)的字符串表現(xiàn)形式, 因此我們需要重寫(xiě)他.
2.覆蓋重寫(xiě)
如果不希望使用toString方法的默認(rèn)行為則可以對(duì)它進(jìn)行重寫(xiě) , 例:
public class Person {String name;int age;@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';} }3.equals方法
1.摘要
equals() 方法, 判斷其他某個(gè)對(duì)象是否和子對(duì)象相等.
調(diào)用成員方法equals并指定參數(shù)為另一個(gè)對(duì)象,則可以判斷這兩個(gè)對(duì)象是否是相同的
如果沒(méi)有覆蓋重寫(xiě)equals 方法, 那么Object類(lèi)中默認(rèn)進(jìn)行== 運(yùn)算符的對(duì)象進(jìn)行比較, 只要不是同一個(gè)對(duì)象結(jié)果必為false.
如果希望進(jìn)行對(duì)象的內(nèi)容比較, 所有或者指定的部分成員變量相同就判定兩個(gè)對(duì)象相同, 則可以重寫(xiě)equals方法
public class Person {String name;int age;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age &&Objects.equals(name, person.name);} }4.Object類(lèi)
在jdk7 中添加了一個(gè)Object工具類(lèi), 他提供了一些方法來(lái)操作對(duì)象, 他由一些靜態(tài)的實(shí)例方法組成, 這些方法是null-save(空指針安全的)或者null-tolerant(容忍空指針的),用于計(jì)算對(duì)象的hashcode,返回對(duì)象的字符串表示形式, 計(jì)較兩個(gè)對(duì)象.
-
public static boolean equals(Object o , Object b ) 判斷兩個(gè)對(duì)象是否相等,
-
源碼
public static boolean equals(Object a, Object b) {return (a == b) || (a != null && a.equals(b));}
2.常用類(lèi)
1.System類(lèi)
java.lang.System類(lèi)中提供了大量的靜態(tài)方法,可以獲取與系統(tǒng)香瓜你的信息或系統(tǒng)級(jí)操作, 在System類(lèi)的API文檔中常用的方法有:
- public static long currentTimeMillis():返回以毫秒為單位的當(dāng)前時(shí)間.
- public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):將數(shù)組中指定的數(shù)據(jù)拷貝到另一個(gè)數(shù)組中
1.1,currentTimeMillis 方法
currentTimeMillis 方法就是獲取當(dāng)前系統(tǒng)時(shí)間與1970年01月01日00:00點(diǎn)之間的毫秒差值
public static void main(String[] args) {long l = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {System.out.println(i);}long l1 = System.currentTimeMillis();System.out.println("耗時(shí):"+(l1-l)); //耗時(shí):256 毫秒}1.2.arraycopy方法
將數(shù)組中的指定數(shù)據(jù)拷貝到另一個(gè)數(shù)組中,
數(shù)組的拷貝動(dòng)作是系統(tǒng)級(jí)的, 性能很高,其中有五個(gè)參數(shù):
參數(shù)名稱(chēng) 參數(shù)類(lèi)型 參數(shù)含義
src Object 原數(shù)組
srcPos int 原數(shù)組索引其起始位置
dest Object 目標(biāo)數(shù)組
destPos int 目標(biāo)數(shù)組索引起始位置
length int 復(fù)制元素的個(gè)數(shù)
2.StringBuilder類(lèi)
2.1 字符串拼接問(wèn)題
由于strign類(lèi)的對(duì)象內(nèi)容是不可變的,所以每當(dāng)進(jìn)行字符串拼接時(shí),總是會(huì)在內(nèi)存中創(chuàng)建一個(gè)新的對(duì)象:例如
public static void main(String[] args) {String str01 = "Hello";System.out.println(str01.hashCode());//69609650str01 += "world";System.out.println(str01.hashCode());//468881952System.out.println(str01);//Helloworld}在api中對(duì)string類(lèi)的描述是:java中所有的自付出那蚊子(例如:“abc”)都被時(shí)限為此實(shí)例.字符后才能不變,他們的值在創(chuàng)建后不能被更改,字符串緩沖區(qū)支持可變字符串, 因?yàn)镾tring對(duì)象是不可能變得 ,他們可以被共享.
上面代碼可以用下圖表示:
由圖片可知, 如果對(duì)字符串進(jìn)行拼接操作,每次拼接都會(huì)在內(nèi)存中開(kāi)辟空間,創(chuàng)建一個(gè)新的string對(duì)象, 既耗時(shí)又消耗空間,為了解決這種問(wèn)題, 可以使用java.lang.StringBuilder類(lèi)
2.2 StringBuilder
javaAPI:StringBulider又稱(chēng)為可變字符序列, 他是一個(gè)類(lèi)似String的字符串緩沖區(qū), 通過(guò)某些方法調(diào)用可以改變?cè)撔蛄械拈L(zhǎng)度和內(nèi)容,
StringBuilder相當(dāng)于一個(gè)容器, 可以裝很多的字符串, 并且能夠?qū)ψ址M(jìn)行相應(yīng)的操作,它的內(nèi)部擁有一個(gè)數(shù)組來(lái)存放字符字符串內(nèi)容, 進(jìn)行字符串拼接時(shí), 直接在數(shù)組中插入新的內(nèi)容,StringBuilder會(huì)自動(dòng)維護(hù)數(shù)組的擴(kuò)容,
2.2.1構(gòu)造方法
常用的構(gòu)造方法有兩個(gè):
- public StringBuilder():構(gòu)造一個(gè)空的StirngBuilder容器.
- public StringBulider(String str):構(gòu)造一個(gè)空的StirngBuilder容器,并將字符串添加進(jìn)去
2.2.2 常用方法
StringBuilder常用方法有兩個(gè):
-
public StringBuilder append():添加任意類(lèi)型數(shù)據(jù)的字符串形式,并返回當(dāng)前對(duì)象自身.
-
public StringBulider toString(): 將當(dāng)前StringBuilder 對(duì)象轉(zhuǎn)換為String對(duì)象.
public static void main(String[] args) {
//創(chuàng)建對(duì)象
StringBuilder stringBuilder = new StringBuilder();
//添加任意類(lèi)型數(shù)據(jù)
stringBuilder.append(“hello”);
System.out.println(stringBuilder.hashCode());//1163157884
stringBuilder.append(“world”);
System.out.println(stringBuilder.hashCode());//1163157884
stringBuilder.append(1);
stringBuilder.append(true);
stringBuilder.append(1.1f);
System.out.println(stringBuilder.toString());
//上面寫(xiě)法可以寫(xiě)成
System.out.println(stringBuilder.append(“hello”).append(“world”).append(1).append(true).append(1.1f).toString());
}
3.包裝類(lèi)
3.1 概述
java的數(shù)據(jù)類(lèi)型基本有兩種, 基本類(lèi)型與引用類(lèi)型, 基本類(lèi)型的話(huà)效率比較高 , 但是我們一般會(huì)使用引用類(lèi)型, 這樣我們創(chuàng)建對(duì)象可以進(jìn)行更多的操作, 我們也可以把基本類(lèi)型轉(zhuǎn)換成引用類(lèi)型, 就可以使用基本類(lèi)型的包裝類(lèi);
基本類(lèi)型 對(duì)應(yīng)包裝類(lèi) java.lang包中
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
3.2 拆箱與裝箱
基本類(lèi)型與引用類(lèi)型之間轉(zhuǎn)換的過(guò)程,我們稱(chēng)之為"裝箱"與"拆箱"
- 裝箱 :從基本類(lèi)型轉(zhuǎn)換為引用類(lèi)型
- 拆箱 :從引用類(lèi)型轉(zhuǎn)換為基本類(lèi)型.
基本類(lèi)型->包裝類(lèi);
Integer i = new Integer(4);//使用構(gòu)造器方法 Integer i1 = Integer.valueOf(4);//使用包裝類(lèi)的valueOf() 方法包裝類(lèi)->基本類(lèi)型
int i2 = i.intvalue();因?yàn)槲覀兤綍r(shí)經(jīng)常基本類(lèi)型與包裝類(lèi)之間轉(zhuǎn)換 ,從 jkd1.5開(kāi)始, 基本類(lèi)型與包裝類(lèi)之間不用手動(dòng)進(jìn)行拆裝箱, 可以自動(dòng)完成
Integer i = 8 ; int a = i + 8;4.基本類(lèi)型與字符轉(zhuǎn)之間的轉(zhuǎn)換
4.1 基本類(lèi)型轉(zhuǎn)換為引用類(lèi)型;
有三種方式:
4.2 String 類(lèi)型轉(zhuǎn)換為基本類(lèi)型
除了Character 類(lèi)之外, 其他所有的包裝類(lèi)都具有parseXxx 靜態(tài)方法可以將字符串轉(zhuǎn)換為基本數(shù)據(jù)類(lèi)型;
- public static byte parseByte(String s ) :將字符串轉(zhuǎn)換為對(duì)應(yīng)的byte類(lèi)型
- public static short parseShort(String s ):將字符串轉(zhuǎn)換為對(duì)應(yīng)的 shord 類(lèi)型
- public static int parseInt(String s ):將字符串轉(zhuǎn)換為對(duì)應(yīng)的int 類(lèi)型
- public static long parseLong(String s ):將字符串轉(zhuǎn)換為對(duì)應(yīng)的 long 類(lèi)型
- public static float parseFloat(Stirng s):將字符串轉(zhuǎn)換為對(duì)應(yīng)的 float 類(lèi)型
- public static double parseDouble (String s);將字符串轉(zhuǎn)換為對(duì)應(yīng)的 double 類(lèi)型
- public static boolean parseDoolean (String s ):將字符串轉(zhuǎn)換為對(duì)應(yīng)的 boolean 類(lèi)型
//舉個(gè)例子:
public static void main(String[] args) {
String s = “true00000”;
boolean b = Boolean.parseBoolean(s);
System.out.println(b);//false
if (b) {
System.out.println(“222”);
}
String s1 = “12324”;
int i = Integer.parseInt(s1);
System.out.println(i);//12324
}
如果無(wú)法正確轉(zhuǎn)換 會(huì)拋出
java.lang.NumberFormatException.異常
5.日期時(shí)間類(lèi)
5.1 Date類(lèi)
5.1.1 概述
java.util.Date 類(lèi) 表示指定的瞬間,精確到毫秒
jdk文檔 介紹:一個(gè)大約一毫秒值的薄包裝,允許JDBC將其標(biāo)識(shí)為SQL DATE值。 毫秒值表示1970年1月1日00:00:00.000 GMT之后的毫秒數(shù)。
為了符合SQL DATE ,由java.sql.Date實(shí)例包裝的毫秒值必須通過(guò)在實(shí)例關(guān)聯(lián)的特定時(shí)區(qū)中將小時(shí),分鐘,秒和毫秒設(shè)置為零來(lái)“歸一化”。
構(gòu)造方法 : 例
Date(int year, int month, int day) 已棄用 而是使用構(gòu)造Date(long date)
Date(long date) 使用給定的毫秒時(shí)間值構(gòu)造一個(gè) Date對(duì)象。
Date 擁有多個(gè)構(gòu)造方法, 只是大部分已經(jīng)過(guò)時(shí), 但是其中有未過(guò)時(shí)的函數(shù)可以吧毫秒值轉(zhuǎn)換成日期
- public Date():分配Date對(duì)象并初始化此對(duì)象, 以表示分配他的時(shí)間(精確到毫秒)
- public Date(long date):分配Date對(duì)象并初始化此對(duì)象, 以表示自從標(biāo)準(zhǔn)時(shí)間(成為"歷元(epoch)", 即使1970年01月01日00:00:00 GMT) 以來(lái)的毫秒數(shù).
tips: 由于中國(guó)處于東八區(qū)(GMT+08:00)是比世界協(xié)調(diào)時(shí)間/格林尼治時(shí)間(GMT)快8小時(shí)的時(shí)區(qū),當(dāng)格林尼治標(biāo)準(zhǔn)時(shí)間為0:00時(shí),東八區(qū)的標(biāo)準(zhǔn)時(shí)間為08:00。
使用無(wú)參構(gòu)造器,可以自動(dòng)設(shè)置當(dāng)前系統(tǒng)時(shí)間的毫秒時(shí)刻; 指定long類(lèi)型的構(gòu)造參數(shù), 可以定義毫秒時(shí)刻,例如:
public static void main(String[] args) {System.out.println(new Date());//Mon Jun 29 16:06:19 CST 2020System.out.println(new Date(0L));//Thu Jan 01 08:00:00 CST 1970 }//在使用println方法時(shí),會(huì)自動(dòng)調(diào)用Date類(lèi)中的toString方法。Date類(lèi)對(duì)Object類(lèi)中的toString方法進(jìn)行 //了覆蓋重寫(xiě),所以結(jié)果為指定格式的字符串。5.1.2 常用方法
Date類(lèi)中有很多方法已經(jīng)過(guò)時(shí), 常用的方法有:
- public long getTime(): 把日期對(duì)象轉(zhuǎn)換成對(duì)象的時(shí)間毫秒值
5.2 DateFormat類(lèi)
java.text.DateFormat: 是日期/時(shí)間格式化子類(lèi)的抽象類(lèi),我們通過(guò)這個(gè)類(lèi)可以幫我們完成日期和文本之間的轉(zhuǎn)換,也就是可以在Date對(duì)象與String對(duì)象之間進(jìn)行來(lái)回轉(zhuǎn)換。
- 格式化: 按照指定的格式, 從Date對(duì)象轉(zhuǎn)換為String對(duì)象.
- 解析: 按照指定的格式,從String 轉(zhuǎn)換成Date對(duì)象.
5.2.1 構(gòu)造方法
由于DataFormat 為抽象類(lèi) , 不能被實(shí)例化, 所以我們經(jīng)常使用他的子類(lèi),java.text.SimpleDateFormat:這個(gè)類(lèi)需要一個(gè)格式來(lái)指定格式化或解析的標(biāo)準(zhǔn), 構(gòu)造方法為:
- public SimpleDateFormat(String pattern):用于給定的模式和默認(rèn)語(yǔ)言環(huán)境的日期格式符號(hào)構(gòu)造SimpleDateFormat.參數(shù)patterm 是一個(gè)字符串, 代表日期時(shí)間的定義格式;
5.2.2 格式規(guī)則
表示字母(區(qū)分大小寫(xiě)) 含義 例子
Y
y 年 1997;07
M 月 7月;8月
m 分
D
d 日
H 時(shí)
h
S
s 秒
W
w
K
k
Z
z
F
E
G 文本 AD
X
L
a
u
具體介紹參考JDK文檔
5.2.3 常用方法
DateFormat類(lèi)的常用方法有:
-
public String format(Date date):將Date對(duì)象格式化為字符串;
-
public Date parse(String source):將字符串轉(zhuǎn)換為Date 對(duì)象;
public static void main(String[] args) throws ParseException {
//將當(dāng)前日期轉(zhuǎn)換為字符串
SimpleDateFormat sl = new SimpleDateFormat(“yyyy-MM-dd”);
String format = sl.format(new Date());
System.out.println(format);
//將當(dāng)前時(shí)間轉(zhuǎn)換為日期類(lèi)型
SimpleDateFormat sl1 = new SimpleDateFormat(“yyyyMMddhhmmss");
Date parse = sl1.parse("19971130231032”);
//將日期類(lèi)型轉(zhuǎn)化為Stirng
String format1 = sl1.format(parse);
System.out.println(format1);
}
5.3Calender類(lèi)
5.3.1概念
java.util.Calendar 是日歷類(lèi), 在Date之后出現(xiàn), 替換掉許多Date的方法, 該類(lèi)將所有可能用到的時(shí)間信息封裝為靜態(tài)成員變量,日歷類(lèi)就是方便獲取各個(gè)時(shí)間屬性的.
5.3.2 獲取方式
Calendar 為抽象類(lèi), 不能直接創(chuàng)建, 而是通過(guò)靜態(tài)方法創(chuàng)建,返回子類(lèi)對(duì)象
Calendar 靜態(tài)方法
-
public static Calendar getInstance():使用默認(rèn)失去和語(yǔ)言環(huán)境獲得一個(gè)日歷
Calendar calendar = Calendar.getInstance();
5.3.3 常用方法
常用的方法有:
- public int get(int field):返回給定日期字段的值;
- public void set (int field , int value):將制定的日期字段設(shè)置為給定值.
- public abstract void add(int field , int amount):根據(jù)日歷的規(guī)則, 為給定的日歷字段添加或減去指定的時(shí)間量.
- public Date getTime():返回一個(gè)標(biāo)識(shí)此Calendar 時(shí)間值(從歷元到現(xiàn)在的毫秒的偏移量)的Date對(duì)象.
Calendar類(lèi)中提供很多成員常量, 代表給定的日期字段:
常用:
字段值 含義
YEAR 年
MONTH 月(從0開(kāi)始,可以+1使用)
DAY_OF_MONTH 用中的第幾天(幾號(hào))
HOUR 時(shí)(12小時(shí))
HOUR_OF_DAY 時(shí)(24小時(shí))
MINUTE 分
SECOND 秒
DAY_OF_WEEK 周中的天(周幾,周日為1, 可以用-1使用)
JDK提供:
Modifier and Type Field and Description
static int ALL_STYLES getDisplayNames的樣式說(shuō)明符, 表示所有樣式的名稱(chēng),如“1月”和“1月”。
static int AM AM_PM字段的值表示從午夜到中午之前的一天中的一段時(shí)間。
static int AM_PM 對(duì)于現(xiàn)場(chǎng)數(shù) get和 set指示是否 HOUR是前或中午之后。
static int APRIL MONTH字段的價(jià)值 指示了格里高利和朱利安日歷中的第四個(gè)月。
protected boolean areFieldsSet 如果 fields[]與當(dāng)前設(shè)置的時(shí)間同步,則為真。
static int AUGUST MONTH領(lǐng)域的價(jià)值 指示了公歷和朱利安日歷中的第八個(gè)月。
static int DATE get和 set字段編號(hào)表示該月的日期。
static int DAY_OF_MONTH get字段編號(hào)和 set本月的日期。
static int DAY_OF_WEEK get字段編號(hào)和 set表示一周中的日期。
static int DAY_OF_WEEK_IN_MONTH get字段編號(hào)和 set當(dāng)月的 set幾的序號(hào)。
static int DAY_OF_YEAR get和 set字段編號(hào), set本年度的日數(shù)。
static int DECEMBER MONTH字段的值表示公歷和朱利安日歷中的第十二個(gè)月。
static int DST_OFFSET get和 set字段編號(hào) get夏令時(shí)偏移量(以毫秒為單位)。
static int ERA get和 set字段號(hào)表示時(shí)代,例如在儒略歷中的AD或BC。
static int FEBRUARY MONTH字段的價(jià)值表示今年第二個(gè)月在公歷和朱利安日歷。
static int FIELD_COUNT get和 set的不同字段的數(shù)量。
protected int[] fields 該日歷的當(dāng)前設(shè)置時(shí)間的日歷字段值。
static int FRIDAY DAY_OF_WEEK字段的值表示周五。
static int HOUR get和 set字段編號(hào), get上午或下午的小時(shí)。
static int HOUR_OF_DAY get字段編號(hào)和 set當(dāng)天的小時(shí)數(shù)。
protected boolean[] isSet 說(shuō)明是否設(shè)置日歷的指定日歷字段的標(biāo)志。
protected boolean isTimeSet 如果那么那么 time的值是有效的。
static int JANUARY MONTH字段的價(jià)值表示今年首次在公歷和朱利安日歷。
static int JULY MONTH字段的值代表了 公歷和朱利安日歷中的第七個(gè)月。
static int JUNE MONTH字段的價(jià)值 指示了公歷和朱利安日歷中的第六個(gè)月。
static int LONG getDisplayName和 getDisplayNames相當(dāng)于 LONG_FORMAT的樣式說(shuō)明 符 。
static int LONG_FORMAT getDisplayName和 getDisplayNames的樣式說(shuō)明 符 , 表示用于格式的長(zhǎng)名稱(chēng)。
static int LONG_STANDALONE 一個(gè) getDisplayName和 getDisplayNames的樣式說(shuō)明 符 , 表示一個(gè)獨(dú)立使用的長(zhǎng)名稱(chēng),例如月份名稱(chēng)作為日歷頭。
static int MARCH MONTH字段的值代表了 公歷和朱利安日歷中的第三個(gè)月。
static int MAY MONTH領(lǐng)域的價(jià)值 指示了公歷和朱利安日歷中的第五個(gè)月。
static int MILLISECOND get和 set字段號(hào)表示 get內(nèi)的 set數(shù)。
static int MINUTE get和 set字段編號(hào)表示小時(shí)內(nèi)的分鐘。
static int MONDAY DAY_OF_WEEK字段的值表示星期一。
static int MONTH get和 set字段號(hào)表示月份。
static int NARROW_FORMAT getDisplayName和 getDisplayNames的樣式說(shuō)明 符 , 表示用于格式的窄名稱(chēng)。
static int NARROW_STANDALONE getDisplayName和 getDisplayNames的樣式說(shuō)明 符 獨(dú)立地表示一個(gè)狹義的名稱(chēng)。
static int NOVEMBER MONTH領(lǐng)域的價(jià)值 指示了公歷和朱利安日歷中的第十一個(gè)月。
static int OCTOBER MONTH字段的價(jià)值表示在公歷和朱利安日歷中的一年中的第十個(gè)月。
static int PM AM_PM字段的值表示從中午到午夜之前的一天中的一段時(shí)間。
static int SATURDAY DAY_OF_WEEK字段的值表示星期六。
static int SECOND get和 set字段編號(hào)表示分鐘內(nèi)的第二個(gè)。
static int SEPTEMBER MONTH字段的值代表了 公歷和朱利安日歷中的第九個(gè)月。
static int SHORT getDisplayName和 getDisplayNames的樣式說(shuō)明 符 , 相當(dāng)于 SHORT_FORMAT 。
static int SHORT_FORMAT getDisplayName和 getDisplayNames的樣式說(shuō)明 符 , 表示用于格式的短名稱(chēng)。
static int SHORT_STANDALONE 一個(gè)用于 getDisplayName和 getDisplayNames的樣式說(shuō)明 符 , 表示一個(gè)簡(jiǎn)單的名稱(chēng),例如一個(gè)月縮寫(xiě)作為日歷頭。
static int SUNDAY DAY_OF_WEEK字段的值表示星期天。
static int THURSDAY DAY_OF_WEEK字段的值表示星期四。
protected long time 這個(gè)日歷的當(dāng)前設(shè)定時(shí)間,以1970年1月1日,格林尼治標(biāo)準(zhǔn)時(shí)間0:00:00之后的毫秒表示。
static int TUESDAY DAY_OF_WEEK字段的值表示周二。
static int UNDECIMBER MONTH字段的值表示一年的第十三個(gè)月。
static int WEDNESDAY DAY_OF_WEEK字段的值表示周三。
static int WEEK_OF_MONTH get和 set字段編號(hào), set當(dāng)月的周數(shù)。
static int WEEK_OF_YEAR get和 set字段編號(hào), set本年度的周數(shù)。
static int YEAR get現(xiàn)場(chǎng)編號(hào)和 set表示年份。
static int ZONE_OFFSET get和 set字段編號(hào), get GMT以毫秒為 get的原始偏移量。
西方星期的開(kāi)始為周日,中國(guó)為周一。
在Calendar類(lèi)中,月份的表示是以0-11代表1-12月。
日期是有大小關(guān)系的,時(shí)間靠后,時(shí)間越大。
6.BigDecimal類(lèi)
6.1BigDecimal 類(lèi)概述
java.math.BigDecimal類(lèi): 他可以標(biāo)識(shí)一個(gè)不可變的, 任意精度的有符號(hào)10進(jìn)制數(shù),同時(shí)他也提供了對(duì)這種數(shù)據(jù)運(yùn)算的一些方法, 以及各種舍入模式, 它尤其可以避免基本數(shù)據(jù)類(lèi)型進(jìn)行浮點(diǎn)運(yùn)算時(shí)損失精度的問(wèn)題,
public static void main(String[] args) {float f1 = 0.1f;double f2 = 0.05;System.out.println(f1+f2);//0.1500000014901161}6.2 BigDecimal 使用
- 構(gòu)造方法:
- public BigDecimal(Double d):將double 轉(zhuǎn)換成BigDecimal [不建議]
- public BigDecimal(String s):將String 轉(zhuǎn)換為BigDecimal [建議]
- BigDecimal(BigInteger val) 將 BigInteger轉(zhuǎn)換成 BigDecimal 。
BigDecimal(BigInteger unscaledVal, int scale) 將BigInteger的 BigInteger值和 int等級(jí)轉(zhuǎn)換為 BigDecimal 。
BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) 將 BigInteger未縮放值和 int擴(kuò)展轉(zhuǎn)換為 BigDecimal ,根據(jù)上下文設(shè)置進(jìn)行舍入。
BigDecimal(BigInteger val, MathContext mc) 根據(jù)上下文設(shè)置將 BigInteger轉(zhuǎn)換為 BigDecimal舍入。
BigDecimal(char[] in) 一個(gè)轉(zhuǎn)換的字符數(shù)組表示 BigDecimal成 BigDecimal ,接受字符作為的相同序列 BigDecimal(String)構(gòu)造。
BigDecimal(char[] in, int offset, int len) 一個(gè)轉(zhuǎn)換的字符數(shù)組表示 BigDecimal成 BigDecimal ,接受字符作為的相同序列 BigDecimal(String)構(gòu)造,同時(shí)允許一個(gè)子陣列被指定。
BigDecimal(char[] in, int offset, int len, MathContext mc) 一個(gè)轉(zhuǎn)換的字符數(shù)組表示 BigDecimal成 BigDecimal ,接受字符作為的相同序列 BigDecimal(String)構(gòu)造,同時(shí)允許指定一個(gè)子陣列和用根據(jù)上下文設(shè)置進(jìn)行舍入。
BigDecimal(char[] in, MathContext mc) 一個(gè)轉(zhuǎn)換的字符數(shù)組表示 BigDecimal成 BigDecimal ,接受相同的字符序列作為 BigDecimal(String)構(gòu)造與根據(jù)上下文設(shè)置進(jìn)行舍入。
BigDecimal(double val) 將 double轉(zhuǎn)換為 BigDecimal ,這是 double的二進(jìn)制浮點(diǎn)值的精確十進(jìn)制表示。
BigDecimal(double val, MathContext mc) 將 double轉(zhuǎn)換為 BigDecimal ,根據(jù)上下文設(shè)置進(jìn)行舍入。
BigDecimal(int val) 將 int成 BigDecimal 。
BigDecimal(int val, MathContext mc) 將 int轉(zhuǎn)換為 BigDecimal ,根據(jù)上下文設(shè)置進(jìn)行舍入。
BigDecimal(long val) 將 long成 BigDecimal 。
BigDecimal(long val, MathContext mc) 將 long轉(zhuǎn)換為 BigDecimal ,根據(jù)上下文設(shè)置進(jìn)行舍入。
BigDecimal(String val) 將BigDecimal的字符串表示 BigDecimal轉(zhuǎn)換為 BigDecimal 。
BigDecimal(String val, MathContext mc) 一個(gè)轉(zhuǎn)換的字符串表示 BigDecimal成 BigDecimal ,接受相同的字符串作為 BigDecimal(String)構(gòu)造,利用根據(jù)上下文設(shè)置進(jìn)行舍入。 - 常用方法:
- public BigDecimal add(BigDecimal augend):與參數(shù)相加.
- public BigDecimal subract(BigDecimal subtranhend):與參數(shù)相減;
- public BigDecimal multiply(BigDecimal multiplicand):與參數(shù)相乘
- public BigDecimal divide(BigDecimal divisor): 與參數(shù)做除法, 除不盡會(huì)拋出異常
- `public BigDecimal divide(BigDecimal divisor, int scale ,int roundingMode):與參數(shù)做除法;
-
參數(shù)1:除數(shù);
-
參數(shù)2:小數(shù)點(diǎn)后保留的位數(shù);
-
參數(shù)2:舍入模式;
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal(“1000”);
BigDecimal bd2= new BigDecimal(“3”);
System.out.println(bd1.add(bd2));//加法
System.out.println(bd1.subtract(bd2));//減法
System.out.println(bd1.multiply(bd2));//乘法
//bd3/bd4 保留五位小數(shù),2舍 3入
BigDecimal divide = bd1.divide(bd2, 5, 2);
System.out.println(divide);
}
-
3.常見(jiàn)數(shù)據(jù)結(jié)構(gòu)
3.1數(shù)據(jù)結(jié)構(gòu)介紹
數(shù)據(jù)結(jié)構(gòu)的含義即是 : 數(shù)據(jù)用什么樣的方式排列在一起
3.2常見(jiàn)數(shù)據(jù)結(jié)構(gòu)
常用的數(shù)據(jù)結(jié)構(gòu)分為: 棧, 隊(duì)列, 數(shù)組, 鏈表, 紅黑樹(shù), 其余不一一列舉
3.2.1 棧
- 棧(stack): 又稱(chēng)為堆棧 ,他是運(yùn)算受限的線(xiàn)性代表, 其限制是僅允許在標(biāo)的一端進(jìn)行插入和刪除操作,不允許在其他任何位置進(jìn)行添加,查找, 刪除等操作.
采用該結(jié)構(gòu)的集合, 對(duì)元素的存取有一下特點(diǎn)
- 先進(jìn)后出: 存進(jìn)去的元素,要在他后面的元素依次取出后, 才能取出該元素.就好比子彈夾,往里面壓入子彈, 射擊的時(shí)候最上面的先擊發(fā);
- 棧的入口和出口都是在棧的最頂端位置
- 壓棧 : 就是存入元素, 即把元素存儲(chǔ)到棧的頂端位置, 棧中已有元素依次向棧底移動(dòng)一個(gè)位置.
- 彈棧: 就是取出元素,即把棧的頂端位置元素取出, 棧中已有元素依次向棧的頂端移動(dòng)一個(gè)位置.
3.2.2 隊(duì)列
- 隊(duì)列(queue) ,簡(jiǎn)稱(chēng)隊(duì), 他從堆棧一樣, 也是一種運(yùn)算受限的線(xiàn)性表, 其限制是僅允許在表的一端進(jìn)行插入, 而在表的另一端進(jìn)行刪除.
采用該結(jié)構(gòu)的集合,對(duì)元素的存取有如下特點(diǎn):
- 先進(jìn)先出:存進(jìn)去的元素,要在他的前面的元素依次取出后, 他能求出該元素; 比如顯示生活中的隧道;
- 隊(duì)列的入口出口,各占一半,
3.2.3 數(shù)組
- 數(shù)組(array) 是有序的元素序列, 數(shù)組是在內(nèi)存中開(kāi)辟一端連續(xù)的空間, 并在此空間存放元素; 酒店,每個(gè)房間都有房間號(hào);可以根據(jù)房間號(hào)查看每個(gè)房間是否有客人;
采用該結(jié)構(gòu)的集合,對(duì)元素有一下特點(diǎn)
- 查找元素快: 通過(guò)索引,可以快速訪(fǎng)問(wèn)指定位置的元素
- 增刪元素比較慢 :
-
指定索引位置增加元素: 需要?jiǎng)?chuàng)建一個(gè)新數(shù)組,將指定新元素存儲(chǔ)在指定索引位置 , 再把原數(shù)組根據(jù)索引,復(fù)制到新數(shù)組對(duì)應(yīng)的索引位置;
-
指定索引位置刪除元素: 需要?jiǎng)?chuàng)建一個(gè)新數(shù)組,把原數(shù)組元素根據(jù)索引,復(fù)制到新數(shù)組對(duì)應(yīng)索引的位置, 原數(shù)組中指定索引位置元素不復(fù)制到新數(shù)組,
-
3.2.4 鏈表
- 鏈表(linked list) , 由一些列節(jié)點(diǎn)node(鏈表中每一個(gè)元素成為一個(gè)節(jié)點(diǎn))組成, 節(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成,每個(gè)節(jié)點(diǎn)包括兩部分:一個(gè)時(shí)存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域, 另一個(gè)是存儲(chǔ)下一個(gè)節(jié)點(diǎn)地址的指針域.鏈表結(jié)構(gòu)有單向鏈表和雙向鏈表,
- 單向鏈表
采用該結(jié)構(gòu)的集合,對(duì)元素的存儲(chǔ)有一下特點(diǎn):
- 多個(gè)節(jié)點(diǎn)之間,通過(guò)地址進(jìn)行連接, 例如自行車(chē)鏈條
- 增刪元素比較快
3.2.5 紅黑樹(shù)
- 二叉樹(shù)(binary tree) , 是每個(gè)節(jié)點(diǎn)不超過(guò)2的有序樹(shù)(tree).
就是類(lèi)似于我們現(xiàn)實(shí)中的數(shù)目結(jié)構(gòu), 只不過(guò)每個(gè)樹(shù)枝最多有兩個(gè)叉, 頂上的叫根節(jié)點(diǎn), 兩邊被稱(chēng)為"左子樹(shù)" 和"右子樹(shù)"
紅黑樹(shù)本質(zhì)就是一顆二叉查找樹(shù),將節(jié)點(diǎn)插入后, 該樹(shù)仍然是一顆二叉查找樹(shù)
紅黑樹(shù)可以通過(guò)紅色節(jié)點(diǎn)和黑色節(jié)點(diǎn)盡可能的保證二叉樹(shù)的平衡, 從而提高效率, 查找速度恐怖!
具體什么是紅黑樹(shù), 是很大一門(mén)學(xué)問(wèn), 需要另起文章,一一講解;
4.Collection-集合框架
- 集合的概述:
- 集合: 集合使java中提供的一種容器, 可以用來(lái)存儲(chǔ)多個(gè)數(shù)據(jù).
- 集合與數(shù)組的區(qū)別:
- 數(shù)組長(zhǎng)度是固定的, 集合的長(zhǎng)度是可變的.
- 數(shù)組中存儲(chǔ)的是同一種元素, 可以存儲(chǔ)任意類(lèi)型的數(shù)據(jù), 集合中存儲(chǔ)的都是引用數(shù)據(jù)類(lèi)型,如果想存儲(chǔ)基本數(shù)據(jù)類(lèi)型需要存儲(chǔ)對(duì)應(yīng)的包裝類(lèi)
- 集合的繼承體系
Collection:單列集合的根接口,用于存儲(chǔ)一系列符合某種規(guī)則的元素, 他有兩個(gè)重要的子接口, 分別是java.util.List和java.util.Set其中, List的特點(diǎn)是有序,元素可重復(fù), Set的特點(diǎn)是元素不可重復(fù).List接口的主要實(shí)現(xiàn)類(lèi)有java.util.ArrayList和java.util.LinkedList,Set接口的主要實(shí)現(xiàn)類(lèi)有java.util.HashSet和’LinedHashSet.
上面這張圖包括我們經(jīng)常使用到的集合框,并不是說(shuō)僅僅只有這些
集合本身就是一個(gè)工具, 它存放在java.util包中,在Collection接口中定義了單例集合框架中共性的部分
- Collection 常用的功能;
Collection ,是所有單列集合的父接口, 因此在Collection 中定義了單列集合(List/Set)通用的一些方法, 這些方法可以用于操作所有的單列集合- public boolean add(E e): 把給定的對(duì)象添加到當(dāng)前集合中.
- public void clear():清空所有的元素.
- public boolean remove(E e) : 把給定的對(duì)象在當(dāng)前集合中刪除.
- public boolean contains(Object obj):判斷當(dāng)前集合中是否包含給定的對(duì)象.
- public boolean isEmpty(): 判斷當(dāng)前集合是否為空.
- public int size():返回當(dāng)前集合中元素的個(gè)數(shù).
- public Object[] toArray: 把集合中的元素,存儲(chǔ)到數(shù)組中
常用的方法基本就以上這么多,還有很多方法可以查看java API 文檔
Iterator 迭代器,增強(qiáng)for
- Iterator 接口
在程序開(kāi)發(fā)中,經(jīng)常需要遍歷集合中所有元素, 針對(duì)這種需求,JDK專(zhuān)門(mén)提供了一個(gè)接口
java.util.Iterator
想要遍歷Collection集合, 那么就要獲取該集合迭代器完成迭代操作,- pubic Iterator iterator():獲取集合對(duì)應(yīng)的迭代器, 用來(lái)遍歷集合中的元素的
- 迭代 : 即Collection 集合元素通用的獲取方式, 在取元素之前要先判斷集合里面有沒(méi)有元素, 如果有則取出來(lái),繼續(xù)判斷有的話(huà)再取出, 直到把集合中元素全部取出來(lái), 這種方式專(zhuān)業(yè)術(shù)語(yǔ)叫做迭代
- Iterator 接口的常用方法如下:
-
public E next() :返回迭代的下一個(gè)元素.
-
public boolean hasNext(): 如果有下一個(gè)元素可以迭代, 返回true.
public static void main(String[] args) {
ArrayList arr = new ArrayList<>();
arr.add(“test01”);
arr.add(“test02”);
arr.add(“test03”);
arr.add(“test04”);
//獲取集合的迭代器
Iterator iterator = arr.iterator();
//判斷是否有下一個(gè)元素
while (iterator.hasNext()) {
String next = iterator.next();
System.out.print(next+"\t");//test01 test02 test03 test04
}
}
-
PS:
在進(jìn)行集合元素獲取時(shí), 如果集合中已經(jīng)沒(méi)有元素了,還繼續(xù)調(diào)用迭代器的next() 方法, 將會(huì)拋出異常:java.util.NoSuchElementException 沒(méi)有元素異常.
在進(jìn)行集合元素獲取時(shí), 如果天劍或移除集合中的元素, 將無(wú)法繼續(xù)迭代,將會(huì)拋出
ConcurrentModificationException并發(fā)修改異常
-
迭代器的實(shí)現(xiàn)原理
當(dāng)遍歷集合時(shí),首先通過(guò)調(diào)用集合的iterator()方法獲取迭代器對(duì)象, 然后使用hasNest()方法判斷集合中是否有下一個(gè)元素,如果存在, 則調(diào)用next()方法取出,否則證明已經(jīng)全部取出, 停止循環(huán)遍歷
Iterator 迭代器對(duì)象在遍歷集合時(shí), 內(nèi)部采用指針的方式來(lái)跟蹤集合中的元素;在調(diào)用iterator 的next()方法之前,迭代器的索引位于第一個(gè)元素之前, 不指向任何元素, 當(dāng)?shù)谝淮握{(diào)用迭代器的next()方法之后,迭代器的索引為向后移動(dòng)一位, 指向第一個(gè)元素并返回, 以此類(lèi)推,知道hasNext()方法返回false; 終止遍歷
-
增強(qiáng)for
也稱(chēng)為foreach 循環(huán), 是jkd5之后, 出現(xiàn)的一個(gè)高級(jí)for循環(huán) , 主要用來(lái)遍歷元素,內(nèi)部其實(shí)是一個(gè)Iterator迭代器, 所以在遍歷的時(shí)候不能對(duì)元素進(jìn)行增刪操作;
格式:
for(元素類(lèi)型 變量名 : 集合或者數(shù)組)
{}
它用于遍歷Collection 和數(shù)組, 通常只進(jìn)行遍歷,不要在遍歷過(guò)程中對(duì)集合中的元素進(jìn)行增刪操作;
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 8};
for (int a : arr) {
System.out.print(a+"\t");//1 3 5 7 8
}
System.out.println();
ArrayList arrayList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
arrayList.add(i + “”);
}
for (String s : arrayList) {
System.out.print(s+"\t");
//0 1 2 3 4 5 6 7 8 9
}
}
PS:
foreach 循環(huán)必須有被遍歷的目標(biāo), 目標(biāo)只能是Collection 或者數(shù)組;
僅僅可以遍歷不能增刪元素否則會(huì)拋出ConcurrentModifcationException并發(fā)異常
4.1 List
4.1.1 List介紹
java.util.List接口實(shí)現(xiàn)Collection接口, 是單列結(jié)合的一個(gè)重要分支, 一般將實(shí)現(xiàn)List接口的對(duì)象成為L(zhǎng)ist集合, 在List集合中允許出現(xiàn)重復(fù)的元素, 所有的元素是以一種線(xiàn)性方式進(jìn)行存儲(chǔ)的, 在程序中可以通過(guò)索引來(lái)訪(fǎng)問(wèn)集合中指定的元素, List集合是有序的, 即元素的存入順序和取出順序一致
List接口特點(diǎn):
4.1.2 List 接口中常用方法
List作為Collection 子接口, 不但繼承了Collection 接口中的全部方法, 而且還增加了一些根據(jù)元素索引來(lái)操作集合的特有方法:
- public void add(int index ,E element):將指定的元素,添加到該集合中的指定位置上
- public E get(int index):返回集合中指定位置的元素.
- public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素.
- pubic E set(int index ,E element): 用指定的元素替換集合中指定位置的元素, 返回替換之前的元素
4.1.3 ArrayList 集合
java.util.ArrayList集合數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu)是數(shù)組結(jié)構(gòu), 元素增刪慢, 查找快, 因?yàn)槿粘2僮鞫际遣樵?xún)數(shù)據(jù),遍歷數(shù)據(jù),所以ArrayList 經(jīng)常使用;
4.1.4 LinkedList 集合
java.util.LinkedList 集合數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)是鏈表結(jié)構(gòu),方便元素添加,刪除的集合;
LinkList 是一個(gè)雙向鏈表結(jié)構(gòu)
LindedList 提供了大量首尾操作的方法:
- public void addFirst(E e): 將指定的元素插入此列表的開(kāi)頭
- public void addLast(E e):將指定的元素插入此列表的結(jié)尾
- public E getFirst():返回此列表開(kāi)頭第一個(gè)的元素
- public E getLast():返回此列表結(jié)尾最后一個(gè)元素
- public E removeFirst():移除并返回此列表的第一個(gè)元素
- public E removeLast(): 移除并返回此列表的最后一個(gè)元素
- public E pop():從此列表鎖表示的堆棧處彈出一個(gè)元素
- public void push(E e):將元素推入此列表所表示的堆棧.
- public boolean isEmpty():如果列表不包含元素則返回true.
LinkedList是List的子類(lèi), List中的方法LinkedList 中都可以使用 , LinkedList 可以被當(dāng)做堆棧, 隊(duì)列來(lái)使用;
public static void main(String[] args) {LinkedList<String> linkedList = new LinkedList<>();linkedList.add("str01");linkedList.add("str02");linkedList.add("str03");linkedList.add("str04");System.out.println(linkedList.toString());String first = linkedList.getFirst();System.out.println(first);String last = linkedList.getLast();System.out.println(last);String s = linkedList.removeFirst();System.out.println(s);String s1 = linkedList.removeLast();System.out.println(s1);System.out.println(linkedList.toString());linkedList.addFirst("str01");linkedList.addLast("str04");System.out.println("========================");System.out.println(linkedList.toString());boolean empty = linkedList.isEmpty();System.out.println(empty);System.out.println("========================");String pop = linkedList.pop();System.out.println(pop);System.out.println(linkedList.toString());linkedList.push("test999");System.out.println(linkedList.toString());/*[str01, str02, str03, str04]str01str04str01str04[str02, str03]========================[str01, str02, str03, str04]false========================str01[str02, str03, str04][test999, str02, str03, str04]*/}4.2 Set
java.util.Set接口和java.util.List接口一樣都是Collection的子接口與, 他與Collection 接口中的方法基本一致, 并沒(méi)有對(duì)Collection 接口進(jìn)行功能上的擴(kuò)充 , 只是比Collection接口更加的嚴(yán)格, 與List接口不同的是, Set 接口中的元素是無(wú)序的, 并且都會(huì)以某種規(guī)則保證存入的元素不出現(xiàn)重復(fù);Set集合有多個(gè)子類(lèi), 主要的兩個(gè)為java.util.hashSet,java.util.LinkedHashSet這兩個(gè)集合,
取出元素的方式可以采用: 迭代器, 增強(qiáng)for
4.2.1HashSet集合
java.util.HashSet 是Set接口的一個(gè)實(shí)現(xiàn)類(lèi), 他所存儲(chǔ)的元素是不可重復(fù)的, 并且元素都是無(wú)序的(存取順序無(wú)法保證)java.util.HashSet 底層是一個(gè)java.util.HashMap 支持,
HashSet 是根據(jù)對(duì)象的哈希值來(lái)確定元素在集合中的存儲(chǔ)位置, 因此查找性能比較好, 保證元素唯一性的方式采用 hashcode 和equals方法
public static void main(String[] args) {HashSet<String> hashSet = new HashSet<>();hashSet.add("str1");hashSet.add("str1");hashSet.add(new String("str1"));for (String s : hashSet) {System.out.println(s);}/** str1* str11* */}//不同對(duì)象, 數(shù)據(jù)相同也不會(huì)儲(chǔ)存4.2.2 HashSet集合存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)(哈希表)
哈希表是什么?
在jkd1.8之前, 哈希表底層采用數(shù)組+鏈表來(lái)實(shí)現(xiàn), 即使用數(shù)組處理沖突, 同一hash 值的鏈表都存儲(chǔ)在一個(gè)數(shù)組里, 但是當(dāng)位于一個(gè)桶中的元素較多, 即hash值相同的元素較多是,通過(guò)key 值依次查找效率比較低,在jdk1.8時(shí)哈希表存儲(chǔ)數(shù)據(jù)采用數(shù)組+鏈表+紅黑樹(shù)實(shí)現(xiàn),當(dāng)鏈表長(zhǎng)度超過(guò)閾值(8)時(shí), 將鏈表轉(zhuǎn)換為紅黑樹(shù),來(lái)降低查找時(shí)間.
HashSet唯一性通過(guò)hashCode和equals 方法來(lái)決定的, 如果往集合中添加自定義對(duì)象, 要保證其唯一性,就必須重寫(xiě)hashCode和equals 方法簡(jiǎn)歷屬于當(dāng)前對(duì)象的比較方式
4.2.3 HashSet 存儲(chǔ)自定義類(lèi)型元素
public class Student {String name ;String sex ;public Student(String name, String sex) {this.name = name;this.sex = sex;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return Objects.equals(name, student.name) &&Objects.equals(sex, student.sex);}@Overridepublic int hashCode() {return Objects.hash(name, sex);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", sex='" + sex + '\'' +'}';} }public class Test_Student {public static void main(String[] args) {HashSet<Student> hashSet = new HashSet<>();hashSet.add(new Student("小紅", "23"));hashSet.add(new Student("小紅", "23"));hashSet.add(new Student("小紅", "23"));hashSet.add(new Student("小紅", "23"));for (Student student1 : hashSet) {System.out.println(student1);//Student{name='小紅', sex='23'}}} }4.2.4 LinkedHashSet
HashSet保證元素的唯一性, 但是無(wú)法保證放入元素的順序, 如果要保證順序的話(huà),在HashSet下面有一個(gè)子接口java.util.LinkedHashSet , 他是鏈表和哈希表組合的一種數(shù)據(jù)存儲(chǔ)結(jié)構(gòu).
public static void main(String[] args) {LinkedHashSet<String> set = new LinkedHashSet<String>();set.add("aaa");set.add("bbb");set.add("ccc");set.add("ddd");set.add("ddd");for (String s : set) {System.out.println(s);}/*aaabbbcccddd*/}4.3 Map
4.3.1 什么是Map
>現(xiàn)實(shí)生活中,我們每個(gè)人都有每個(gè)人的身份證號(hào), 像這中一一對(duì)象的關(guān)系叫做映射, java提供了專(zhuān)門(mén)的集合類(lèi)來(lái)存放這些具有映射關(guān)系的元素,`java.util.Map` 接口, `Map`和`Collection`存儲(chǔ)數(shù)據(jù)的方式不同, Map是雙列的集合結(jié)構(gòu)- collection集合中元素是獨(dú)立存在的
- Map 集合中元素是成對(duì)出現(xiàn)的, 每個(gè)元素都由兩個(gè)部分組成, 通過(guò)鍵可以找到對(duì)應(yīng)的值
- 'Collection 集合成為單列集合, Map集合稱(chēng)為多列集合(每個(gè)鍵都是唯一的,值可以重復(fù)).
4.3.2 Map的常用子類(lèi)
- HashMap<K,V> : 存儲(chǔ)數(shù)據(jù)采用的哈希表結(jié)構(gòu), 元素的存取順序不能保證一致 ,由于要保證鍵的唯一性,不可重復(fù), 需要重寫(xiě)鍵的hashcode() 和equals() 方法,
- LinkedHashMap: HashMap 下的子類(lèi), 存儲(chǔ)數(shù)據(jù)采用哈希表+鏈表結(jié)構(gòu), 通過(guò)鏈表結(jié)構(gòu)可以保證元素存取順序一致, 通過(guò)哈希表結(jié)構(gòu)可以保證鍵的唯一,不重復(fù), 需要重寫(xiě)鍵的 hashcode() 和 equals()方法
- Map 集合中都有兩個(gè)泛型變量 <K,V> , 在定義時(shí) ,兩個(gè)泛型變量類(lèi)型可以相同也可以不同, 一般都是這樣定義Map<String,Object> 為了方便使用;
具體每個(gè)集合的底層以后一一研究 這里就不做贅述, 沒(méi)和集合底層都是一門(mén)學(xué)問(wèn);
4.3.3 Map 的常用方法
Map 接口中定義了很多種方法, 比較常用的有:
-
public v put(k key ,v value): 把指定的鍵與指定的值添加到Map中 , 若Map中沒(méi)有這個(gè)K則返回null, 如果有的話(huà)就返回原先的值,把新值插進(jìn)去;
-
public v remove(Object key): 把指定的鍵所對(duì)應(yīng)的鍵值在集合中刪除, 返回被刪除的值
-
public v get(Object key): 根據(jù)指定的鍵, 在Map 集合中獲取對(duì)應(yīng)的值
-
public Set keySet(): 獲取Map集合中所有的鍵, 存儲(chǔ)到Set 集合中.
-
public Set<Map.Entry<K,V>> entrySet(): 獲取到Map集合中所有的鍵值對(duì)對(duì)象的集合(Set集合)。
-
public boolean containKey(Object key) :判斷該集合中是否有此鍵。
public static void main(String[] args) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put(“1”, “test01”);
hashMap.put(“2”, “test02”);
hashMap.put(“3”, “test03”);
hashMap.put(“4”, “test04”);
System.out.println(hashMap);//{1=test01, 2=test02, 3=test03, 4=test04}
Object remove = hashMap.remove(“1”);//test01
System.out.println(remove);
System.out.println(hashMap);//{2=test02, 3=test03, 4=test04}
hashMap.put(“1”, “test01”);
System.out.println(hashMap);//{1=test01, 2=test02, 3=test03, 4=test04}
Object o = hashMap.get(“1”);
System.out.println(o);//test01
Set set = hashMap.keySet();
System.out.println(set);//[1, 2, 3, 4]
Set<Map.Entry<String, Object>> entries = hashMap.entrySet();
System.out.println(entries);//[1=test01, 2=test02, 3=test03, 4=test04]
boolean b = hashMap.containsKey(“1”);
System.out.println(b);//true
}
4.3.4 Map的遍歷方式
Map的遍歷, 因?yàn)殒I值唯一的,我們可以用keySet() 方法獲取到所有的鍵的set集合,然后遍歷set集合根據(jù)get()方法將key傳進(jìn)去, 取出值
public static void main(String[] args) {HashMap<String, Object> hashMap = new HashMap<>();hashMap.put("1", "test01");hashMap.put("2", "test02");hashMap.put("3", "test03");Set<String> set = hashMap.keySet();for (String s : set) {String ss = (String) hashMap.get(s);System.out.println(ss);}/*test01test02test03*/}還有一種就是用entrySet()方法, 獲取Set集合, 通過(guò)遍歷set 集合獲取每一個(gè)entry對(duì)象, 在通過(guò)entry 的getKey(), 和 getValue()方法來(lái)獲取鍵和值;
public static void main(String[] args) {HashMap<String, Object> hashMap = new HashMap<>();hashMap.put("1", "test01");hashMap.put("2", "test02");hashMap.put("3", "test03");Set<Map.Entry<String, Object>> entries = hashMap.entrySet();for (Map.Entry<String, Object> entry : entries) {String key = entry.getKey();Object value = entry.getValue();System.out.println(key+"==="+value);}/*1===test012===test023===test03*/}4.3.5 LinkedHashMap
hashMap的查詢(xún)速度很快, 可以保證成對(duì)元素的唯一性, 但是無(wú)法保證元素存放的順序, 要想保證元素的順序, 就得使用HashMap下的子類(lèi), LikendHashMap 他的底層是采用鏈表加哈希表組合的數(shù)據(jù)結(jié)構(gòu)
public static void main(String[] args) {LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();for (int i = 1; i <= 5; i++) {linkedHashMap.put("" + i + "", "Test" + i);}Set<Map.Entry<String, Object>> entries = linkedHashMap.entrySet();for (Map.Entry<String, Object> entry : entries) {System.out.println(entry.getKey()+"->"+entry.getValue());}/*1->Test12->Test23->Test34->Test45->Test5*/}4.4 collections工具類(lèi)
-
java.util.Collections 是集合的工具類(lèi),主要用來(lái)操作集合
-
public static void shuffle(List<?> list) : 打亂集合順序.
- public static void main(String[] args) {ArrayList<Integer> integers = new ArrayList<>();integers.add(11);integers.add(22);integers.add(33);integers.add(44);System.out.println(integers);//[11, 22, 33, 44]Collections.shuffle(integers);System.out.println(integers);//[11, 33, 22, 44]}
-
public static void sort(List list):將集合中的元素按照默認(rèn)規(guī)則排序
- public static void main(String[] args) {ArrayList<Integer> integers = new ArrayList<>();integers.add(1);integers.add(97);integers.add(43);integers.add(22);System.out.println(integers);//[1, 97, 43, 22]Collections.sort(integers);System.out.println(integers);//[1, 22, 43, 97]}
-
public static void sort(List list , Comparator<? super T>):將集合中元素按照指定規(guī)則排序.
public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Strdent{" +"name='" + name + '\'' +", age=" + age +'}';} }public static void main(String[] args) {ArrayList<Student> objects = new ArrayList<>();objects.add(new Student("小王",66));objects.add(new Student("小紅", 1));objects.add(new Student("小狗", 9));objects.add(new Student("小豬", 5));System.out.println(objects);//[Student{name='小王', age=66}, Student{name='小紅', age=1}, Student{name='小狗', age=9}, Student{name='小豬', age=5}]Collections.sort(objects, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o2.getAge() -o1.getAge() ;//前減后 由小到大, 后減前 由大到小}});System.out.println(objects);//[Student{name='小王', age=66}, Student{name='小狗', age=9}, Student{name='小豬', age=5}, Student{name='小紅', age=1}]}
public class Student {
private String name;
private int age;
5.泛型, 泛型通配符
5.1 泛型(Geneic)
在JDK1.5之前, 我們定義集合的時(shí)候 是可以隨意往里面賦值的, 但是取出的時(shí)候我們無(wú)法確定是什么類(lèi)型, 有時(shí)候就會(huì)導(dǎo)致異常的發(fā)生java.lang.ClassCasetException, 類(lèi)型轉(zhuǎn)換異常, 但是才JDK1.5 之后引入了泛型,就不會(huì)導(dǎo)致這種異常的發(fā)生,因?yàn)槲覀儗?shí)例集合的時(shí)候已經(jīng)指定了類(lèi)型,這樣的話(huà)如果存入的數(shù)據(jù)類(lèi)型匹配的話(huà)就會(huì)導(dǎo)致編譯報(bào)錯(cuò)
泛型的定義與使用;
可以定義泛型類(lèi), 方法, 接口,
-
定義含有泛型類(lèi)
public class Test01 {
public void add(E e){
}
}
在實(shí)例化類(lèi)的時(shí)候在能確定泛型的類(lèi)型;
public class Test {public static void main(String[] args) {Test01<String> stringTest01 = new Test01<>();stringTest01.add("d");} }-
定義含有泛型方法
//修飾符 <代表泛型的變量> 返回值類(lèi)型 方法名(參數(shù)){}
public class Test02 {
public E query(E e){
return e;
}
}
在調(diào)用方法的時(shí)候才能確定泛型的類(lèi)型
Test02 test02 = new Test02();test02.query("fd");-
定義含有泛型接口
public interface Test03 {
void add(E e);
E query();
}
調(diào)用時(shí)指明類(lèi)型
public class Test implements Test03<String> {public static void main(String[] args) {}@Overridepublic void add(String o) { }@Overridepublic String query() { return null; } }沒(méi)有創(chuàng)建時(shí)不能確定的類(lèi)型叫做泛型
public class Test01<E> implements Test03<E>{public void add(E e){ }@Overridepublic E query() { return null; } }5.2 泛型通配符
當(dāng)使用泛型類(lèi)或者接口是, 傳遞的數(shù)據(jù)中,泛型類(lèi)型不能確定, 可以通過(guò)通配符<?> 表示 , 使用通配符后, 只能使用Object中的共性方法 , 集合中元素自身的方法無(wú)法使用,
5.2.1 通配符的基本使用
泛型通配符:不知道該用什么類(lèi)型接收的時(shí)候可以使用泛型通配符? 表示未知通配符.此時(shí)只能接收數(shù)據(jù), 不能我那個(gè)集合中存入數(shù)據(jù).
public static void main(String[] args) {LinkedHashMap<Object, Object> objectObjectLinkedHashMap = new LinkedHashMap<>();get(objectObjectLinkedHashMap);}public static void get(Map< ?,? > collection){}泛型不存在繼承關(guān)系
如上圖, 這種實(shí)例定義泛型定義String 類(lèi)型, 但是接收用Object 的話(huà)就編譯報(bào)錯(cuò)
5.2.2 通配符高級(jí)使用–受限泛型
java中泛型存在上限和下限
泛型的上限
- 格式 類(lèi)型<? extends 類(lèi)> 對(duì)象名稱(chēng)
- 含義: 只能接收該類(lèi)型及其子類(lèi)
泛型的下限
-
格式:類(lèi)型<? super 類(lèi)> 對(duì)象名稱(chēng)
-
含義:只能接收本類(lèi)及其父類(lèi)
public class Test01 {
public static void getElements(Collection<? extends Number> collection) { }public static void getElements1(Collection<? super Number> collection) { }
public static void main(String[] args) {
HashSet objects = new HashSet();
HashSet integers = new HashSet();
HashSet strings = new HashSet();
HashSet numbers = new HashSet();
//getElements(objects); 會(huì)編譯報(bào)錯(cuò), 因?yàn)?getElements 接收的只能是Number類(lèi) 及其他的子類(lèi)
//getElements(strings); 同上
getElements(numbers);
getElements(integers);
//getElements1(integers); 編譯報(bào)錯(cuò), getElements1 泛型只能接收Number 類(lèi)型的及其的他父類(lèi)型
//getElements1(strings);
getElements1(numbers);
getElements1(objects);
}}
總結(jié)
以上是生活随笔為你收集整理的JAVA基础03-Object类,常用类,基本的数据结构, Collection常用体系,泛型-泛型通配符的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 妹子说我没有表情包?没关系通过pytho
- 下一篇: 在手心刻上你的名字