集合 Map

和 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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值