目录
我们知道, map 接口是双列 , 底下三个实现类 hashMap, TreeMap , HashTable
hashMap 可参考:hashMap底层实现解析(负载因子0.75,初始容量16,键不重复)_xx12321q的博客-CSDN博客
hashTable 底层同 hashMap相同, 但是它在大部分方法上加了synchronized锁,是线程安全的(但是键不能存放null值)
最后就是TreeMap(键采用红黑树存储)
TreeMap
TreeMap<String,String> treeMap = new TreeMap<>();
treeMap.put("b","2");
treeMap.put("c","3");
treeMap.put("d","4");
treeMap.put("a","10");
System.out.println(treeMap);
结果 :
我们可以看到, TreeMap根据键的顺序来为我们已经排好了序 , 我们这里的键是String, 而String已经实现了Comparable接口, 并重写了compareTo()方法,所以这里按照字母顺序排列
但是如果我们使用了自己定义的类, 并没有实现Comparable接口 ,这样是不能put的
public class User { //自定义一个User类
private Integer id;
private String account;
private String sex;
public User(){}
public User(Integer id, String account, String sex) {
this.id = id;
this.account = account;
this.sex = sex;
}
}
TreeMap<User,String> treeMap = new TreeMap<>();
User user = new User();
treeMap.put(user,"abc");
结果
可以看到,直接会报出 ClassCastException(类加载异常)
所以我们使用TreeMap的时候,键必须要实现Comparable接口重写compareTo()方法来传入我们自己定义的排序规则, 例 :
// 实现Comparable接口,传入类型
public class User implements Comparable<User>{
private Integer id;
private String account;
private String sex;
public User() {
}
public User(Integer id, String account, String sex) {
this.id = id;
this.account = account;
this.sex = sex;
}
@Override
public int compareTo(User user) { //可以自定义排序规则
return 0;
}
}
介绍完特征,我们来看 put() 方法的部分源码,这里就不完全展示了
可以看到 , 这就是TreeMap的有序性
需要注意的是, TreeMap并不能存储 null 的键,而hashMap可以
Map接口的遍历方式
先建立一个Map , 以hashMap为例
Map<String,String> map = new HashMap<>();
map.put("a","1");
map.put("f","12");
map.put("q","123");
map.put("w","1234");
map.put("b","12345");
方式一 : 先将所有key(键) 存到一个set 集合中(使用keySet()方法),然后遍历set集合 ,通过key拿到value ,例 :
Set<String> set = map.keySet(); //拿到所有的键
Iterator<String> iterator = set.iterator(); //拿到set的迭代器
while (iterator.hasNext()){ //循环遍历
System.out.println(map.get(iterator.next())); //通过get()拿值
}
结果 :
方式二 : 通过entrySet() 方法,直接拿到底层存储键值对的对象, 返回到set 集合中,然后遍历set集合
通过Entry类里的方法遍历,例:
Set<Map.Entry<String, String>> entrySet = map.entrySet(); //拿到底层entry
for (Map.Entry<String, String> entry : entrySet) {
System.out.println("key:"+entry.getKey()+":: value:"+entry.getValue());
}
结果 :
方式三 : 流遍历
map.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String s, String s2) {
System.out.println(s+"::"+s2);
}
});
结果:
以上就是map 遍历的三种方式