一,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);
}
}