黑马程序员——集合框架之Map

时间:2023-02-18 15:34:40
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Map集合特点:该集合存储键值对,一对一对的往里存,并且键是唯一的。
Map: Hashtable 底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的 
hashmap   底层是哈希表数据结构,允许使用null值和null键,是不同步的,效率高
TreeMap   底层是二叉树结构,线程不同步,可以用于给Map集合中的键进行排序。

1、添加。 
1)put(key,value):当存储的键相同时,新的值会替换老的值,并将老值返回。如果键没有重复,返回null; 2)void putAll(Map);
2、删除。 
1)void clear():清空  2)value remove(key) :删除指定键。 
3、判断。 
1)boolean isEmpty():  2)boolean containsKey(key):是否包含key  3)boolean containsValue(value) :是否包含value 
4、取出。 
1)int size():返回长度  2)value get(key) :通过指定键获取对应的值。如果返回null,可以判断该键不存在。当然有特殊情况,就是在hashmap集合中,是可以存储null键null值的。  3)Collection values():获取map集合中的所有的值。 
5、想要获取map中的所有元素: 
原理:map中是没有迭代器的,collection具备迭代器,只要将map集合转成Set集合,可以使用迭代器了。之所以转成set,是因为map集合具备着键的唯一性,其实set集合就来自于map,set集合底层其实用的就是map的方法。

把map集合转成set的方法:
1)Set<k> keySet();将map中所有的键存到Set集合。
2)Set<k,value> entrySet();/取的是键和值的映射关系。
Entry就是Map接口中的内部接口;
为什么要定义在map内部呢?entry是访问键值关系的入口,是map的入口,访问的是map中的键值对。

取出map集合中所有元素的方式一:keySet()方法。可以将map集合中的键都取出存放到set集合中。对set集合进行迭代。迭代完成,再通过get方法对获取到的键进行值的获取。
public class MapDemo {

public static void main(String[] args) {

Map<Integer,String> map = new HashMap<Integer,String>();
method_2(map);
}
public static void method_2(Map<Integer,String> map){

map.put(8,"zhaoliu");
map.put(2,"zhaoliu");
map.put(7,"xiaoqiang");
map.put(6,"wangcai");

//取出map中的所有元素。
//原理,通过keySet方法获取map中所有的键所在的Set集合,在通过Set的迭代器获取到每一个键,
//在对每一个键通过map集合的get方法获取其对应的值即可。
Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator();
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key+":"+value);

}
}
}
取出map集合中所有元素的方式二:entrySet()方法。
public class MapDemo {

public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method_2(map);
}
public static void method_2(Map<Integer,String> map){

map.put(8,"zhaoliu");
map.put(2,"zhaoliu");
map.put(7,"xiaoqiang");
map.put(6,"wangcai");

/*
* 通过Map转成set就可以迭代。
* 找到了另一个方法。entrySet。
* 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型(结婚证)
*/
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();

Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();

while(it.hasNext()){
Map.Entry<Integer, String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::::"+value);

}
}
}

Map练习:
/*
每一个学生都有对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。

1,描述学生。
2,定义map容器。将学生作为键,地址作为值。存入。
3,获取map集合中的元素。
*/
import java.util.*;
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}

public int compareTo(Student s){
int num = new Integer(this.age).compareTo(new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}

public int hashCode(){
return name.hashCode()+age*34;
}
public boolean equals(Object obj){
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.age==s.age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String toString(){
return name+":"+age;
}
}
public class  MapTest{public static void main(String[] args) {HashMap<Student,String> hm = new HashMap<Student,String>();hm.put(new Student("lisi1",21),"beijing");hm.put(new Student("lisi1",21),"tianjin");hm.put(new Student("lisi2",22),"shanghai");hm.put(new Student("lisi3",23),"nanjing");hm.put(new Student("lisi4",24),"wuhan");//第一种取出方式 keySetSet<Student> keySet = hm.keySet();Iterator<Student> it = keySet.iterator();while(it.hasNext()){Student stu = it.next();String addr = hm.get(stu);System.out.println(stu+".."+addr);}//第二种取出方式 entrySetSet<Map.Entry<Student,String>> entrySet = hm.entrySet();Iterator<Map.Entry<Student,String>> iter = entrySet.iterator();while(iter.hasNext()){Map.Entry<Student,String> me = iter.next();Student stu = me.getKey();String addr = me.getValue();System.out.println(stu+"........."+addr);}}}
TreeMap练习:需求:对学生对象的年龄进行升序排序。
因为数据是以键值对形式存在的。所以要使用可以排序的Map集合。TreeMap。
public class StuNameComparator implements Comparator<Student>{
public int compare(Student s1,Student s2){
int num = s1.getName().compareTo(s2.getName());
if(num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
return num;
}
}
public class  MapTest2{public static void main(String[] args) {TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuNameComparator());tm.put(new Student("blisi3",23),"nanjing");tm.put(new Student("lisi1",21),"beijing");tm.put(new Student("alisi4",24),"wuhan");tm.put(new Student("lisi1",21),"tianjin");tm.put(new Student("lisi2",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 stu = me.getKey();String addr = me.getValue();System.out.println(stu+":::"+addr);}}}
TreeMap练习:"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。希望打印结果:a(1)c(2).....
/*
通过结果发现,每一个字母都有对应的次数。说明字母和次数之间都有映射关系。
注意了,当发现有映射关系时,可以选择map集合。因为map集合中存放就是映射关系。
什么使用map集合呢?当数据之间存在这映射关系时,就要先想map集合。
思路:
1,将字符串转换成字符数组。因为要对每一个字母进行操作。
2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3,遍历字符数组。
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合已经存在并有对应次数。
那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。
4,将map集合中的数据变成指定的字符串形式返回。
*/

public class MapTest3{
public static void main(String[] args) {
String s= charCount("ak+abAf1c,dCkaAbc-defa");
System.out.println(s);
}

public static String charCount(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)
count = value;
count++;
tm.put(chs[x],count);//直接往集合中存储字符和数字,为什么可以,因为自动装箱。
count = 0;
}

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();
}
}