一,Map集合的特點: * * 1.Map集合和Collection集合,沒有關係 * * 2.Map集合的元素是成對存在(夫妻關係) * Collection集合的元素是獨立存在的(單身關係) * * 3.Map集合的元素不能重覆(是元素的key值不能重覆) * * 總結: * Collectio ...
一,Map集合的特點:
*
* 1.Map集合和Collection集合,沒有關係
*
* 2.Map集合的元素是成對存在(夫妻關係)
* Collection集合的元素是獨立存在的(單身關係)
*
* 3.Map集合的元素不能重覆(是元素的key值不能重覆)
*
* 總結:
* Collection集合我們一般稱為單列集合
* Map集合我們稱為雙列集合
* 二,Map介面下常用的實現類
*
* HashMap<K,V>:底層是哈希表結構,無序的(存取順序不一致)
*
*
* LinkedHashMap<K,V>:底層鏈表+哈希表結構,有序的(存取順序一致)
* 這裡<K,V>是兩個泛型,這裡的K和V可以相同 也可以不同
* K代表鍵的類型,V代表的是值的類型
*
* 以上所有的實現類,保證鍵的唯一性(鍵不能重覆),那麼我們需要重寫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);//刪除一個鍵值對(根據鍵來刪除)
*
* 3.改:實際上就是put方法,只要put的時候鍵和map集合中原有的鍵重覆,就可以達到改的目的
*
* 4.查
* public V get(Object key);//根據鍵 來查找鍵所對應的值
public interface InterfaceA {
public abstract void showA();
interface InterfaceB{//內部介面
public abstract void showB();
}
}
//定義一個類 去實現介面
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<Map.Entry<K,V>> entrySet()
*/
//創建內部類對象
//OuterClass.InnerClass oi = new OuterClass().new InnerClass();
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("張三", 18);
map.put("李四", 28);
map.put("王五", 38);
map.put("趙六", 48);
//1.獲取map集合的entry 集合
Set<Map.Entry<String, Integer>> entries = map.entrySet();
//2.用迭代器 遍歷這個entries這個Set集合
Iterator<Map.Entry<String, Integer>> it = entries.iterator();
//3.遍歷
while(it.hasNext()){
Map.Entry<String, Integer> entry = it.next();
//一個entry中 有兩個屬性
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
* 練習1:使用map存儲:鍵為學號,值為一個學生的對象,學生對象有屬性(姓名,年齡)
*
*
* 練習2:使用map存儲:鍵為學生(姓名,年齡)值為學生自己的家庭住址。
* Map<Student,String>
public class MapDemo {
public static void main(String[] args) {
//定義一個Map集合 存儲鍵為學生(姓名,年齡)值為學生自己的家庭住址。
Map<Student, String> map = new HashMap<Student, String>();
//向集合添加數據
map.put(new Student("王寶強", 40), "北京五環外");
map.put(new Student("謝霆鋒", 50), "北京180環外");
map.put(new Student("馬蓉", 45), "上海交通路");
map.put(new Student("郭德綱", 55), "廣州德雲社");
map.put(new Student("馬蓉", 45), "我家");
//map判斷鍵重覆不重覆,是通過hashCode和equals方法
//如果 我要求一個學生的姓名和年齡一樣 就認為是同一個學生
//遍歷集合 keySet entrySet
//1.獲取entry的集合
Set<Map.Entry<Student, String>> entries = map.entrySet();
//2.迭代器遍歷 foreach
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
/*
* LinkedHashMap: 採用鏈表+哈希表結構
* 元素是有序的
Collection和Map都可以嵌套
*
* ArrayList<ArrayList<String>>
*
* ArrayList<Map<K,V>>
*
* Map<String,ArrayList<String>>
*
* Map<String,Map<String,Student>>
*
* 比如我們傳智博客學生(有iOS Android UI JavaEE)
* Map<學號,學生> UI = new HashMap<學號,學生>();
*
* Map<學號,學生> JavaEE = new HashMap<學號,學生>();
*
* Map<學號,學生> android = new HashMap<學號,學生>();
*
*
* ArrayList<Map<學號,學生>> 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.創建一個UI學院的map集合
Map<String, Student> uiMap = new HashMap<String, Student>();
uiMap.put("黑馬001", new Student("小麗", 18));
uiMap.put("黑馬003", new Student("小美", 19));
uiMap.put("黑馬004", new Student("小雨", 20));
//2.創建一個JavaEE學院map集合
Map<String, Student> eeMap = new HashMap<String, Student>();
eeMap.put("黑馬001", new Student("小詩", 18));
eeMap.put("黑馬002", new Student("小公", 19));
eeMap.put("黑馬004", new Student("小龍", 20));
//3.創建一個android學院map集合
Map<String, Student> anMap = new HashMap<String, Student>();
anMap.put("黑馬002", new Student("小k", 18));
anMap.put("黑馬003", new Student("小Q", 19));
anMap.put("黑馬004", new Student("小A", 20));
//4.定義一個存儲所有學院名字和map對象的集合
Map<String,Map<String, Student>> map = new HashMap<String, Map<String,Student>>();
map.put("UI學院", uiMap);
map.put("EE學院", eeMap);
map.put("AN學院", anMap);
//遍歷map 列印是每一個學生
//1.keySet() 2.entrySet()
Set<Map.Entry<String,Map<String, Student>>> entries = map.entrySet();
//2.遍歷 entries 迭代器,foreach
Iterator<Map.Entry<String,Map<String, Student>>> it = entries.iterator();
//標準代碼
while(it.hasNext()){
Map.Entry<String,Map<String, Student>> entry = it.next();
String key = entry.getKey();
Map<String, Student> valueMap = entry.getValue();
//遍歷value這個map集合 keySet entrySet
Set<Map.Entry<String, Student>> xyentries = valueMap.entrySet();
//迭代器 foreach
Iterator<Map.Entry<String, Student>> xyit = xyentries.iterator();
//標準代碼
while(xyit.hasNext()){
Map.Entry<String, Student> 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<T> list);//按照自然順序(123 321 abc cba)排序一個List集合
*
* public static void shuffle(List<?> list);//打亂集合中順序
* 可變參數: 這裡說的可變 不是參數的數據類型 而是參數的個數
* JDK1.5之後的新特性
*
* 格式: public void showNum(int... num){
*
* }
*
* 註意事項:
* 當一個方法具有多個參數,而且其中有一個是可變參數,那麼可變參數必須寫到 參數的最後一個
*
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);
}
//定義帶有可變參數的方法
public static void show(int count,int... num){
//在方法中怎麼獲取實際傳遞進來的參數,可變參數本質就是一個數組
System.out.println(num.length);
for (int i = 0; i < num.length; i++) {
System.out.println(num[i]);
}
}
}
/*
* 1.定義自定義規則的map集合
*
* 2.產生一副牌(存儲的是序號)
*
* 3.洗牌(序號的集合)
*
* 4.發牌(發的就是序號)
*
* 5.要求三個玩家以及地主牌進行排序(sort方法)
*
* 6.看牌(根據序號從自定義的map集合中取值)
*
*
*/
public class DouDiZhuDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1.定義規則的map集合
Map<Integer, String> map = new LinkedHashMap<Integer, String>();
//2.定義一個牌集合
ArrayList<Integer> cards = new ArrayList<Integer>();
//添加牌 一張牌 數值+花色
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.發牌
//定義三個集合
ArrayList<Integer> p1 = new ArrayList<Integer>();
ArrayList<Integer> p2 = new ArrayList<Integer>();
ArrayList<Integer> p3 = new ArrayList<Integer>();
//定義地主牌的集合
ArrayList<Integer> dp = new ArrayList<Integer>();
//遍歷54張牌
for (int i = 0; i < cards.size(); i++) {
Integer card = cards.get(i);
//如果是最後三張,不發,保存到地主牌的集合中
//i 53 52 51
if(i>=51){
//不發
dp.add(card);
}else{
//0 p1 1 p2 2 p3 3 p1
if(i%3==0){
//給p1發牌
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<Integer> cards,Map<Integer, String> map){
//根據每一張的編號從 map中取出列印
for (Integer id : cards) {
String card = map.get(id);
System.out.print(card+" ");
}
System.out.println();
}
}
/*
Map 裡面有個方法: boolean containsKey : 判斷Map集合中是否包含指定值
HashSet:底層是哈希演算法實現.
LinkedHashSet:底層是鏈表實現,但是也是可以保證元素唯一,和HashSet原理一樣.
TreeSet:底層是二叉樹演算法實現.
一般在開發的時候不需要對存儲的元素排序,所有在開發的時候大多用HashSet,HashSet的效率比較高
TreeSet在面試的時候比較多,問你有幾種排序方式,和幾種排序方式的區別?
2. TreeSet總結
1). TreeSet的特點
(1). 可以對元素進行排序
有兩種排序方式。
(2). TreeSet保證元素的唯一性依據
在實現的Comparable的compareTo或者Comparator的compare方法中,如果這兩個方法的返回值為0,那麼TreeSet就認為這兩個元素一樣。按照Set的唯一性規則,在一次重覆的元素不能被添加到TreeSet這個集合中。
2). TreeSet的兩種排序方式
(1). 讓元素本身具有比較性
元素本身要實現Comparable介面並實現裡面的compareTo方法以保證元素本身具有比較性
(2). 讓容器自身具有比較性
當元素本身不具有比較性或者具備的比較性不是所需要的,就在TreeSet建立實例的時候,傳入Comparator介面的實現子類的實例。這個Comparator子類必須實現compare方法。
(3). 元素的可存儲性
[1]. 自定義的類,如果重寫了hashCode和equals兩個方法,可以存入HashSet容器
[2]. 自定義的類,如果實現了Comparable的compareTo()方法,可以存入TreeSet容器。
【總結】如果自定義的類既重寫了hashCode和equals,又實現了compareTo,那麼這個類的元素既可以存入HashSet容器,也可以存入TreeSet容器。
Map
HashMap :底層是哈希演算法,針對鍵
LinkedHashMap:底層是鏈表,針對鍵.
TreeMap:底層是二叉樹演算法,針對鍵.(開發中HashMap比較多)
Collection
List(存取有序,有索引,可以重覆)
ArrayList:底層是數組實現的,線程不安全,查找和修改快,增和刪比較慢.
LinkedList:底層是鏈表實現的,線程不安全,增和刪比較快,查找和修改比較慢
Vector : 底層是數組實現的,線程安全的,無論增刪改查都慢.
如果查找和修改多,用ArrayList.
如果增和刪多,用LinkedList.
如果都多,用ArrayList
Set(存取無序,無索引,不可以重覆)
HashSet
LinkedHashSet
TreeSet
//獲取字元串中每個字元的個數
public class Demo11 {
public static void main(String[] args) {
String sbc = "kalsdjfoisoigjsljlfklkadaooaijfa";
//將字元串變成一個字元數組
char[] chs = sbc.toCharArray();
//遍歷這個字元數組,一個一個的進行比較,但是要計算數量,那麼用那個集合好點?Map,為什麼Map,可以顯示效果,'a',1 'b'2
Map<Character, Integer> map = new HashMap<>();
//遍歷字元數組
for(char c : chs) {
//判斷Map裡面有沒有鍵是c的?
boolean flag = map.containsKey(c);
//代表map裡面有鍵是c的,那麼數量就需要++
if(flag) {
//在原先的數量上加上1,根據鍵找值
map.put(c, map.get(c)+1);
}else {
//就是map集合裡面沒用這個字元,如果說是沒有的話,那麼說明是第一次.
map.put(c, 1);
}
}
System.out.println(map);
}
}