一,Map集合的基本操作
package fighting;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
/**
* Map:存儲一組成對的鍵值對象,key不要求有序,但不能重複;value也不要求有序,但允許重複。
*
* Collection是單列集合,Map是雙列集合。
*
* 1,添加
* put(k,v)
* pubAll()
* 2,删除
* clear()
* remove(k)
* 3,判斷
* containsKey()
* containsValue()
* isEmpty()
* 4,擷取
* get()
* size()
* values()
*
* entrySet()
* keySet()
*
* Map
* |-HashTable:底層是哈希表資料結構,不可以存入null鍵和null值,線程同步,效率低。
* 用作鍵的對象必須實作hashCode方法和equals方法。
* |-HashMap:底層是哈希表資料結構,允許使用null鍵和null值,該集合是不同步,效率高。
* |-TreeMap:底層是二叉樹資料結構,線程不同步,可以用于給map集合中的鍵進行排序。
*
* TreeMap和Set很想,其實,Set底層就是使用了Map集合。
*/
public static void main(String[] args) {
Map<String,String> map=new HashMap<String,String>();
//添加元素
map.put("01", "zhangsan001");
map.put("02", "zhangsan002");
map.put("03", "zhangsan003");
System.out.println("containsKey:"+map.containsKey("02"));//containsKey:true
//remove方法傳回值:與 key 關聯的舊值;如果 key 沒有任何映射關系,則傳回 null。(傳回 null 還可能表示該映射之前将 null 與 key 關聯。)
System.out.println("remove:"+map.remove("022"));//remove:null
System.out.println("remove:"+map.remove("02"));//remove:zhangsan002
//可以通過get方法的傳回值來判斷一個鍵是否存在。
System.out.println("get:"+map.get("02"));//get:null
System.out.println("get:"+map.get("03"));//get:zhangsan003
//下面這兩種特殊情況
map.put(null, "aaa");
System.out.println("get:"+map.get(null));//get:aaa
map.put("04", null);
System.out.println("get:"+map.get("04"));//get:null
//這行代碼說明,使用get方法擷取的null為空,不能說明沒有這個鍵,也可能是映射之前将null和key關聯
//擷取map集合中所有的值
Collection<String> coll = map.values();//這裡不要Collection<V> coll,實際使用中,要把V變成具體的類型。
System.out.println(coll);//[zhangsan001, zhangsan003, null, aaa]
//注意:添加元素時,如果出現相同的key,後添加的值會覆寫原有的鍵對應的值,并且傳回原來的這個值。
System.out.println(map.put("ch", "中國"));//null
System.out.println(map.put("ch", "中華人民共和國"));//中國
System.out.println(map);//{ch=中華人民共和國, 01=zhangsan001, 03=zhangsan003, 04=null, null=aaa}
}
}
二,Map集合的兩種取出方式:
package fighting;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapKeySet {
/**
* map集合的兩種取出方式:
* 1,keySet:将map集合中所有的鍵存入到Set集合,因為Set具備疊代器,
* 是以可以使用疊代方式取出所有的鍵,再根據get方法,擷取每一個鍵對應的值
* map集合沒有疊代器,map集合的取出原理:将map集合轉成Set,利用Set的疊代器疊代取出。
* 2,entrySet:傳回映射中包含的映射關系的Set視圖--Map.Entry<K,V>
* Map.Entry 其實Entry也是一個接口,他是Map接口中的一個内部接口。
* interface Map
* {
* public static interface Entry{
* public abstract Object getKey();
* public abstract Object getValue();
* }
* }
* class HashMap implements implements Map{
*
* class xxx implements Map.Entry{
* public Object getKey(){};
* public Object getValue(){};
* }
* }
*/
public static void main(String[] args) {
Map<String,String> map=new HashMap<String,String>();
//添加元素
map.put("01", "zhangsan001");
map.put("02", "zhangsan002");
map.put("04", "zhangsan004");
map.put("03", "zhangsan003");
//擷取map集合中所有鍵的Set集合
Set<String> keySet = map.keySet();
//擷取疊代器
Iterator<String> it = keySet.iterator();
while(it.hasNext()){
String key = it.next();
System.out.println("key:"+key+" value:"+map.get(key));
}
/*輸出結果
* key:01 value:zhangsan001
* key:03 value:zhangsan003
* key:04 value:zhangsan004
* key:02 value:zhangsan002
*/
Set<Map.Entry<String, String>> entryset = map.entrySet();
Iterator<Map.Entry<String, String>> it1 = entryset.iterator();
while(it1.hasNext()){
Map.Entry<String, String> me = it1.next();
String key = me.getKey();
String value = me.getValue();
System.out.println(key+":"+value);
}
/*輸出結果
* 01:zhangsan001
* 03:zhangsan003
* 04:zhangsan004
* 02:zhangsan002
*/
}
}
三,有關Map的一個小練習:
package fighting;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.itheima.Student;
public class MapDemo2 {
/**
* 練習:每一個學生都有對應的歸屬地。
* 學生Student,位址String
* 學生屬性:姓名,年齡
* 注意:姓名和年齡相同的視為同一個學生
* 保證學生的唯一性。
*
* 1,描述學生。
* 2,定義map容易,将學生作為鍵,位址作為值,存入。
* 3,擷取map集合中的元素。
*
*/
public static void main(String[] args) {
HashMap<Student0627,String> hm = new HashMap<Student0627,String>();
hm.put(new Student0627("zhangsan001",22), "北京");
hm.put(new Student0627("zhangsan002",23), "河北");
hm.put(new Student0627("zhangsan003",24), "内蒙古");
hm.put(new Student0627("zhangsan004",25), "天津");
//第一種取出方式:keySet
Set<Student0627> keySet =hm.keySet();
Iterator<Student0627> it = keySet.iterator();
while(it.hasNext()){
Student0627 stu = it.next();
System.out.println(stu+hm.get(stu));
}
/*
* zhangsan001...22北京
* zhangsan004...25天津
* zhangsan003...24内蒙古
* zhangsan002...23河北
*/
//第二種取出方式:entrySet
Set<Map.Entry<Student0627, String>> entrySet = hm.entrySet();
Iterator<Map.Entry<Student0627, String>> it1 = entrySet.iterator();
while(it1.hasNext()){
Map.Entry<Student0627, String> me= it1.next();
System.out.println(me.getKey()+"..."+me.getValue());
}
/*
* zhangsan001...22...北京
*zhangsan004...25...天津
*zhangsan003...24...内蒙古
*zhangsan002...23...河北
*/
//再添加一條記錄,key已經存在,值不同
hm.put(new Student0627("zhangsan001",22), "廣東");
Set<Map.Entry<Student0627, String>> entrySet2 = hm.entrySet();
Iterator<Map.Entry<Student0627, String>> it2 = entrySet.iterator();
while(it2.hasNext()){
Map.Entry<Student0627, String> me= it2.next();
System.out.println(me.getKey()+"..."+me.getValue());
}
/*
* zhangsan001...22...廣東 ----注意zhangsan001這一條歸屬地變成了"廣東"
* zhangsan004...25...天津
* zhangsan003...24...内蒙古
* zhangsan002...23...河北
*/
}
}
//注意:類的對象不确定要存到什麼集合中去,是以要保證儲存到任何集合中都不會出錯
//①要覆寫hashCode方法和equals方法,
//②還要實作Comparable接口,實作compareTo方法。
class Student0627 implements Comparable<Student0627>{
private String name;
private int age;
public Student0627(String name,int age){
this.name=name;
this.age=age;
}
public int compareTo(Student0627 o) {
int num = new Integer(this.age).compareTo(new Integer(o.age));
if(num==0)
return this.name.compareTo(o.name);
return num;
}
public int hashCode(){
return name.hashCode()+age*34;
}
public boolean equals(Object obj){
if(!(obj instanceof Student0627)){
throw new ClassCastException("類型不比對");
}
Student0627 s =(Student0627)obj;
return this.name.equals(s.name)&&this.age==s.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;
}
@Override
public String toString(){
return this.name+"..."+this.age;
}
}
四,上一個小練習(MapDemo2)的需求更新:
package fighting;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapDemo {
/**
* MapDemo2的續:
* 需求:對學生對象的年齡進行升序排序。
* 需求2:按照學生對象的姓名升序排序
* 因為資料是以鍵值對形式存在的,是以要使用可以排序的Map集合--TreeMap
*
*/
public static void main(String[] args) {
//需求1
TreeMap<Student0627,String> tm = new TreeMap<Student0627,String>();
tm.put(new Student0627("bzhangsan003",23), "北京");
tm.put(new Student0627("zhangsan001",21), "河北");
tm.put(new Student0627("azhangsan004",24), "内蒙古");
tm.put(new Student0627("zhangsan002",22), "天津");
Set<Map.Entry<Student0627,String>> entrySet =tm.entrySet();
Iterator<Map.Entry<Student0627,String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Student0627,String> me =it.next();
Student0627 stu = me.getKey();
String addr = me.getValue();
System.out.println(stu+"..."+addr);
}
/*
* zhangsan001...21...河北
* zhangsan002...22...天津
* bzhangsan003...23...北京
* azhangsan004...24...内蒙古
*/
//需求2:如果想按照姓名升序進行排序,可以自定義比較器,傳入TreeMap構造方法
TreeMap<Student0627,String> tm2 = new TreeMap<Student0627,String>(new StuNameComparator());
tm2.put(new Student0627("bzhangsan003",23), "北京");
tm2.put(new Student0627("zhangsan001",21), "河北");
tm2.put(new Student0627("azhangsan004",24), "内蒙古");
tm2.put(new Student0627("zhangsan002",22), "天津");
Set<Map.Entry<Student0627,String>> entrySet2 =tm2.entrySet();
Iterator<Map.Entry<Student0627,String>> it2 = entrySet2.iterator();
while(it2.hasNext()){
Map.Entry<Student0627,String> me =it2.next();
Student0627 stu = me.getKey();
String addr = me.getValue();
System.out.println(stu+"..."+addr);
}
/*
* azhangsan004...24...内蒙古
* bzhangsan003...23...北京
* zhangsan001...21...河北
* zhangsan002...22...天津
*/
}
}
class StuNameComparator implements Comparator<Student0627>{
public int compare(Student0627 s1, Student0627 s2) {
int num =s1.getName().compareTo(s2.getName());
if(num==0){
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}
五,有關Map的第二個小練習--字母出現的次數:
package fighting;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapDemo1 {
/**
* 練習:
* "adsgljrgsgjfdgf"擷取該字元串中的字母出現的次數。
* 希望列印結果:a(1)c(2)...
*
* 通過結果發現,每一個字母都有對應的次數,
* 說明字母和次數之間都有映射關系。
*
* 注意了,當發現有映射關系時,就可以選擇Map集合,
* 因為Map集合中存放就是映射關系。
*
* 思路:
* 1,将字元串轉換成字元數組,因為要對每一個字元進行操作。
* 2,定義一個map集合,因為列印結果的字母有順序,是以使用TreeMap集合,
* 3,周遊字元數組,将每一個字母作為鍵,去查map集合,
* 如果傳回null,就将該字母和1存入map集合;
* 如果傳回不是null,說明該字母在map集合内已經存在,并有對應的次數,
* 那麼就擷取該次數并自增,讓後讓該字母和自增後的次數覆寫到集合中,覆寫到原來的鍵和對應的值
* 4,将Map集合的資料指定的字元串形式傳回
*/
public static void main(String[] args) {
String str = carCount("adsgljrgsgjfdgf");
System.out.println(str);
}
public static String carCount(String str){
char[] chs = str.toCharArray();
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
int count=0;
for(int x=0;x<chs.length;x++){
if(chs[x]>='a'&&chs[x]<='z'||chs[x]>='A'&&chs[x]<='Z'){//非字母不用計算個數
continue;
}
Integer value = tm.get(chs[x]);
//方法二
if(value!=null){//不等于空,說明已經存在這個key,那麼把key對應的值賦給count,再加一
count = value;
}
count++;
tm.put(chs[x], count);
count =0;
//方法一
/*if(value==null){
value = 1;
tm.put(chs[x], 1);
}else{
value++;
tm.put(chs[x], value);
}*/
}
StringBuilder sb = new StringBuilder();
Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Character,Integer> me= it.next();
Character ch = me.getKey();
Integer value = me.getValue();
sb.append(ch+"("+value+")");
}
return sb.toString();//把sb轉換成字元串類型傳回,這裡toString不能省略
}
}
六,Map擴充知識:大集合嵌套小集合、一對多映射
package fighting;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
public class MapDemo1 {
/**
* Map擴充知識:
* map集合被使用是因為具備映射關系。。
*
* 需求:一個學校有多個班級,每個班級有多名學生,利用Map周遊所有學生
* 比如:學校有預熱班和就業班
* "預熱班","1号","張三"
* "預熱班","2号","李四"
* "就業班","1号","張三"
* "就業班","2号","李四"
*
* 需求2:把學号和學生姓名封裝成學生對象進行操作。
*
* 大集合裡嵌套小集合
* 一對多映射
*/
public static void main(String[] args) {
//分别定義學校、預熱班、就業班
HashMap<String,HashMap<String,String>> school = new HashMap<String,HashMap<String,String>>();
HashMap<String,String> yure=new HashMap<String,String>();
HashMap<String,String> jiuye =new HashMap<String,String>();
//把班級資訊添加到學校集合
school.put("預熱班", yure);
school.put("就業班", jiuye);
//把學生資訊添加到班級集合
yure.put("1号", "張三");
yure.put("2号", "李四");
//把學生資訊添加到班級集合
jiuye.put("1号", "張三er");
jiuye.put("2号", "李四er");
//周遊輸出,
Iterator<String> it = school.keySet().iterator();//擷取學校的所有班級資訊
while(it.hasNext()){
String roomName = it.next();//班級名稱--預熱班、就業班
HashMap<String,String> room = school.get(roomName);//班級對應的集合--yure、jiuye
Iterator<String> it1 = room.keySet().iterator();//班級裡學生資訊的學号集合
while(it1.hasNext()){
String id = it1.next();//學号
System.out.println(roomName+id+"::"+room.get(id));
}
}
System.out.println("---------------------------把學生封裝成對象(Student27)實作如下--------------------------------");
demo();
}
public static void demo(){
//把學生資訊儲存到List集合裡,就是說每一個班級對應一個學生的List集合,
//擷取班級資訊後,就可以擷取學生的一個List集合,再疊代這個List集合就可以得到所有學生資訊。
HashMap<String,List<Student27>> hm = new HashMap<String,List<Student27>>();
List<Student27> yure = new ArrayList<Student27>();
List<Student27> jiuye = new ArrayList<Student27>();
hm.put("預熱班", yure);
hm.put("就業班", jiuye);
yure.add(new Student27("1号", "張三"));
yure.add(new Student27("2号", "李四"));
jiuye.add(new Student27("1号", "張三er"));
jiuye.add(new Student27("2号", "李四er"));
Iterator<String> it = hm.keySet().iterator();
while(it.hasNext()){
String roomName = it.next();
List<Student27> room = hm.get(roomName);
Iterator<Student27> it1 = room.iterator();
while(it1.hasNext()){
Student27 stu = it1.next();
System.out.println(roomName+stu.getId()+"::"+stu.getName());
}
}
}
}
//把學号和學生姓名封裝成學生對象--學生類
class Student27 {
private String id;
private String name;
public Student27(String id,String name){
this.id=id;
this.name=name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}