Java中的Map
来源:互联网 发布:互联网mysql开发规范 编辑:程序博客网 时间:2024/06/05 20:09
在前面的博文中提到的Collection集合是单列集合,但是在现实生活中,也会有双列集合,其中的数据是存在映射关系的,也就是所谓的“键—值”对
Map接口:是双列集合的最顶层接口,其中数据都是以键值对的形式存储的,其中键值是不能重复的,而且每个键值最多映射到一个值,值可以重复。
每次存储都是存储一对元素
—–>HashMap、TreeMap、HashTable
与Collection在集合框架中并列存在
interface Map<K,V>K - 此映射所维护的键的类型V - 映射值的类型
Map的通用性方法:
1、添加:
1、V put(K key, V value) (可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null) (其中的键&值都可以是null) 2、`putAll(Map<? extends K,? extends V> m)` 从指定映射中将所有映射关系复制到此映射中(可选操作)。
2、删除
1、remove() 删除关联对象,指定key对象2、clear() 清空集合对象
3、获取
1:value get(key); 可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null。
4、判断:
1、boolean isEmpty() 长度为0返回true否则false2、boolean containsKey(Object key) 判断集合中是否包含指定的key3、boolean containsValue(Object value) 判断集合中是否包含指定的value
4、长度:
Int size()
下面着重说一下Map迭代的方法
1.Set<K> keySet()
:返回包含所有键值的Set集合对象,然后通过遍历Set集合获取Map的所有键值
2.Collection<V> values()
:获取包含所有值的的Collection集合对象,只能获得值,并不能或者键
上述两种方式要么就返回键,要么就返回值,那么我们就会想到有没有一种方式是可以返回键和值呢?
那就是通过定义一个类,其中这个类包含键和值就可以了!
class Entry<K,V>{ K key; V value;}ArrayList<Entry> list = new ArrayList<Entry>();list.add(New Entry("key","value"));
3.Map.Entry对象:那么在Map中确实存在一个内部静态类Entry,其中存储了键和值。其中Entry类使用了自定义泛型。
下面的示例使用了上述三种方式进行了Map的遍历
import java.util.*;/** * Created by Dream on 2017/10/27. */public class MapSee { public static void main(String[] args){ Map<String,String> map = new HashMap<>(); map.put("Dream","11"); map.put("Thia","22"); map.put("Maria","33"); /*方式一遍历:获得键,然后通过键获得值*/ Set<String> set = map.keySet(); Iterator<String> it = set.iterator(); while(it.hasNext()){ String key = it.next(); System.out.println("Key:"+key+" Value:"+map.get(key)); } /*方式二遍历:只能获得值*/ Collection<String> collection = map.values(); it = collection.iterator(); while(it.hasNext()){ System.out.print(it.next()+" "); } System.out.println(); /*方式三:利用Map的静态内部类Entry*/ Set<Map.Entry<String,String>> list = map.entrySet(); Iterator<Map.Entry<String,String>> its = list.iterator(); while(its.hasNext()){ Map.Entry<String,String> entry = its.next(); System.out.println("Key:"+entry.getKey()+" Value:"+entry.getValue()); } System.out.println("========直接输出Map======="); System.out.println(map); }}
具体实现类:
HashMap:底层的实现原理跟HashSet类似,都是通过哈希表来存储的,HashSet存储的是一个对象,而HashMap存储的是一对数据,不仅存储对象,还存储对象的值!
实现原理:底层是通过哈希表存储的,每次存储一对数据,即“键–值”的时候,首先会调用“键”的hashCode()方法,然后经过一系列运算得到该“键”及其“值”存放的位置,如果该位置上没有数据存放,那么直接将该数据存放在该位置上即可;如果该位置上已经有数据存在,那么会调用“键”的equals方法比较两个“键”是否相同,如果equals返回的是true,那么则视为相同的“键”,此时不再将该“键”所在的数据对添加到该位置上,只是将该“键”所对应的值“覆盖”原先的值,即所谓的“后来者居上”;如果equals返回false,那么该对象允许被存储。至于hashCode方法和equals方法的定义,按需更改!
小示例:
package BasicObject.day17;import java.util.*;/** * Created by Dream on 2017/10/31. */class Employee{ String name; int age; public Employee(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "[name:"+name+", age:"+age+"]"; } public int hashCode(){ return this.name.hashCode(); } public boolean equals(Object o){ Employee e = (Employee)o; return this.name.equals(e.name) && this.age == e.age; }}public class hashMapPrac { public static void main(String[] args){ HashMap<Employee,String> employees = new HashMap<>(); employees.put(new Employee("Sara",21),"1001"); employees.put(new Employee("Mary",21),"2002"); employees.put(new Employee("Thia",23),"3003"); employees.put(new Employee("Tom",25),"4004"); employees.put(new Employee("Eric",23),"5005"); employees.put(new Employee("Sara",21),"6666"); //重写了hashCode和equals方法,所以此键值会覆盖Sara第一次出现的键值 System.out.println(employees); /*通过获取键来获取其对应的值 Set<Employee> set = employees.keySet(); Iterator<Employee> it = set.iterator(); while(it.hasNext()){ Employee e = it.next(); System.out.print(e+"=="+employees.get(e)+","); }*/ /*仅能获取值 Collection<String> collection = employees.values(); Iterator<String> it = collection.iterator(); while(it.hasNext()){ System.out.print(it.next()+","); }*/ /*通过entrySet获得全部的键和值*/ Set<Map.Entry<Employee,String>> set = employees.entrySet(); Iterator<Map.Entry<Employee,String>> it = set.iterator(); while(it.hasNext()){ Map.Entry<Employee,String> entry = it.next(); System.out.println(entry.getKey()+"=="+entry.getValue()); } }}
输出结果:
{[name:Tom, age:25]=4004, [name:Eric, age:23]=5005, [name:Sara, age:21]=6666, [name:Thia, age:23]=3003, [name:Mary, age:21]=2002}
[name:Tom, age:25]==4004
[name:Eric, age:23]==5005
[name:Sara, age:21]==6666
[name:Thia, age:23]==3003
[name:Mary, age:21]==2002
TreeMap:跟TreeSet的实现原理类似,也是基于红黑树(二叉树)实现的,会对元素的“键”进行排序存储
实现原理:底层基于红黑树实现,左小有大。既然有排序,那么就需要定义一种比较规则!
1.如果存储的数据的“键”具有自然顺序,那么会按照“键”的自然顺序排序;
2.如果“键”不具备自然顺序,那么“键”所在的类需要实现Comparable接口,把比较规则写在compareTo(Object o)方法上
3.如果“键”不具备自然顺序,而且“键”所在的类也没有实现Comparable接口,那么在创建TreeMap对象的时候,就需要传入一个比较器,将规则定义在compare(Object o1,Object o2)方法内。
存储键—值对时,如果键发生冲突,即存储的键在容器中已经存在,那么后添加的值会覆盖前面所存储的值,简记为后来者居上!
HashTable:与HashMap的方法和底层实现原理是一样的,唯一的不同除了前者在JDK1.0出现,后者在JDK1.2出现,最大的区别在于HashTable是同步的,线程安全的,但是效率低;而HashMap是不同步的,线程非安全的,但是效率高。后者的出现就是为了替代HashTable,因为大部分情况下是不会发生线程安全问题,为了追求效率,大部分情况下使用即使HashMap,即使出现线程非安全问题,我们也可以通过工具类Collections中的方法来实现(具体应用见下一篇博文)
小示例:
package BasicObject.day17;import java.util.Comparator;import java.util.TreeMap;/** * Created by Dream on 2017/10/31. */class Person implements Comparable<Person>{ int id; String name; public Person(int id,String name){ this.id = id; this.name = name; } public String toString(){ return "[id:"+id+","+"name:"+name+"]"; } @Override /*返回值:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象*/ public int compareTo(Person o) { /*按照id从小到大排列*/ return this.id - o.id; }}class MyComparator implements Comparator<Person>{ /*随第一个参数小于、等于或大于第二个参数而分别返回负整数、零或正整数*/ public int compare(Person p1,Person p2){ /*按照id从大到小排列*/ return p2.id - p1.id; }}public class TreeMapPrac { public static void main(String[] args){ /*存储的数据是具有自然顺序的键 TreeMap map = new TreeMap(); map.put(1,"1"); map.put(3,"3"); map.put(9,"9"); map.put(2,"2"); map.put(0,"0"); 输出结果:{0=10, 1=1, 2=2, 3=3, 9=9} */ /*存储的键是不具备自然顺序的*/ MyComparator comparator = new MyComparator(); TreeMap<Person,String> map = new TreeMap<>(comparator); map.put(new Person(1001,"Dream"),"1001"); map.put(new Person(4004,"Mary"),"4004"); map.put(new Person(2002,"Amy"),"2002"); map.put(new Person(1001,"Thia"),"6666"); map.put(new Person(3003,"Maria"),"3003"); System.out.println(map); }}
输出结果:
{[id:4004,name:Mary]=4004, [id:3003,name:Maria]=3003, [id:2002,name:Amy]=2002, [id:1001,name:Dream]=6666}
上述示例中即利用了实现Comparable接口,也实现了自定义的比较器,当对一个TreeMap对象同时使用时,比较器的优先级会更高一点!
- JAVA中的Map
- java中的map
- java中的Map
- java中的Map
- java中的Map
- java中的Map接口
- java 中的map
- java中的map接口
- Java中的Map
- java中的Map集合
- java中的Map用法
- Java中的Map
- java中的hash map
- Java中的Map遍历
- Java 中的map
- Java中的Map集合
- Java中的Map总结
- Java中的Map
- NSFZOJ #1057. 【NOIP2015】信息传递
- Linux ALSA音频应用
- Java中可作为gc root 的对象有哪些?
- Where to Run LightOJ
- 第五周 项目二 建立链栈算法库
- Java中的Map
- hive常用函数
- 最全团队管理手册
- 顶级性能配置+HiFi Xplay6全面提升手游视听体验
- 用mapreduce去访问文件中每个用户的用户名
- 汇聚全球物联网精英 COMPUTEX助攻万物互联商机
- 再次高喊启动上市 Airbnb新融资股东显露中方资本身影
- Boom-Shakalaka 深度剖析锂电池爆炸原理
- ofo上海免押金:芝麻信用需达650分