查看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()方法的更多相关文章

  1. HashMap 中的 entrySet()使用方法 2016.12.28

    package map; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import ...

  2. K:HashMap中hash函数的作用

      在分析了hashCode方法和equals方法之后,我们对hashCode方法和equals方法的相关作用有了大致的了解.在通过查看HashMap类的相关源码的时候,发现其中存在一个int has ...

  3. 【转】浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...

  4. HashMap 中的 hash 函数

    1. 什么是 hash 函数 hash 函数,即散列函数,或叫哈希函数.它可以将不定长的输入,通过散列算法转换成一个定长的输出,这个输出就是散列值.需要注意的是,不同的输入通过散列函数,也可能会得到同 ...

  5. Java基础:HashMap中putAll方法的疑惑

    最近回顾了下HashMap的源码(JDK1.7),当读到putAll方法时,发现了之前写的TODO标记,当时由于时间匆忙没来得及深究,现在回顾到了就再仔细思考了下 @Override public v ...

  6. Java分享笔记:使用entrySet方法获取Map集合中的元素

    /*--------------------------------- 使用entrySet方法取出Map集合中的元素: ....该方法是将Map集合中key与value的关系存入到了Set集合中,这 ...

  7. 统计字符串中每种字符出现的评率(HashMap中getOrDefault(K, V)方法的使用)

    为了统计字符串中每种字符出现的频率,使用HashMap这种数据结构.其中,字符作为Key,出现的频率作为Value. 基本算法为: 1. 将字符串分成字符数组 2. (1)如果HashMap中的Key ...

  8. Java中hashCode()方法以及HashMap()中hash()方法

    Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...

  9. HashMap中使用自定义类作为Key时,为何要重写HashCode和Equals方法

    之前一直不是很理解为什么要重写HashCode和Equals方法,才只能作为键值存储在HashMap中.通过下文,可以一探究竟. 首先,如果我们直接用以下的Person类作为键,存入HashMap中, ...

随机推荐

  1. CSS基础 元素整体透明效果(包含内容+背景及子元素)

    属性名:opacity:数字+px; 数字值取值0-1之间数字 数字值:1表示完全不透明 0表示完全透明使用后效果 html结构代码 <div class="box"> ...

  2. IdentityServer4 综合应用实战系列 (一)登录

    这篇文章主要说登录,这里抛开IdentityServer4的各种模式,这里只说登录 我们要分别实现 4中登录方式来说明,  IdentityServer4本地登陆 . Windows账户登录(本地的电 ...

  3. vue-router 两个子路由之间相互跳转时出错

    patient页面跳转到apply页面后,再点击patient页面后无法跳回 解决方法:使用`${path + path1}` 来自为知笔记(Wiz)

  4. [Docker] 制作并运行 Nginx 镜像

    环境 操作系统(cat /etc/redhat-release):CentOS Linux release 7.6.1810 (Core) Docker:18.09.6 文件 Dockerfile F ...

  5. nuxt中iview按需加载配置

    在plugins/iview.js中修改 初始代码如下 import Vue from 'vue' import iView from 'iview' import locale from 'ivie ...

  6. openlayers素材网站

    1.教程网站 http://weilin.me/ol3-primer/ch05/05-03.html 2.特效气象图 https://earth.nullschool.net/zh-cn/#curre ...

  7. HDOJ1573X问题

    https://acm.hdu.edu.cn/showproblem.php?pid=1573 n组线性同余方程求解,最后求出多少解.而最终的解的周期为最小公倍数,范围内的,需要这样算.如果最小超过, ...

  8. SpringBoot整合Elasticsearch+ik分词器+kibana

    话不多说直接开整 首先是版本对应,SpringBoot和ES之间的版本必须要按照官方给的对照表进行安装,最新版本对照表如下: (官网链接:https://docs.spring.io/spring-d ...

  9. PIKACHU之文件包含漏洞

    PIKUCHU靶场之文件包含 一.file inclusion(local) 实验源码: <?php /** * Created by runner.han * There is nothing ...

  10. AGC041F Histogram Rooks

    有生之年自己做出了一个 AGC F 还踩了标算,但是好像在我之前已经有人踩过标算了,再鞭尸一波也无可厚非 hhh 看到"全部被覆盖" 条件不好做,考虑容斥,即选择若干个位置强制它们 ...