Map:存储键值对。Key,Value
HashMap:key无序散列存放,key唯一。
1.添加:put(key,value);
2.删除:remove(key) clear();
3.修改:put(key,value),覆盖之前key对应的value值;
4.查找:containsKey,containsValue;
package day10.map; import java.util.*; publicclass TestHashMap { publicstaticvoid main(String[] args) { Map<String,String> map = new HashMap<String,String>(); map.put("name", "zhangsan"); map.put("password","123456"); map.put("email", "zhangsan@anjoyo.com"); map.put(null, null);// HashMap中key和value都支持null // 把zhangsan覆盖掉了。 map.put("name", "guanyu"); // 按key删除 map.remove("name"); System.out.println(map); // map中是否包含该value System.out.println(map.containsValue("zhangsan")); // map中是否包含该key System.out.println(map.containsKey("email")); } } |
运行结果: {null=null, email=zhangsan@anjoyo.com, password=123456} false true |
5.取出:Map是没有迭代器,只能利用Set中的迭代器。
a)如果知道key,用get(key)
b)不知道,需要迭代所有key。
Set<String> set = map.keySet(); Iterator<String> it = set.iterator(); while(it.hasNext()){ // 取key String key = it.next(); // 根据key取value String value = map.get(key); System.out.println(key+":"+value); } |
或者根据其内部类来取出所有的key和value:
// 获得Map中存放键值对的内部接口集合。 Set<Map.Entry<String, String>> entry = map.entrySet(); // 迭代该集合 Iterator<Map.Entry<String, String>> entryIt = entry.iterator(); while(entryIt.hasNext()){ // 获得一个个的键值对对象 Map.Entry<String, String> me = entryIt.next(); // 在键值对对象中取key String key = me.getKey(); // 在键值对对象中取value String value = me.getValue(); System.out.println(key+":"+value); } |
如果只想得到所有的value,也可以通过下面的方法:
// 如果只需要value values方法获得map中的所有值(value) Collection<String> col = map.values(); // 迭代所有值(value)。 Iterator<String> colIt = col.iterator(); while(colIt.hasNext()){ // 获得一个个的值 String value = colIt.next(); System.out.println("value:"+value); } |
练习:
模拟用户注册的过程
要求输入用户名、密码、密码确认、email
每项分别输入,判断输入格式是否正确(用户名5-8,密码6-8,邮箱)
若输入格式错误,重新输入,直到格式正确,放入HashMap中
注册完毕后,用HashMap中的数据构造一个User对象,打印该用户信息
注册类代码如下:UserRegist.java |
package day10.map.regist; import java.util.HashMap; import java.util.Map; import java.util.Scanner; /** * 模拟用户注册过程 */ publicclass UserRegist { publicstaticvoid main(String[] args) { Scanner scan = new Scanner(System.in); // HashMap用于存放键值对信息。 Map<String,String> map = new HashMap<String,String>(); for(;;){ System.out.println("请输入用户姓名:"); String name = scan.next(); if(name.matches("[a-zA-Z0-9_]{5,8}")){ // 正则表达式的使用 map.put("name",name); break; }else{ System.out.println("用户名格式错误!"); } } for(;;){ // 如果重复密码输入错误,也即两次录入不等,密码也要重新输入。 String password = ""; for(;;){ System.out.println("请输入用户密码:"); password = scan.next(); if(password.matches("[a-zA-Z0-9_]{6,8}")){ // 密码和重复密码都确认后再存储 break; }else{ System.out.println("密码格式错误!"); } } String repassword = ""; for(;;){ // 重复密码格式不对,重新录入重复密码 System.out.println("请重复用户密码:"); repassword = scan.next(); if(repassword.matches("[a-zA-Z0-9_]{6,8}")){ break; }else{ System.out.println("重复密码格式错误!"); } } if(password.equals(repassword)){ // 密码和重复密码都确认后再存储 map.put("password",password); break; }else{ System.out.println("两次录入不一致"); } } for(;;){ System.out.println("请输入用户邮箱:"); String email = scan.next(); if(email.matches("[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\\.com|\\.cn)")){ map.put("email", email); break; }else{ System.out.println("邮箱格式错误!"); } } // System.out.println(map); // 通过get(key)取出value,构建user对象。 User user = new User(map.get("name"),map.get("password"),map.get("email")); System.out.println(user); } } |
HashMap和Hashtable区别:
1.和ArrayList/Vector StringBuiler/StringBuffer一样。
2.HashMap中的key和value都可以是null,Hashtable不可以。
测试如下
TestHashMap.java |
Map<String,String> map = newHashMap<String,String>(); map.put("name", "zhangsan"); map.put(null, null); System.out.println(map); |
运行结果: |
{null=null, name=zhangsan} |
如果是Hashtable:
TestHashtable.java |
Map<String,String> map = newHashtable<String,String>(); map.put("name", "zhangsan"); map.put(null, null); System.out.println(map); |
运行结果: java.lang.NullPointerException |
HashMap中containsKey按照hashcode和equals查找,containsValue根据equals查找。
TreeMap:可排序的map,按照key值排序,key需要具有可比较性。
package day10.map; import java.util.*; publicclass TestTreeMap { publicstaticvoid main(String[] args) { Map<String,User> map = new TreeMap<String,User>(); User user1 = new User("zhangsan","123456","zhangsan@163.com"); User user2 = new User("lisi","654321","lisi@163.com"); User user3 = new User("wangwu","123654","wangwu@163.com"); map.put("one", user1); map.put("two", user2); map.put("three", user3); // 利用集合中的迭代器取出所有元素。 Set<String> set = map.keySet(); Iterator<String> it = set.iterator(); while(it.hasNext()){ String key = it.next(); // 取出的每一个value是User类型的对象。 User value = map.get(key); System.out.println(key+":"+value.getName()); } } } |
输出结果: one:zhangsan three:wangwu two:lisi |
可以看到,one、three、two是按String的compareTo排序之后的结果。
如果我们自己写一个类来做key值,要求这个类对象具有可比较性。
具有可比较性的两种方法在此不再详述。不过,
一般来说,都是八种封装类或String做key。
Arrays:操作数组的工具类。
Arrays.sort():完成数组的排序,要求数组元素可比较性。
Collections:集合操作相关的工具类。
Collections.sort():完成集合的排序。要求集合元素可比较性。
copy、max、min、reverse、synchronizedXxx等方法。