接口Map<K,V>,K – 映射所维护的键的类型;V – 映射值的类型。
public interface Map<K,V>,将键映射到值的对象。一个映射不能包括重复的键;每个键只能映射到一个值。(一对一)
方法:
1. 添加
V put(K key, V value);Put方法返回键对应原来的值,并且对同一个键使用了两次或者多次put方法,则新的值替换旧的值。
void putAll(Map<? Extends K, ? Extends V> m)
2. 删除
void clear();
V remove(Object key)
3. 判断
a) boolean containsKey(Object key)
b) boolean containsValue(Object value)
c) boolean equals(Object o)
d) boolean isEmpty()
4. 获取
V get(Object key);通过键获取值
Int size()
V values()
Set<Map.Entry<K,V>> entrySet()
Set<K> keyset()
Map的三个子接口:Hashtable HashMap TreeMap:
Hashtable:底层是哈希表数据结构,不可以存入null键null值。线程同步的。
HashMap: 基于哈希表的Map子接口。允许使用null键和null值,该集合是线程非同的。
TreeMap: 底层是二叉树数据接口,线程不同步。可以用于给Map集合中的键进行排序。
Set集合底层其实就是用了Map集合。
Map集合的两种取出方式:
1. keyset:将Map中所有的键存入到Set集合,因为Set集合具备迭代器,所以可以通过迭代方式取出所有的键,获取每一个键对应的值。
package Day16; import java.util.*; public class MapDemo1 { public static void main(String[] args){ Map<String,String> map = new HashMap<String,String>(); //添加 map.put("01","zhangsan"); map.put("02","lisi"); map.put("03","wangwu"); // System.out.println("ContainsKe y:"+map.containsKey("02")); //System.out.println("Remove:"+map.remove("022"));//删除 //System.out.println("Remove:"+map.remove("02"));//删除 //System.out.println("Get:"+map.get("02"));//获取 // Collection<String> coll = map.values(); // System.out.println(coll); //先获取map集合的所有键的Set集合,keySet(); Set<String> keySet = map.keySet(); //有了set集合,即可以获取迭代器取出所有键 for (Iterator<String> it = keySet.iterator();it.hasNext();){ //System.out.print("key:"+it.next()+","); //有了键就可以通过map集合的get方法获取其对应的值 System.out.println("vaule:"+map.get(it.next())); } }
}
2. Set<Map.Entry<K,V>> entrySet:将Map集合中的映射关系存到Set集合中,而这个关系的数据类型就是:Map.Entry
package Day16; import java.util.*; public class EntryMap { public static void main(String[] args){ Map<String,String> map = new HashMap<String,String>(); map.put("01","zhangsan"); map.put("03","wangwu"); map.put("04","zhaoliu"); map.put("02","lisi"); //将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();//Entry中的方法 String value = me.getValue();//Entry中的方法 System.out.println("Key:"+key+",Value:"+value); } } }
Map.Entry其实Entry也是一个接口,他是Map接口的一个内部接口。
练习一:
/* * 练习: 1,描述学生 2,定义Map容易,将学生作为键,地址作为值存入 3,获取map集合中的元素 */ package Day16; import java.util.*; public class MapTest { public static void main(String[] args){ HashMap<Student,String> hm = new HashMap<Student,String>(); hm.put(new Student("张三",19),"北京" ); hm.put(new Student("李四",18),"天津" ); hm.put(new Student("王武",25),"上海" ); hm.put(new Student("王武",25),"武汉" );//因为键唯一,所以武汉会覆盖之前的上海 //第一种取出方式 可以Set System.out.println("=======使用Set取出======"); Iterator<Student> it = hm.keySet().iterator(); while (it.hasNext()) { Student s = it.next(); String addr = hm.get(s); System.out.println(s+"..."+addr); } //第二种取出方式entrySet System.out.println("=======使用entrySet取出======"); Iterator<Map.Entry<Student,String>> iter = hm.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Student,String> me = iter.next(); Student s = me.getKey(); String addr = me.getValue(); System.out.println(s+"---"+addr); } } } class Student implements Comparable<Student> { private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } @Override public String toString() { return name+":"+age; } @Override public int hashCode() { return name.hashCode()+age*12; } @Override 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; } @Override 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; } }
运行结果:
=======使用Set取出====== 张三:19...北京 李四:18...天津 王武:25...武汉 =======使用entrySet取出====== 张三:19---北京 李四:18---天津 王武:25---武汉
当数据之间存在映射关系时,就要先想到Map集合。
/* * 练习二: “sdfgzxcvasdfxcvdf”获取该字符串中的字母出现的次数 希望打印结果:a(1)c(2)... 通过结果发现每个字母都有对应的次数,说明字母和次数之间都有映射关系。 思路: 1,将字符串转换成字符数组,因为要对每一个字母进行操作 2,定义MAP集合,因为打印结果的字母是有顺序的,所以使用TreeMap集合 3,遍历字符数组将每一个字母作为键去查Map集合,如果返回null将该字母和1存入到Map集合中;如果返回不是空则说明该字母在Map集合内已经存在并有对应的次数,那么该次数自增后覆盖存入; 4,将Map集合中的数据变成指定的字符串形式返回 */ package Day16; import java.util.*; public class MapTest2 { public static void main(String[] args){ String s = charCount("sdfgzxcvasdfxcvdf"); 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; } //System.out.println(tm); 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(); } }
运行结果:
a(1)c(2)d(3)f(3)g(1)s(2)v(2)x(2)z(1)