和 C++ STL 中的map很像,就是换了代码
键-值对应
下面直接给出操作
操作
Map中不存在重复的key,因为放入相同的key,只会把原有的key-value对应的value给替换掉
代码 | 作用 |
---|---|
Object put(Object k, Object v) | 将指定的值与此映射中的指定键关联 |
void putAll(Map m) | 从指定映射中将所有映射关系复制到此映射中 |
Object get(Object k) | 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null |
Object remove(Object k) | 如果存在一个键的映射关系,则将其从此映射中移除 |
int size( ) | 返回此映射中的键-值映射关系数 |
boolean isEmpty( ) | 如果此映射未包含键-值映射关系,则返回 true |
void clear( ) | 从此映射中移除所有映射关系 |
boolean containsKey(Object k) | 如果此映射包含指定键的映射关系,则返回 true |
boolean containsValue(Object v) | 如果此映射将一个或多个键映射到指定值,则返回 true |
boolean equals(Object obj) | 比较指定的对象与此映射是否相等 |
int hashCode( ) | 返回此映射的哈希码值 |
Set entrySet( ) | 返回此映射中包含的映射关系的 Set 视图 |
Set keySet( ) | 返回此映射中包含的键的 Set 视图 |
Collection values( ) | 返回此映射中包含的值的 Collection 视图 |
创建
最常用的实现类是HashMap
Map<String, Integer> map = new HashMap<>();
遍历
遍历Map时,不可假设输出的key是有序的
即:hashmap内部无序
1、要遍历key或value可以使用for each循环遍历Map实例的keySet()方法返回的Set集合,它包含不重复的key的集合:
(比下一种快)
//遍历keys
for (String key : map.keySet())
Integer value = map.get(key);
//遍历values
for (Integer value : map.values())
System.out.println("Value = " + value);
2、同时遍历key和value可以使用for each循环遍历Map对象的entrySet()集合,它包含每一个key-value映射:
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
}
3、迭代器遍历:
可以在过程中,调用iterator.remove()来删除entries,效率同第一种
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Integer key = (Integer)entry.getKey();
Integer value = (Integer)entry.getValue();
System.out.println("Key = " + key + ", Value = " + value);
}
TreeMap
如果想让map有序,需要使用 TreeMap
String、Integer这些类已经实现了Comparable,所以不需要再写,可以直接使用。
如果是自定义类,需要在创建时写Comparable方法
class Person {
public String name;
public int score;
/...
}
Map<Person, Integer> map = new TreeMap<>(new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Map<Student, Integer> map = new TreeMap<>(new Comparator<Person>() {
if (p1.score == p2.score) {
return 0;
}
return p1.score > p2.score ? -1 : 1;
});
覆写hashCode
-
要正确使用HashMap,作为key的类必须正确覆写equals()和hashCode()方法;
-
一个类如果覆写了equals(),就必须覆写hashCode(),并且覆写规则是:
-
如果equals()返回true,则hashCode()返回值必须相等;
-
如果equals()返回false,则hashCode()返回值尽量不要相等。
-
实现hashCode()方法可以通过Objects.hashCode()辅助方法实现。
对应两个实例a和b:
- 如果a和b相等,那么a.equals(b)一定为true,则a.hashCode()必须等于b.hashCode();
- 如果a和b不相等,那么a.equals(b)一定为false,则a.hashCode()和b.hashCode()尽量不要相等。
上述第一条规范是正确性,必须保证实现,否则HashMap不能正常工作。
而第二条如果尽量满足,则可以保证查询效率,因为不同的对象,如果返回相同的hashCode(),会造成Map内部存储冲突,使存取的效率下降。
如果两个对象不相等,则两个对象的hashCode()尽量不要相等。
public class Person {
String firstName;
String lastName;
int age;
int hashCode() {
return Objects.hash(firstName, lastName, age);
}
}