java基礎(chǔ)第十四篇之Map

一,Map集合的特點:

*

* 1.Map集合和Collection集合,沒有關(guān)系

*

* 2.Map集合的元素是成對存在(夫妻關(guān)系)

* ?? ??? ?Collection集合的元素是獨立存在的(單身關(guān)系)

*

* 3.Map集合的元素不能重復(fù)(是元素的key值不能重復(fù))

*

* 總結(jié):

* ?? ??? ?Collection集合我們一般稱為單列集合

* ?? ??? ?Map集合我們稱為雙列集合

* 二,Map接口下常用的實現(xiàn)類

*

* HashMap:底層是哈希表結(jié)構(gòu),無序的(存取順序不一致)

*

*

* LinkedHashMap:底層鏈表+哈希表結(jié)構(gòu),有序的(存取順序一致)

* ?? ??? ??? ?這里是兩個泛型,這里的K和V可以相同 也可以不同

* ?? ??? ??? ?K代表鍵的類型,V代表的是值的類型

*

* 以上所有的實現(xiàn)類,保證鍵的唯一性(鍵不能重復(fù)),那么我們需要重寫K這種類型的hashCode和equals方法

* ?? ??? ?比如:K的類型是String,Integer...(java提供的類型),那么我們不需要管他

* ?? ??? ??? ?K的類型是Person,Dog等自定義類型 那么我們就需要重寫hashCode和equals方法

*

* 三,Map接口中定義的常用方法:

*

* 1.增加:

* ?? ??? ?public V put(K key,V value);//向Map集合中添加一個元素(鍵值對)

* ?? ??? ?返回值:表示被新的鍵值對 覆蓋的那個舊的鍵值對的值

* ?? ??? ??? ?如果沒有覆蓋,返回值是null

*

* 2.刪除:

* ?? ??? ?public V remove(Object key);//刪除一個鍵值對(根據(jù)鍵來刪除)

*

* 3.改:實際上就是put方法,只要put的時候鍵和map集合中原有的鍵重復(fù),就可以達到改的目的

*

* 4.查

* ?? ??? ?public V get(Object key);//根據(jù)鍵 來查找鍵所對應(yīng)的值

public interface InterfaceA {

public abstract void showA();

interface InterfaceB{//內(nèi)部接口

public abstract void showB();

}

}

//定義一個類 去實現(xiàn)接口

class MyClass1 implements InterfaceA{

@Override

public void showA() {

// TODO Auto-generated method stub

}

//?? ?@Override

//?? ?public void showA() {

//?? ??? ?// TODO Auto-generated method stub

//

//?? ?}

}

class MyClass2 implements InterfaceA.InterfaceB{

@Override

public void showB() {

// TODO Auto-generated method stub

}

}

/*

* 1.因為Map集合 和Collection集合 沒有繼承關(guān)系

* ??? ?map集合中是沒有迭代器

*

* 2.java為map集合提供了另外兩種迭代的方式:

* ?? ??? ?方式一:以鍵找值的方法:

* ?? ??? ??? ?獲取所有的鍵的集合 map.keySet();

* ?? ??? ?方式二:鍵值對的方式

* ?? ??? ??? ?public Set> entrySet()

*/

//創(chuàng)建內(nèi)部類對象

//OuterClass.InnerClass oi = new OuterClass().new InnerClass();

Map map = new HashMap();

map.put("張三", 18);

map.put("李四", 28);

map.put("王五", 38);

map.put("趙六", 48);

//1.獲取map集合的entry 集合

Set> entries = map.entrySet();

//2.用迭代器 遍歷這個entries這個Set集合

Iterator> it = entries.iterator();

//3.遍歷

while(it.hasNext()){

Map.Entry entry = it.next();

//一個entry中 有兩個屬性

String key = entry.getKey();

Integer value = entry.getValue();

System.out.println(key+"="+value);

}

* 練習(xí)1:使用map存儲:鍵為學(xué)號,值為一個學(xué)生的對象,學(xué)生對象有屬性(姓名,年齡)

*

*

* 練習(xí)2:使用map存儲:鍵為學(xué)生(姓名躺孝,年齡)值為學(xué)生自己的家庭住址趟庄。

* ?? ??? ?Map

