一、Map的講解
Demo1:
package map;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/*
Map集合:該集合存儲鍵值對,一對一對往裡存,而且要保證鍵的唯一性。
1、添加:
put(key,value);
putAll(Map<? extends K,? extends v> m);
2、判斷:
boolean containsKey();
boolean containsValue()
isEmpty();
3、删除:
void clear();
remove(key);
4、擷取:
get(key)
size();
values();
entrySet();
keySet();
Map:
|--Hashtable:底層是哈希表資料結構,不可以存入null鍵和null值。該集合是線程同步的。JDK1.0.效率低。
|--HashMap:底層是哈希表資料結構,允許使用null鍵和null值,該集合是不同步的。JDK1.2.效率高。
|--TreeMap:底層是二叉樹資料結構。線程不同步,可以用于給Map集合中的鍵進行排序。
和Set很像。其實Set底層就是用了Map集合。
*/
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
//添加元素,如果出現添加時,相同的鍵,那麼後添加的值會覆寫原有鍵對應的值。
//并put方法會傳回被覆寫的值。
System.out.println("put:" + map.put("01", "zhangsan1"));
System.out.println("put:" + map.put("01", "wangwu1"));
map.put("02", "zhangsan2");
map.put("03", "zhangsan3");
System.out.println("containsKey:" + map.containsKey("02"));
System.out.println("remove:" + map.remove("02"));
System.out.println("get:" + map.get("01"));
//可以通過get方法的傳回值來判斷一個鍵是否存在。通過傳回null來判斷
map.put(null, "05");
map.put("04", null);
System.out.println("get:" + map.get("04"));
//擷取Map集合中是以的值
Collection<String> coll = map.values();
System.out.println(coll);
System.out.println(map);
}
}
Demo2:
package map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
Map集合的兩種取出方式:
1、Set<K> keySet:将Map中所有的鍵存入到Set集合。因為set具備疊代器。
所有可以疊代方式取出所有的鍵,再根據get方法,擷取每一個鍵對應的值。
Map集合的取出原理:将map集合轉成set集合,再通過疊代器取出。
2、Set<Map.Entry<K,V>> entrySet:将map集合中的映射關系存入到set集合中,
而這個關系的資料類型就是Map.Entry.
*/
/*
Map.Entry:其實Entry也是一個接口,它是Map接口中的一個内部接口。
interface Map{
public static interface Entry{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implements Map{
class Hash implements Map.Entry{
public Object getKey(){}
public Object getValue(){}
}
}
*/
public class MapDemo2 {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("02", "zhangsan2");
map.put("03", "zhangsan3");
map.put("01", "zhangsan1");
map.put("04", "zhangsan4");
//方式二:
//将map集合中的映射關系取出,存入到set集合中。
Set<Map.Entry<String, String>> entrySet = map.entrySet();
Iterator<Map.Entry<String, String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<String, String> me = it.next();
String key = me.getKey();
String value = me.getValue();
System.out.println("key:" + key + ",value:" + value);
}
/*方式一:
//先擷取map集合的所有鍵的set集合,可以keySet();
Set<String> keySet = map.keySet();
//有了Set集合,就可以擷取其疊代器
for(Iterator<String> it = keySet.iterator(); it.hasNext();){
String key = it.next();
//有了鍵可以通過map集合的get方法擷取其對應的值。
String value = map.get(key);
System.out.println("key:" + key + ",value:" + value);
}
*/
}
}
Demo3:
package map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/*
map擴充知識:
map集合被使用是因為具備映射關系。
eg:
方式一:學校集合中有班級與學生的映射關系,班級集合中有學号與學生姓名的映射關系
"yureban" "01" "zhangsan"
"yureban" "02" "lisi"
"jiuyeban" "01" "wangwu"
"jiuyeban" "02" "zhaoliu"
方式二:學校集合中有班級與學生的映射關系,班級集合中有封裝的學生對象
"yureban" Student("01" "zhangsan")
"yureban" Student("02" "lisi")
"jiuyeban" Student("01" "wangwu")
"jiuyeban" Student("02" "zhaoliu")
*/
public class MapDemo3 {
public static void main(String[] args) {
System.out.println("=======方式一:======");
method_1();
System.out.println("\n=======方式二:======");
method_2();
}
//方式二:學校集合中有班級與學生的映射關系,班級集合中有封裝的學生對象
public static void method_2(){
HashMap<String,List<Student1>> school = new HashMap<String,List<Student1>> ();//建立學校集合
List<Student1> yure = new ArrayList<Student1>();//建立班級集合
List<Student1> jiuye = new ArrayList<Student1>();
school.put("yureban", yure);//将班級元素添加到學校集合中(映射關系)
school.put("jiuye", jiuye);
yure.add(new Student1(01,"zhangsan"));//将學生對象添加到班級集合中(沒有映射關系)
yure.add(new Student1(03,"lisi"));
yure.add(new Student1(02,"wangwu"));
jiuye.add(new Student1(01,"xiaozhang"));
jiuye.add(new Student1(02,"xiaowang"));
jiuye.add(new Student1(03,"xiaoli"));
//周遊school集合,擷取所有教室
Iterator<String> it = school.keySet().iterator();
while(it.hasNext()){//采用循環嵌套循環的方式
String roomName = it.next();
List<Student1> room = school.get(roomName);
System.out.println("-----" + roomName + "-----" );
//周遊教室集合,擷取所有學生對象
Iterator<Student1> it1 = room.iterator();
while(it1.hasNext()){
Student1 student = it1.next();
System.out.println(student);
}
}
}
//方式一:學校集合中有班級與學生的映射關系,班級集合中有學号與學生姓名的映射關系
public static void method_1(){
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>();
yure.put("01", "zhangsan");//将班級元素添加的學校集合中(映射關系)
yure.put("02", "lisi");
jiuye.put("01", "wangwu");//将學生元素添加到班級集合中(映射關系)
jiuye.put("02", "zhaoliu");
school.put("yureban", yure);
school.put("jiuyeban", jiuye);
//周遊school集合,擷取所有班級。
Iterator<String> it = school.keySet().iterator();
while(it.hasNext()){
String roomName = it.next();
HashMap<String,String> room = school.get(roomName);
System.out.println("-----" + roomName + "-----" );
//getStudentInfo(room);
//周遊班級集合,擷取學生的id和姓名
Iterator<String> it1 = room.keySet().iterator();
while(it1.hasNext()){
String id = it1.next();
String name = room.get(id);
System.out.println(id + ": " + name);
}
}
}
}
//建立學生類
class Student1{
private String name;
private int id;
Student1(){
}
Student1(int id,String name){//重載構造方法
this.id = id;
this.name = name;
}
@Override
public String toString() {//複寫toString方法
return id + ": " + name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
練習一:
package map.test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
練習:
每一個學生都有對應的歸屬地。
學生Student,位址String
學生屬性:姓名,年齡。
注意:姓名和年齡相同的視為同一個學生,保證學生的唯一性。
思路:
1、描述學生。
2、定義map容器。将學生作為鍵,位址作為值,存入。
3、擷取map集合中的元素。
*/
public class MapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<Student,String> map = new HashMap<Student,String>();
map.put(new Student("zhangsan1",21), "beijing");
map.put(new Student("zhangsan3",23), "shenzhen");
map.put(new Student("zhangsan3",23), "tianjing");
map.put(new Student("zhangsan4",24), "xiamen");
map.put(new Student("zhangsan2",22), "shanghai");
System.out.println("----------------第一種擷取方式--------------");
//方式一:
Set<Student> set = map.keySet();
Iterator<Student> it = set.iterator();
while(it.hasNext()){
Student s = it.next();
System.out.println(s + ",位址:" + map.get(s));
}
System.out.println("----------------第二種擷取方式--------------");
//方式二:
Set<Map.Entry<Student, String>> set1 = map.entrySet();
Iterator<Map.Entry<Student, String>> it1 = set1.iterator();
while(it1.hasNext()){
Map.Entry<Student, String> me = it1.next();
Student s1 = me.getKey();
String addr = me.getValue();
System.out.println(s1 + ",位址:" + addr);
}
}
}
class Student implements Comparable<Student>{
private String name;
private int age;
Student(){
}
Student(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student: 姓名:" + name + ", 年齡:" + age ;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public int compareTo(Student o) {
// TODO Auto-generated method stub
int num = new Integer(age).compareTo(new Integer(o.getAge()));
if(num == 0)
return this.getName().compareTo(o.getName());
return num;
}
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;
}
}
練習二:
package map.test;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/*
練習:
需求:對學生對象的年齡進行升序排序。
因為資料是以鍵值對形式存在的,是以要使用可以排序的Map集合。TreeMap.
*
*/
public class MapTest2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuNameComparator());
tm.put(new Student("zhangsan4",21), "beijing");
tm.put(new Student("zhangsan3",23), "shenzhen");
tm.put(new Student("zhangsan3",24), "wuhan");
tm.put(new Student("zhangsan1",24), "xiamen");
tm.put(new Student("zhangsan2",22), "shanghai");
//按照學生的年齡進行排序
Set<Map.Entry<Student,String>> entrySet = tm.entrySet();
Iterator<Map.Entry<Student,String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Student,String> me = it.next();
Student s = me.getKey();
String addr = me.getValue();
System.out.println(s + " ,位址:" + addr);
}
}
}
class StuNameComparator implements Comparator<Student>{
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
int num = o1.getName().compareTo(o2.getName());
if(num == 0)
return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge()));
return num;
}
}
練習三:
package map.test;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/*
練習:
"abhdehodahbdodscndhwhshdls"擷取該字元串中的字母出現次數。
希望列印的結果是:a(1) c(2).......
思路:
通過結果發現,每個字母都有對應的次數。說明字母和次數之間都有映射關系。
注意:當發現有映射關系時,可以選擇map集合。因為map集合中存放的就是映射關系。
什麼時候使用map集合呢?
當資料之間存在映射關系時,首先就要想到map集合。
思路:
1、将字元串轉換成字元數組,因為要對每一個字母進行操作。
2、定義一個map集合,因為列印結果的字母有順序,是以使用TreeMap集合。
3、周遊字元數組,将每一個字母作為鍵去查map集合,如果傳回空,就将該字母和1存入到map集合中,如果傳回不是空,
說明該字母在map集合内已經存在,并有對應的次數,那麼就擷取該次數并進行自增,然後将該字母和自增後的次數存入
到集合中,覆寫掉原來所對應的值。
4、将map集合中的資料變成指定的字元串傳回。
*/
public class MapTest3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = charCount("abhdeh78odahbd51odscndhwh/.,shdls");
System.out.println(s);
}
public static String charCount(String str){
char[] ch = str.toCharArray();//将字元串轉換成字元數組
TreeMap<Character,Integer> map = new TreeMap<Character,Integer>();//定義一個TreeMap集合,存儲字元并計數
int count = 0;
//周遊字元數組
for(int i = 0; i < ch.length; i++){
//判斷是否是字元,如果不是,跳出此次循環,進入下一個字元,次字元不計數
if(!(ch[i] >= 'a' && ch[i] <= 'z' || ch[i] >='A' && ch[i] <= 'Z'))
continue;
Integer value = map.get(ch[i]);
//判斷字元并存儲:方式二:
if(value != null)
count = value;
count++;
map.put(ch[i], count);
count = 0;
/*//判斷字元并存儲:方式一:
if(value == null)
map.put(ch[i], 1);
else
map.put(ch[i], value + 1);
*/
}
//System.out.println(map);//列印集合内容
//修改集合内元素的輸出方式
StringBuilder sb = new StringBuilder();//定義一個StringBuilder,用來存儲字元數組内的每個元素
Set<Map.Entry<Character,Integer>> entrySet = map.entrySet();//定義一個集合
Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();//定義一個疊代器
while(it.hasNext()){//擷取疊代器裡面的内容,并添加到StringBuilder中
Map.Entry<Character,Integer> me = it.next();
Character c = me.getKey();
Integer i = me.getValue();
sb.append(c + "(" + i + ") ");
}
return sb.toString();//傳回字元串
}
}