Map是java.util包中的接口。
Map集合特点:该集合存储键值对。一对一对的往里存。而且要保证键的唯一性。Map接口中的方法如下:
1.添加
put(K Key,V value)
putAll(Map<? extends K,? extends V> m)
2.删除
clear()
remove(Object key)
3.判断
containsValue(Object value)
containsKey(Object key)
isEmpty()
4.获取
get(Object key):根据键获取值
size()
values():获取所有值的Collection集合
entrySet()
keySet()
Map的子类
|——Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低
|——HashMap:底层是哈希表数据结构,可以存入null键和null值,该集合是不同步的。jdk1.2效率高
|——TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键排序。
Set集合底层用了Map集合
下面分别演示Map集合中的方法:
import java.util.Collection; import java.util.HashMap; import java.util.Map; public class MapDemo { public static void main(String[] args) { Map<String,String> map=new HashMap<String, String>(); map.put("01", "beijing"); map.put("02", "shanghai"); map.put("03", "guangzhou"); map.put("04", "shenzhen"); System.out.println(map); String method="values()"; switch (method) { case "put(K Key,V value)": //如果键相同,则新值覆盖旧值,返回旧值 System.out.println(map.put("02", "haerbin")); System.out.println(map); //如果键不同,则添加新键值对,返回null System.out.println(map.put("05", "haerbin")); System.out.println(map); //null也可以作为键或值存入HashMap集合 map.put(null, null); System.out.println(map); break; case "putAll(Map<? extends K,? extends V> m)": Map<String,String> map2=new HashMap<String, String>(); map2.put("03", "beijing"); map2.put("05", "shanghai"); map.putAll(map2); System.out.println(map); break; case "clear()": map.clear(); System.out.println(map); break; case "remove(Object key)": //remove方法删除键值对,并返回值 System.out.println(map.remove("03")); System.out.println(map); //如果指定的键不存在,则返回null System.out.println(map.remove("05")); break; case "containsKey(Object key)": System.out.println(map.containsKey("01")); break; case "containsValue(Object key)": System.out.println(map.containsValue("guangzhou")); break; case "isEmpty()": System.out.println(map.isEmpty()); map.clear(); System.out.println(map.isEmpty()); break; case "get(Object key)": System.out.println(map.get("01")); map.put(null, "NewYork"); //get方法也可以判断键为null的值 System.out.println(map.get(null)); //如果指定的键对应的值不存在或为null,则返回null System.out.println(map.get("05")); break; case "size()": System.out.println(map.size()); break; case "values()": Collection<String> col=map.values(); System.out.println(col); break; default: break; } } }
学习完本节后,已经学习了1个接口(Map),10个方法。类图如下:
map集合中两种取出所有键值对的方法
1,keySet:返回Set<K>将map中所有的键存入到Set集合。因为Set具备迭代器。所以可以用迭代的方式取出所有键,然后根据get方法。获取每一个键对应的值。
2,entrySet:返回Set<Map.Entry<K,V>>
第一种方式演示代码如下:
public static void demo2(){ Map<String, String> map=new HashMap<String, String>(); map.put("01", "beijing"); map.put("02", "shanghai"); map.put("03", "guangzhou"); map.put("04", "shenzhen"); Set<String> set=map.keySet(); Iterator<String> it=set.iterator(); while(it.hasNext()){ String key=it.next(); //通过map集合get方法取出元素值 System.out.println("key:"+key+" value:"+map.get(key)); } }第二种方式获取键值对演示如下:
public static void demo3(){ Map<String, String> map=new HashMap<String, String>(); map.put("01", "beijing"); map.put("02", "shanghai"); map.put("03", "guangzhou"); map.put("04", "shenzhen"); Set<Map.Entry<String, String>> set=map.entrySet(); Iterator<Map.Entry<String, String>> it=set.iterator(); while (it.hasNext()) { Map.Entry<String, String> entry =it.next(); String key=entry.getKey(); String value=entry.getValue(); System.out.println(key+":"+value); } }下面解释Map.Entry:
interface Map{ public static interface Entry{ public abstract Object getKey(); public abstract Object getValue(); } } class HashMap implements Map{ class MapEntry implements Map.Entry{ public Object getKey(){} public Object getValue(){} } }
Entry接口是Map接口的内部接口,所以才会有Map.Entry接口这种奇怪的写法。Map.Entry在使用时,可以将点看做接口名的一部分,而不必在意实现的具体细节。
本节学习了1个接口(Map.Entry)4个方法。本章到目前共学习2个接口,14个方法,如下图所示:
HashMap类似HashSet,不同之处在与HashMap是双列集合,HashSet是单列集合。HashMap同HashSet一样都是通过hashCode方法和equals方法来保证键的唯一性。
每一个学成都有对应的归属地。学生Student,地址String。学生属性:姓名、年龄、姓名和年龄相同视为同一个学生。保证学生唯一性。
1.描述学生
2.定义map容器。将学生作为键,地址作为值。存入。
3.获取map集合中的元素
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; class People{ int age; String name; @Override public String toString() { return "People [age=" + age + ", name=" + name + "]"; } @Override public int hashCode() { return age*31 + ((name == null) ? 0 : name.hashCode()); } @Override public boolean equals(Object obj) { if (!(obj instanceof People)) { throw new ClassCastException("被比较的类不是People类"); } People people=(People)obj; if (people.getAge()==age&&people.getName().equals(name)) { return true; } return false; } public People(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public String getName() { return name; } } public class HashMapDemo { public static void main(String[] args) { HashMap<People,String> hm=new HashMap<People,String>(); hm.put(new People(21,"lisi01"), "jiangsu"); hm.put(new People(23,"lisi02"), "jiangxi"); hm.put(new People(23,"lisi02"), "fujian"); hm.put(new People(41,"lisi03"), "shanxi"); //第一种遍历方式 Set<People> set=hm.keySet(); Iterator<People> it=set.iterator(); while (it.hasNext()) { People people = it.next(); System.out.println(people+" "+hm.get(people)); } //第二种遍历方式 Set<Map.Entry<People,String>> entry=hm.entrySet(); Iterator<Map.Entry<People,String>> it1=entry.iterator(); while (it1.hasNext()) { Map.Entry<People, String> entry2 = it1.next(); System.out.println(entry2.getKey()+" "+entry2.getValue()); } } }上面的代码演示了HashMap类的用法。Map集合类图如下:
TreeMap类似TreeSet,可以给存入其中的键值对按键排序,可以以两种方式自定义排序,一种是键对象实现comparable接口,一种是创建TreeMap对象时给构造方法传入一个比较器(实现comparator接口的类)。
下面对People类进行改造,使之具有按姓名和年龄排序的自然顺序。
class People implements Comparable<People>{ int age; String name; @Override public String toString() { return "People [age=" + age + ", name=" + name + "]"; } @Override public int hashCode() { return age*31 + ((name == null) ? 0 : name.hashCode()); } @Override public boolean equals(Object obj) { if (!(obj instanceof People)) { throw new ClassCastException("被比较的类不是People类"); } People people=(People)obj; if (people.getAge()==age&&people.getName().equals(name)) { return true; } return false; } public People(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public String getName() { return name; } @Override public int compareTo(People o) { int num=new Integer(age).compareTo(new Integer(o.getAge())); if (num==0) { return name.compareTo(o.name); } return num; } }
上面的代码注意Comparable接口带泛型的用法
然后写一个主函数测试下:
import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; public class TreeMapDemo { public static void main(String[] args) { TreeMap<People,String> hm=new TreeMap<People,String>(); hm.put(new People(21,"lisi01"), "jiangsu"); hm.put(new People(23,"lisi02"), "jiangxi"); hm.put(new People(23,"lisi01"), "fujian"); hm.put(new People(25,"lisi03"), "shanxi"); Set<Map.Entry<People,String>> entry=hm.entrySet(); Iterator<Map.Entry<People,String>> it1=entry.iterator(); while (it1.hasNext()) { Map.Entry<People, String> entry2 = it1.next(); System.out.println(entry2.getKey()+" "+entry2.getValue()); } } }打印结果:
People [age=21, name=lisi01] jiangsu People [age=23, name=lisi01] fujian People [age=23, name=lisi02] jiangxi People [age=25, name=lisi03] shanxi
下面用比较器的方法指定顺序:(先按姓名排序,再按年龄排序)
import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; class PeopleNameComparator implements Comparator<People>{ @Override public int compare(People o1, People o2) { int num=o1.getName().compareTo(o2.getName()); if (num==0) { return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge())); } return num; } } public class TreeMapDemo { public static void main(String[] args) { TreeMap<People,String> hm=new TreeMap<People,String>(new PeopleNameComparator()); hm.put(new People(21,"java03"), "jiangsu"); hm.put(new People(24,"java01"), "jiangxi"); hm.put(new People(23,"java07"), "fujian"); hm.put(new People(25,"java02"), "shanxi"); Set<Map.Entry<People,String>> entry=hm.entrySet(); Iterator<Map.Entry<People,String>> it1=entry.iterator(); while (it1.hasNext()) { Map.Entry<People, String> entry2 = it1.next(); System.out.println(entry2.getKey()+" "+entry2.getValue()); } } }运行结果:
People [age=24, name=java01] jiangxi People [age=25, name=java02] shanxi People [age=21, name=java03] jiangsu People [age=23, name=java07] fujian上面的代码,注意Comparator带泛型的用法。
“ a;sdkfja;ksdjfpiajewporfikj;adkjnvfa;skeirjf"获取该字符串中字母出现的次数。
希望打印结果:a(1)c(2)....
通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间有映射关系。于是使用Map集合。
当数据之间存在映射关系时,就要首先想到Map集合。
思路:
1.将字符串转换成字符数组。因为要对每一个字母进行操作。
2.定义一个Map集合,因为打印结构的字母有顺序,所以使用TreeMap集合
3.遍历字符数组。
将每一个字母作为键取查Map集合
如果返回null,将该字母和1存入Map集合中。
如果返回不是null,说明该字母在Map集合中已经存在并有对应次数。
那么就获取该字数自增。然后将该字母和自增后的次数存入Map集合中。覆盖掉原来键对应的值
4.将Map集合中的数据编程指定的字符串格式返回。
代码如下:
import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; public class TreeMapDemo2 { public static void main(String[] args) { System.out.println(getCharCount("asdffasdfj;akjewo[hfaeswdf")); } public static String getCharCount(String str){ StringBuilder sb=new StringBuilder(); TreeMap<Character,Integer> tree=new TreeMap<Character,Integer>(); char[] chars=str.toCharArray(); for (int i = 0; i < chars.length; i++) { if (chars[i]>='a'&&chars[i]<='z') { Integer value=tree.get(chars[i]); tree.put(chars[i],value==null?1:++value); } } Set<Map.Entry<Character, Integer>> set=tree.entrySet(); Iterator<Map.Entry<Character, Integer>> it=set.iterator(); while (it.hasNext()) { Map.Entry<Character, Integer> entry = (Map.Entry<Character, Integer>) it.next(); sb.append(entry.getKey()+"("+entry.getValue()+")"); } return sb.toString(); } }
现有以下数据:
“预热班” “01” “张三”
“预热班” “02” “李四”
“就业班” “01” “王五”
“赵六” “02” “赵六”
请用嵌套集合保存数据,并打印:
Map集合与List集合嵌套,代码如下
import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; class Trainer{ int stuNo; String name; public Trainer(int stuNo, String name) { this.stuNo = stuNo; this.name = name; } public int getStuNo() { return stuNo; } public String getName() { return name; } } public class NestedList { public static void main(String[] args) { //<班级名,学生集合> Map<String,List<Trainer>> school=new HashMap<String,List<Trainer>>(); List<Trainer> students1=new ArrayList<Trainer>(); students1.add(new Trainer(01, "张三")); students1.add(new Trainer(02, "李四")); List<Trainer> students2=new ArrayList<Trainer>(); students2.add(new Trainer(01, "王五")); students2.add(new Trainer(02, "赵六")); school.put("预热班", students1); school.put("就业班", students2); //打印数据 Set<Map.Entry<String,List<Trainer>>> set=school.entrySet(); Iterator<Map.Entry<String,List<Trainer>>> it=set.iterator(); while(it.hasNext()){ Map.Entry<String,List<Trainer>> entry=it.next(); System.out.println(entry.getKey()); List<Trainer> trainers=entry.getValue(); Iterator<Trainer> iter=trainers.iterator(); while (iter.hasNext()) { Trainer trainer =iter.next(); System.out.println(trainer.getStuNo()+" "+trainer.getName()); } } } }
Map集合与Map集合嵌套,代码如下
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class NestedMap { public static void main(String[] args) { //<班级名,学生集合> Map<String,Map<Integer,String>> school=new HashMap<String,Map<Integer,String>>(); Map<Integer,String> students1=new HashMap<Integer,String>(); students1.put(01, "张三"); students1.put(02, "李四"); Map<Integer,String> students2=new HashMap<Integer,String>(); students2.put(01, "王五"); students2.put(02, "赵六"); school.put("预热班", students1); school.put("就业班", students2); //打印数据 Set<Entry<String, Map<Integer, String>>> set=school.entrySet(); Iterator<Entry<String, Map<Integer, String>>> it=set.iterator(); while(it.hasNext()){ Entry<String, Map<Integer, String>> entry=it.next(); System.out.println(entry.getKey()); Map<Integer, String> trainers=entry.getValue(); Iterator<Entry<Integer, String>> iter=trainers.entrySet().iterator(); while (iter.hasNext()) { Entry<Integer, String> trainer =iter.next(); System.out.println(trainer.getKey()+" "+trainer.getValue()); } } } }