public class MapDemo {

public static void main(String[] args) {

//定義一個Map集合 存儲鍵為學(xué)生(姓名,年齡)值為學(xué)生自己的家庭住址奋单。

Map map = new HashMap();

//向集合添加數(shù)據(jù)

map.put(new Student("王寶強", 40), "北京五環(huán)外");

map.put(new Student("謝霆鋒", 50), "北京180環(huán)外");

map.put(new Student("馬蓉", 45), "上海交通路");

map.put(new Student("郭德綱", 55), "廣州德云社");

map.put(new Student("馬蓉", 45), "我家");

//map判斷鍵重復(fù)不重復(fù),是通過hashCode和equals方法

//如果 我要求一個學(xué)生的姓名和年齡一樣 就認為是同一個學(xué)生

//遍歷集合 keySet entrySet

//1.獲取entry的集合

Set> entries = map.entrySet();

//2.迭代器遍歷 foreach

for (Map.Entry entry : entries) {

Student key = entry.getKey();

String value = entry.getValue();

System.out.println(key+"="+value);

}

}

}

/*

* LinkedHashMap: 采用鏈表+哈希表結(jié)構(gòu)

* ?? ??? ?元素是有序的

Collection和Map都可以嵌套

*

* ArrayList>

*

* ArrayList>

*

* Map>

*

* Map>

*

* 比如我們傳智博客學(xué)生(有iOS Android UI JavaEE)

*?? ??? ?Map<學(xué)號,學(xué)生> UI = new HashMap<學(xué)號,學(xué)生>();

*

*?? ??? ?Map<學(xué)號,學(xué)生> JavaEE = new HashMap<學(xué)號,學(xué)生>();

*

*?? ??? ?Map<學(xué)號,學(xué)生> android = new HashMap<學(xué)號,學(xué)生>();

*

*

* ?? ??? ?ArrayList> ?al= new ....

* ?? ??? ??? ?al.add(UI);

* ?? ??? ??? ?al.add(JavaEE);

* ?? ??? ??? ?al.add(android);

*

* ?? ??? ?Map<學(xué)院名,Map<學(xué)號,學(xué)生>> map = new ....

* ?? ??? ??? ?map.put("UI學(xué)院",UI);

* ?? ??? ??? ?map.put("JavaEE學(xué)院",JavaEE);

* ?? ??? ??? ?map.put("安卓學(xué)院",android);

*

*

*

*

*

*/

public class MapMapDemo {

public static void main(String[] args) {

// TODO Auto-generated method stub

//1.創(chuàng)建一個UI學(xué)院的map集合

Map uiMap = new HashMap();

uiMap.put("黑馬001", new Student("小麗", 18));

uiMap.put("黑馬003", new Student("小美", 19));

uiMap.put("黑馬004", new Student("小雨", 20));

//2.創(chuàng)建一個JavaEE學(xué)院map集合

Map eeMap = new HashMap();

eeMap.put("黑馬001", new Student("小詩", 18));

eeMap.put("黑馬002", new Student("小公", 19));

eeMap.put("黑馬004", new Student("小龍", 20));

//3.創(chuàng)建一個android學(xué)院map集合

Map anMap = new HashMap();

anMap.put("黑馬002", new Student("小k", 18));

anMap.put("黑馬003", new Student("小Q", 19));

anMap.put("黑馬004", new Student("小A", 20));

//4.定義一個存儲所有學(xué)院名字和map對象的集合

Map> map = new HashMap>();

map.put("UI學(xué)院", uiMap);

map.put("EE學(xué)院", eeMap);

map.put("AN學(xué)院", anMap);

//遍歷map 打印是每一個學(xué)生

//1.keySet() 2.entrySet()

Set>> entries = map.entrySet();

//2.遍歷 entries 迭代器,foreach

Iterator>> it = entries.iterator();

//標準代碼

while(it.hasNext()){

Map.Entry> entry = it.next();

String key = entry.getKey();

Map valueMap = entry.getValue();

//遍歷value這個map集合 keySet entrySet

Set> ?xyentries = valueMap.entrySet();

//迭代器 foreach

Iterator> xyit = xyentries.iterator();

//標準代碼

while(xyit.hasNext()){

Map.Entry xyentry = xyit.next();

String xykey = xyentry.getKey();

Student xyValue = xyentry.getValue();

//System.out.println("學(xué)院,學(xué)號,學(xué)生名字,學(xué)生年齡");

System.out.println(key+"-"+xykey+"-"+xyValue.getName()+"-"+xyValue.getAge());

}

}

}

}

* Collections集合工具類中的兩個方法:

*

* public static void sort(List list);//按照自然順序(123 321 abc cba)排序一個List集合

*

* public static void shuffle(List list);//打亂集合中順序

* 可變參數(shù): 這里說的可變 不是參數(shù)的數(shù)據(jù)類型 而是參數(shù)的個數(shù)

