Java Map接口用法详解
Map 接口的定义为:
public interface Map<K, V>{}Map 接口定义时使用了泛型,并且定义了两个泛型 K 和 V,K 表示 key,规定了键元素的数据类型,V 表示 value,规定了值元素的数据类型,Map 接口中的方法如下表所示。
方 法 | 描 述 |
---|---|
int size() | 获取集合长度 |
boolean isEmpty() | 判断集合是否为空 |
boolean containsKey(Object key) | 判断集合中是否存在某个 key 值 |
boolean containsValue(Object value) | 判断集合中是否存在某个 value 值 |
V get(Object key) | 取出集合中 key 对应的 value 值 |
v put(K key, V value) | 向集合中存入一组 key-value 的元素 |
V remove(Object key) | 删除集合中 key 对应的 value 值 |
void putAII(Map<? extends K, ? extends V>m) | 向集合中添加另外一个 Map 集合 |
void clear() | 清除集合中的所有元素 |
Set<K> keySet() | 取出集合中所有的 key,返回一个 Set 集合 |
Collection<V> values() | 取出集合中所有的 value,返回一个 Collection 集合 |
Set<Map.Entry<K, V>> entrySet() | 将 Map 对象转换为 Set 对象 |
int hashCode() | 获取集合的散列值 |
boolean equals(Object o) | 比较两个集合是否相等 |
Map接口的实现类
Map 是一个接口,在实际开发中需要使用 Map 必须通过其实现类来完成实例化操作,Map 接口常用的实现类如下所示:- HashMap:存储一组无序,key 不可重复,但 value 可重复的元素。
- Hashtable:存储一组无序,key 不可重复,但 value 可重复的元素。
- TreeMap:存储一组有序,key 不可重复,但 value 可重复的元素,可以按照 key 来排序。
HashMap 是 Map 接口的一个常用实现类,定义如下所示:
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> Cloneable, Serializable{}下面的程序演示了 HashMap 的用法。
public class Test { public static void main(String[] args) { HashMap<String,String> hashMap = new HashMap<String,String> (); hashMap.put("h", "Hello"); hashMap.put("w", "World"); hashMap.put("j", "Java"); hashMap.put("s", "JavaSE"); hashMap.put("m", "JavaME"); hashMap.put("e", "JavaEE"); System.out.println(hashMap); hashMap.remove("e"); System.out.println("删除之后:"+hashMap); hashMap.put("m", "Model"); System.out.println("添加之后:"+hashMap); if(hashMap.containsKey("a")) { System.out.println("集合中存在值为a的key"); }else { System.out.println("集合中不存在值为a的key"); } if(hashMap.containsValue("Java")) { System.out.println("集合中存在值为Java的value"); }else { System.out.println("集合中不存在值为Java的value"); } Set keys = hashMap.keySet(); Iterator keysIterator = keys.iterator(); System.out.print("集合中的key:"); while(keysIterator.hasNext()) { String key = (String) keysIterator.next(); System.out.print(key+","); } Collection values = hashMap.values(); Iterator valuesIterator = values.iterator(); System.out.print("集合中的value:"); while(valuesIterator.hasNext()) { String value = (String) valuesIterator.next(); System.out.print(value+","); } System.out.print("key-value:"); keysIterator = keys.iterator(); while(keysIterator.hasNext()) { String key = (String) keysIterator.next(); String value = hashMap.get(key); System.out.print(key+"-"+value+","); } } }运行结果为:
{h=Hello, w=World, j=Java, s=JavaSE, m=JavaME, e=JavaEE}
删除之后:{h=Hello, w=World, j=Java, s=JavaSE, m=JavaME}
添加之后:{h=Hello, w=World, j=Java, s=JavaSE, m=Model}
集合中不存在值为a的key
集合中存在值为Java的value
集合中的key:h,w,j,s,m,
集合中的value:Hello,World,Java,JavaSE,Model,
key-value:h-Hello,w-World,j-Java,s-JavaSE,m-Model,
Hashtable 是较早推出的一个实现类,与 HashMap 的区别是:Hashtable 是线程安全的,但是性能较低;HashMap 是非线程安全的,但是性能较高。
从实际开发角度来讲,HashMap 使用的频率更高,Hashtable 的定义如下:
public class Hashtab<K, V> extends Dictionary<K, V> implements Map<K, V> Cloneable, java.io.Serializable{}下面的实例演示了 Hashtable 的用法。
public class Test { public static void main(String[] args) { Hashtable<String,String> hashtable = new Hashtable<String,String> (); hashtable.put("h", "Hello"); hashtable.put("w", "World"); hashtable.put("j", "Java"); hashtable.put("s", "JavaSE"); hashtable.put("m", "JavaME"); hashtable.put("e", "JavaEE"); System.out.println(hashtable); hashtable.remove("e"); System.out.println("删除之后:"+hashtable); hashtable.put("m", "Model"); System.out.println("添加之后:"+hashtable); if(hashtable.containsKey("a")) { System.out.println("集合中存在值为a的key"); }else { System.out.println("集合中不存在值为a的key"); } if(hashtable.containsValue("Java")) { System.out.println("集合中存在值为Java的value"); }else { System.out.println("集合中不存在值为Java的value"); } Set keys = hashtable.keySet(); Iterator keysIterator = keys.iterator(); System.out.print("集合中的key:"); while(keysIterator.hasNext()) { String key = (String) keysIterator.next(); System.out.print(key+","); } Collection values = hashtable.values(); Iterator valuesIterator = values.iterator(); System.out.print("集合中的value:"); while(valuesIterator.hasNext()) { String value = (String) valuesIterator.next(); System.out.print(value+","); } System.out.print("key-value:"); keysIterator = keys.iterator(); while(keysIterator.hasNext()) { String key = (String) keysIterator.next(); String value = hashtable.get(key); System.out.print(key+"-"+value+","); } } }运行结果为:
{h=Hello, w=World, j=Java, s=JavaSE, m=JavaME, e=JavaEE}
删除之后:{h=Hello, w=World, j=Java, s=JavaSE, m=JavaME}
添加之后:{h=Hello, w=World, j=Java, s=JavaSE, m=Model}
集合中不存在值为a的key
集合中不存在值为Java的value
集合中的key:h,w,j,s,m,
集合中的value:Hello,World,Java,JavaSE,Model,
key-value:h-Hello,w-World,j-Java,s-JavaSE,m-Model,
public class TreeMap<K, V> extends AbstractMap<K, V> implements NavigableMap<K, V> Cloneable, java.io.Serializable{}下面的实例演示了 TreeMap 的用法。
public class Test { public static void main(String[] args) { TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>(); treeMap.put(3, "Java"); treeMap.put(5, "JavaME"); treeMap.put(1, "Hello"); treeMap.put(6, "JavaEE"); treeMap.put(2, "World"); treeMap.put(4, "JavaSE"); Set keys = treeMap.keySet(); Iterator keysIterator = keys.iterator(); while(keysIterator.hasNext()) { Integer key = (Integer) keysIterator.next(); String value = treeMap.get(key); System.out.print(key+"-"+value+","); } } }运行结果为:
1-Hello,2-World,3-Java,4-JavaSE,5-JavaME,6-JavaEE,
可以看到,无论向集合中保存数据时的顺序如何,TreeMap 内部会自动按照 key 升序对数据进行排序。此时的 key 是 Integer 类型的,那如果 key 不是一个可自动排序的数据类型,如自定义的 User 类型,TreeMap 能否对其进行排序呢?观察下面的实例程序:
public class Test { public static void main(String[] args) { TreeMap<User,String> treeMap = new TreeMap<User,String>(); treeMap.put(new User(3,"Java"), "Java"); treeMap.put(new User(5,"JavaME"), "JavaME"); treeMap.put(new User(1,"Hello"), "Hello"); treeMap.put(new User(6,"JavaEE"), "JavaEE"); treeMap.put(new User(2,"World"), "World"); treeMap.put(new User(4,"JavaSE"), "JavaSE"); Set keys = treeMap.keySet(); Iterator keysIterator = keys.iterator(); while(keysIterator.hasNext()) { User key = (User) keysIterator.next(); String value = treeMap.get(key); System.out.println(key+"-"+value); } System.out.println("集合中第一个Entry:"+treeMap.firstEntry()); System.out.println("集合中第一个key:"+treeMap.firstKey()); System.out.println("集合中最后一个Entry:"+treeMap.lastEntry()); System.out.println("集合中最后一个key:"+treeMap.lastKey()); System.out.println("集合中比new User(3,Java)大的最小key值:"+treeMap.higherKey (new User(3,"Java"))); System.out.println("集合中比new User(3,Java)小的最大key值:"+treeMap.lowerKey(new User(3,"Java"))); System.out.println("集合中比new User(3,Java)大的最小的key-value对:"+treeMap. higherEntry(new User(3,"Java"))); System.out.println("集合中比new User(3,Java)小的最大的key-value对:"+treeMap. lowerEntry(new User(3,"Java"))); System.out.println("截取之后的集合:"+treeMap.subMap(new User(3,"Java") , new User(5,"JavaME"))); } } class User{ private int id; private String name; //getter、setter、有参构造函数、重写toString }运行结果如下图所示。
程序运行报错,错误原因是 User 的实例化对象无法进行排序,解决方法是让 User 类实现 Comparable 接口,并在 compareTo() 方法中实现对象的排序规则,代码如下:
class User implements Comparable{ …… @Override public int compareTo(Object o) { // TODO Auto-generated method stub /** * A.compareTo(B) * 返回值: * 1表示A大于B * 0表示A等于B * -1表示A小于B */ User user = (User) o; if(this.id > user.id) { return 1; }else if(this.id == user.id) { return 0; }else { return -1; } } }再次运行程序,结果为:
User{id=1, name='Hello'}-Hello
User{id=2, name='World'}-World
User{id=3, name='Java'}-Java
User{id=4, name='JavaSE'}-JavaSE
User{id=5, name='JavaME'}-JavaME
User{id=6, name='JavaEE'}-JavaEE
集合中第一个Entry:User{id=1, name='Hello'}-Hello
集合中第一个key:User{id=1, name='Hello'}
集合中最后一个Entry:User{id=6, name='JavaEE'}-JavaEE
集合中最后一个key:User{id=6, name='JavaEE'}
集合中比new User(3,Java)大的最小key值:User{id=4, name='JavaSE'}
集合中比new User(3,Java)小的最大key值:User{id=2, name='World'}
集合中比new User(3,Java)大的最小的key-value对:User{id=4, name='JavaSE'}-JavaSE
集合中比new User(3,Java)小的最大的key-value对:User{id=2, name='World'}-World
截取之后的集合:{User{id=3, name='Java'}=Java, User{id=4, name='JavaSE'}=JavaSE}