java基礎第十四篇之Map

一,Map集合的特點:

*

* 1.Map集合和Collection集合,沒有關系

*

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

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

*

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

*

* 總結(jié):

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

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

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

*

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

*

*

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

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

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

*

* 以上所有的實現(xiàn)類,保證鍵的唯一性(鍵不能重復),那么我們需要重寫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集合中原有的鍵重復,就可以達到改的目的

*

* 4.查

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

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集合 沒有繼承關系

* ??? ?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);

}

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

*

*

* 練習2:使用map存儲:鍵為學生(姓名,年齡)值為學生自己的家庭住址。

* ?? ??? ?Map

public class MapDemo {

public static void main(String[] args) {

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

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判斷鍵重復不重復,是通過hashCode和equals方法

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

//遍歷集合 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>

*

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

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

*

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

*

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

*

*

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

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

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

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

*

* ?? ??? ?Map<學院名,Map<學號,學生>> map = new ....

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

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

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

*

*

*

*

*

*/

public class MapMapDemo {

public static void main(String[] args) {

// TODO Auto-generated method stub

//1.創(chuàng)建一個UI學院的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學院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學院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.定義一個存儲所有學院名字和map對象的集合

Map> map = new HashMap>();

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

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

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

//遍歷map 打印是每一個學生

//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("學院,學號,學生名字,學生年齡");

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){

*

* ?? ??? ??? ? }

*

* 注意事項:

* ?? ??? ?當一個方法具有多個參數(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ī)則,在一次重復的元素不能被添加到TreeSet這個集合中。

2). TreeSet的兩種排序方式

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

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

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

當元素本身不具有比較性或者具備的比較性不是所需要的,就在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(存取有序,有索引,可以重復)

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

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

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

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

如果增和刪多,用LinkedList.

如果都多,用ArrayList

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

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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容