* ?? ??? ?JDK1.5之后的新特性

*

* ?? ??? ?格式: public void showNum(int... num){

*

* ?? ??? ??? ? }

*

* 注意事項:

* ?? ??? ?當(dāng)一個方法具有多個參數(shù),而且其中有一個是可變參數(shù),那么可變參數(shù)必須寫到 參數(shù)的最后一個

*

public class VariableArgDemo01 {

public static void main(String[] args) {

// TODO Auto-generated method stub

//?? ??? ?show(1);

//?? ??? ?show(1,2);

//?? ??? ?show(1,2,3);

show(1,2,3,4,5);

}

//定義帶有可變參數(shù)的方法

public static void show(int count,int... num){

//在方法中怎么獲取實際傳遞進來的參數(shù),可變參數(shù)本質(zhì)就是一個數(shù)組

System.out.println(num.length);

for (int i = 0; i < num.length; i++) {

System.out.println(num[i]);

}

}

}

/*

* 1.定義自定義規(guī)則的map集合

*

* 2.產(chǎn)生一副牌(存儲的是序號)

*

* 3.洗牌(序號的集合)

*

* 4.發(fā)牌(發(fā)的就是序號)

*

* 5.要求三個玩家以及地主牌進行排序(sort方法)

*

* 6.看牌(根據(jù)序號從自定義的map集合中取值)

*

*

*/

public class DouDiZhuDemo {

public static void main(String[] args) {

// TODO Auto-generated method stub

//1.定義規(guī)則的map集合

Map map = new LinkedHashMap();

//2.定義一個牌集合

ArrayList cards = new ?ArrayList();

//添加牌 一張牌 數(shù)值+花色

String[] nums = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};

String[] colors = {"?","?","?","?"};

//拼接一個張牌

int id = 54;//1234

for (String num : nums) {

for (String color : colors) {

String card = color+num;

map.put(id, card);

cards.add(id);

id--;

//System.out.println(card);

}

}

//添加大王小王

map.put(2, "小S");

cards.add(2);

map.put(1, "大S");

cards.add(1);

//3.洗牌

Collections.shuffle(cards);

//4.發(fā)牌

//定義三個集合

ArrayList p1 = new ArrayList();

ArrayList p2 = new ArrayList();

ArrayList p3 = new ArrayList();

//定義地主牌的集合

ArrayList dp = new ArrayList();

//遍歷54張牌

for (int i = 0; i < cards.size(); i++) {

Integer card = cards.get(i);

//如果是最后三張,不發(fā),保存到地主牌的集合中

//i 53 52 51

if(i>=51){

//不發(fā)

dp.add(card);

}else{

//0 p1 1 p2 ?2 p3 ?3 p1

if(i%3==0){

//給p1發(fā)牌

p1.add(card);

}else if(i%3==1){

p2.add(card);

}else{

p3.add(card);

}

}

}

//5.排序

Collections.sort(p1);

Collections.sort(p2);

Collections.sort(p3);

Collections.sort(dp);

//看牌

lookCards(p1,map);

lookCards(p2,map);

lookCards(p3,map);

lookCards(dp,map);

}

/*

* 看牌

*/

public static void lookCards(ArrayList cards,Map map){

//根據(jù)每一張的編號從 map中取出打印

for (Integer id : cards) {

String card = map.get(id);

System.out.print(card+" ");

}

System.out.println();

}

}

