TreeMap或者HashMap中的entrySet()方法
查看entrySet()源码
/**
* Returns a {@link Set} view of the mappings contained in this map.
*
* <p>The set's iterator returns the entries in ascending key order. The
* sets's spliterator is
* <em><a href="Spliterator.html#binding">late-binding</a></em>,
* <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} and
* {@link Spliterator#ORDERED} with an encounter order that is ascending key
* order.
*
* <p>The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. If the map is modified
* while an iteration over the set is in progress (except through
* the iterator's own {@code remove} operation, or through the
* {@code setValue} operation on a map entry returned by the
* iterator) the results of the iteration are undefined. The set
* supports element removal, which removes the corresponding
* mapping from the map, via the {@code Iterator.remove},
* {@code Set.remove}, {@code removeAll}, {@code retainAll} and
* {@code clear} operations. It does not support the
* {@code add} or {@code addAll} operations.
*/
public Set<Map.Entry<K,V>> entrySet() {
EntrySet es = entrySet;
return (es != null) ? es : (entrySet = new EntrySet());
}
而从 EntrySet es = entrySet; 和三目运算中可以知道实际返回的是entrySet,在TreeMap类中可查看entrySet的源码
private transient EntrySet entrySet; //java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。
entrySet是一个临时变量,不参与序列化(关于序列化,我的另一篇博客会有略微提及),这里只是一个声明,没有传值
同理也可以知道返回的是一个EntrySet数组,此EntrySet中存放的是Map.Entry<K,V>接口所指向的子类对象,查找源码
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK; /**
* Make a new cell with given key, value, and parent, and with
* {@code null} child links, and BLACK color.
*/
Entry(K key, V value, Entry<K,V> parent) {
this.key = key;
this.value = value;
this.parent = parent;
} /**
* Returns the key.
*
* @return the key
*/
public K getKey() {
return key;
} /**
* Returns the value associated with the key.
*
* @return the value associated with the key
*/
public V getValue() {
return value;
} /**
* Replaces the value currently associated with the key with the given
* value.
*
* @return the value associated with the key before this method was
* called
*/
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
} public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o; return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
} public int hashCode() {
int keyHash = (key==null ? 0 : key.hashCode());
int valueHash = (value==null ? 0 : value.hashCode());
return keyHash ^ valueHash;
} public String toString() {
return key + "=" + value;
}
}
可以看见TreeMap中的内部类Entry<K,V>实现了 Map.Entry<K,V>接口,那么Entry<K,V>是 Map.Entry<K,V>的一个实现类,但是Entry<K,V>中的值是如何从外界添加进来的,继续查看源码中put方法
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
compare(key, key); // type (and possibly null) check root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
原来put方法将值存入了一个名为root的Entry<K,V>中,root是一个临时变量
private transient Entry<K,V> root;
那么到目前为止还是不知道Entry<K,V>的值如何传入entrySet中,继续查看源码,
class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator(getFirstEntry());
} public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
Object value = entry.getValue();
Entry<K,V> p = getEntry(entry.getKey());
return p != null && valEquals(p.getValue(), value);
} public boolean remove(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
Object value = entry.getValue();
Entry<K,V> p = getEntry(entry.getKey());
if (p != null && valEquals(p.getValue(), value)) {
deleteEntry(p);
return true;
}
return false;
} public int size() {
return TreeMap.this.size();
} public void clear() {
TreeMap.this.clear();
} public Spliterator<Map.Entry<K,V>> spliterator() {
return new EntrySpliterator<K,V>(TreeMap.this, null, null, 0, -1, 0);
}
}
final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
EntryIterator(Entry<K,V> first) {
super(first);
}
public Map.Entry<K,V> next() {
return nextEntry();
}
}
final Entry<K,V> nextEntry() {
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
next = successor(e);
lastReturned = e;
return e;
}
TreeMap或者HashMap中的entrySet()方法的更多相关文章
- HashMap 中的 entrySet()使用方法 2016.12.28
package map; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import ...
- K:HashMap中hash函数的作用
在分析了hashCode方法和equals方法之后,我们对hashCode方法和equals方法的相关作用有了大致的了解.在通过查看HashMap类的相关源码的时候,发现其中存在一个int has ...
- 【转】浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...
- HashMap 中的 hash 函数
1. 什么是 hash 函数 hash 函数,即散列函数,或叫哈希函数.它可以将不定长的输入,通过散列算法转换成一个定长的输出,这个输出就是散列值.需要注意的是,不同的输入通过散列函数,也可能会得到同 ...
- Java基础:HashMap中putAll方法的疑惑
最近回顾了下HashMap的源码(JDK1.7),当读到putAll方法时,发现了之前写的TODO标记,当时由于时间匆忙没来得及深究,现在回顾到了就再仔细思考了下 @Override public v ...
- Java分享笔记:使用entrySet方法获取Map集合中的元素
/*--------------------------------- 使用entrySet方法取出Map集合中的元素: ....该方法是将Map集合中key与value的关系存入到了Set集合中,这 ...
- 统计字符串中每种字符出现的评率(HashMap中getOrDefault(K, V)方法的使用)
为了统计字符串中每种字符出现的频率,使用HashMap这种数据结构.其中,字符作为Key,出现的频率作为Value. 基本算法为: 1. 将字符串分成字符数组 2. (1)如果HashMap中的Key ...
- Java中hashCode()方法以及HashMap()中hash()方法
Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...
- HashMap中使用自定义类作为Key时,为何要重写HashCode和Equals方法
之前一直不是很理解为什么要重写HashCode和Equals方法,才只能作为键值存储在HashMap中.通过下文,可以一探究竟. 首先,如果我们直接用以下的Person类作为键,存入HashMap中, ...
随机推荐
- Android开发案例 设置背景图片轮播
点击按钮实现图片轮播效果 实践案例: xml <?xml version="1.0" encoding="utf-8"?> <LinearLa ...
- 三角网格上的寻路算法Part.2—A*算法
背景 继上一篇三角网格Dijkstra寻路算法之后,本篇将继续介绍一种更加智能,更具效率的寻路算法-A*算法,本文将首先介绍该算法的思想原理,再通过对比来说明二者之间的相同与不同之处,然后采用类似Di ...
- pytest动态添加命令行参数并获取(钩子函数:pytest_addoption)
考虑场景: 我们的自动化用例需要支持在不同测试环境运行,有时候在dev环境运行,有时候在test环境运行: 有时候需要根据某个参数不同的参数值,执行不同的业务逻辑: 上面的场景我们都可以通过" ...
- ubuntu的一些常用操作
查看当前正在运行的操作系统版本 $ cat /etc/issue 查看操作系统详细信息 $ sudo lsb_release -a 查看内核版本号 $ uname -r 卸载软件(不保留配置文件) $ ...
- SYCOJ570传纸条
题目-传纸条 (shiyancang.cn) 算法(线性DP) O(n3)O(n3)首先考虑路径有交集该如何处理.可以发现交集中的格子一定在每条路径的相同步数处.因此可以让两个人同时从起点出发,每次同 ...
- Redis可视化内存分析工具--RDR:查看Redis中key的占用情况
RDR(redis datareveal)是一个解析redis rdbfile的工具.与redis-rdb-tools 相比,RDR 是由 golang 实现的,速度要快得多(5GB rdbfile ...
- 【C】C语言大作业——学生学籍管理系统
文章目录 学生管理系统 界面 主界面 登陆界面 注册界面 管理界面 学生界面 退出界面 链接 注意 学生管理系统 学C语言时写的一个大作业,弄了一个带图形界面的,使用的是VS配合EasyX图形库进行实 ...
- python中的sort方法和sorted方法
一.sort()函数 描述 sort() 函数用于对原列表进行排序,如果指定参数,则使用比较函数指定的比较函数. 语法 sort()方法语法: 1 list.sort(cmp=None, key=No ...
- rocketmq实现延迟队列(精确到秒级)
最近项目里需要在延时队列,但是开源版本rocketmq不支持任意时间延时,造成有些任务无法执行 参考了网上的不少文章,但是都么有实现,所以再开源的基础上改造了个支持任意时间延时的队列. 源码地址: h ...
- 如何管理leader对你的能力预期?
在内网看到一个讨论帖,原文如下: 如何管理leader对你的能力预期? 你一个项目做得好,之后类似项目,leader认为你也就是合格水平,而且认为你只会做这种项目. SAD.. 思考 在开始之前先想下 ...