/*

Map 里面有個方法: ?boolean containsKey : 判斷Map集合中是否包含指定值?

HashSet:底層是哈希算法實現(xiàn).

LinkedHashSet:底層是鏈表實現(xiàn),但是也是可以保證元素唯一,和HashSet原理一樣.

TreeSet:底層是二叉樹算法實現(xiàn).

一般在開發(fā)的時候不需要對存儲的元素排序,所有在開發(fā)的時候大多用HashSet,HashSet的效率比較高

TreeSet在面試的時候比較多,問你有幾種排序方式,和幾種排序方式的區(qū)別?

2. ? ?TreeSet總結(jié)

1). TreeSet的特點

(1). 可以對元素進行排序

有兩種排序方式贷笛。

(2). TreeSet保證元素的唯一性依據(jù)

在實現(xiàn)的Comparable的compareTo或者Comparator的compare方法中乏苦,如果這兩個方法的返回值為0,那么TreeSet就認為這兩個元素一樣洞就。按照Set的唯一性規(guī)則掀淘,在一次重復(fù)的元素不能被添加到TreeSet這個集合中。

2). TreeSet的兩種排序方式

(1). 讓元素本身具有比較性

元素本身要實現(xiàn)Comparable接口并實現(xiàn)里面的compareTo方法以保證元素本身具有比較性

(2). 讓容器自身具有比較性

當(dāng)元素本身不具有比較性或者具備的比較性不是所需要的倾贰,就在TreeSet建立實例的時候拦惋,傳入Comparator接口的實現(xiàn)子類的實例。這個Comparator子類必須實現(xiàn)compare方法吞彤。

(3). 元素的可存儲性

[1]. 自定義的類,如果重寫了hashCode和equals兩個方法寥枝,可以存入HashSet容器

[2]. 自定義的類,如果實現(xiàn)了Comparable的compareTo()方法俱恶,可以存入TreeSet容器。

【總結(jié)】如果自定義的類既重寫了hashCode和equals合是,又實現(xiàn)了compareTo,那么這個類的元素既可以存入HashSet容器泊藕,也可以存入TreeSet容器娃圆。

Map

HashMap :底層是哈希算法,針對鍵

LinkedHashMap:底層是鏈表,針對鍵.

TreeMap:底層是二叉樹算法,針對鍵.(開發(fā)中HashMap比較多)

Collection

List(存取有序,有索引,可以重復(fù))

ArrayList:底層是數(shù)組實現(xiàn)的,線程不安全,查找和修改快,增和刪比較慢.

LinkedList:底層是鏈表實現(xiàn)的,線程不安全,增和刪比較快,查找和修改比較慢

Vector : 底層是數(shù)組實現(xiàn)的,線程安全的,無論增刪改查都慢.

如果查找和修改多,用ArrayList.

如果增和刪多,用LinkedList.

如果都多,用ArrayList

Set(存取無序,無索引,不可以重復(fù))

HashSet

LinkedHashSet

TreeSet

//獲取字符串中每個字符的個數(shù)

public class Demo11 {

public static void main(String[] args) {

String sbc = "kalsdjfoisoigjsljlfklkadaooaijfa";

//將字符串變成一個字符數(shù)組

char[] chs = sbc.toCharArray();

//遍歷這個字符數(shù)組,一個一個的進行比較,但是要計算數(shù)量,那么用那個集合好點?Map,為什么Map,可以顯示效果,'a',1 ?'b'2

Map map = new HashMap<>();

//遍歷字符數(shù)組

for(char c : chs) {

//判斷Map里面有沒有鍵是c的?

boolean flag = map.containsKey(c);

//代表map里面有鍵是c的,那么數(shù)量就需要++

if(flag) {

//在原先的數(shù)量上加上1,根據(jù)鍵找值

map.put(c, map.get(c)+1);

}else {

//就是map集合里面沒用這個字符,如果說是沒有的話,那么說明是第一次.

map.put(c, 1);

}

}

System.out.println(map);

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末讼呢,一起剝皮案震驚了整個濱河市谦炬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌础爬,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赖条,居然都是意外死亡纬乍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門纽竣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茧泪,“玉大人,你說我怎么就攤上這事穴吹∈任辏” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵锈颗,是天一觀的道長。 經(jīng)常有香客問我淋淀,道長姨拥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任柴罐,我火速辦了婚禮革屠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘似芝。我一直安慰自己,他們只是感情好详炬,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布寞奸。 她就那樣靜靜地躺著呛谜,像睡著了一般隐岛。 火紅的嫁衣襯著肌膚如雪瓷翻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天妒牙,我揣著相機與錄音童谒,去河邊找鬼。 笑死象浑,一個胖子當(dāng)著我的面吹牛愉豺,可吹牛的內(nèi)容都是我干的茫因。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼驰贷,長吁一口氣:“原來是場噩夢啊……” “哼洛巢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起稿茉,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤芥炭,失蹤者是張志新(化名)和其女友劉穎园蝠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痢士,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年陪汽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片况增。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖歧强,靈堂內(nèi)的尸體忽然破棺而出摊册,到底是詐尸還是另有隱情颊艳,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布棋枕,位于F島的核電站白修,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏重斑。R本人自食惡果不足惜兵睛,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窥浪。 院中可真熱鬧祖很,春花似錦、人聲如沸漾脂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽符相。三九已至拆融,卻和暖如春蠢琳,著一層夾襖步出監(jiān)牢的瞬間傲须,已是汗流浹背泰讽。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留累澡,地道東北人愧哟。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓蕊梧,卻偏偏與公主長得像肥矢,于是被迫代替她去往敵國和親甘改。 傳聞我的和親對象是個殘疾皇子楼誓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容