- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java Map.entry案例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>,Map.Entry 是Map中的一个接口,他的用途是表示一个映射项(里面有Key和Value),而Set<Map.Entry<K,V>>表示一个映射项的Set。Map.Entry里有相应的getKey和getValue方法,即JavaBean,让我们能够从一个项中取出Key和Value.
下面是遍历Map的四种方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
public
static
void
main(String[] args) {
Map<String, String> map =
new
HashMap<String, String>();
map.put(
"1"
,
"value1"
);
map.put(
"2"
,
"value2"
);
map.put(
"3"
,
"value3"
);
//第一种:普遍使用,二次取值
System.out.println(
"通过Map.keySet遍历key和value:"
);
for
(String key : map.keySet()) {
System.out.println(
"key= "
+ key +
" and value= "
+ map.get(key));
}
//第二种
System.out.println(
"通过Map.entrySet使用iterator遍历key和value:"
);
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while
(it.hasNext()) {
Map.Entry<String, String> entry = it.next();
System.out.println(
"key= "
+ entry.getKey() +
" and value= "
+ entry.getValue());
}
//第三种:推荐,尤其是容量大时
System.out.println(
"通过Map.entrySet遍历key和value"
);
for
(Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(
"key= "
+ entry.getKey() +
" and value= "
+ entry.getValue());
}
//第四种
System.out.println(
"通过Map.values()遍历所有的value,但不能遍历key"
);
for
(String v : map.values()) {
System.out.println(
"value= "
+ v);
}
}
|
下面是HashMap的源代码:
首先HashMap的底层实现用的时候一个Entry数组 。
1
2
3
4
5
6
7
8
9
10
11
|
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry[] table; //声明了一个数组
........
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
table = new Entry[DEFAULT_INITIAL_CAPACITY];//初始化数组的大小为DEFAULT_INITIAL_CAPACITY(这里是16)
init();
}
|
再来看一下Entry是在什么地方定义的,继续上源码,我们在HashMap的源码的674行发现了它的定义,原来他是HashMap的一个内部类,并且实现了Map.Entry接口,以下有些地方是转载 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
static
class
Entry<K,V>
implements
Map.Entry<K,V> {
final
K key;
V value;
Entry<K,V> next;
final
int
hash;
/**
* Creates new entry.
*/
Entry(
int
h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
public
final
K getKey() {
return
key;
}
public
final
V getValue() {
return
value;
}
public
final
V setValue(V newValue) {
V oldValue = value;
value = newValue;
return
oldValue;
}
public
final
boolean
equals(Object o) {
if
(!(o
instanceof
Map.Entry))
return
false
;
Map.Entry e = (Map.Entry)o;
Object k1 = getKey();
Object k2 = e.getKey();
if
(k1 == k2 || (k1 !=
null
&& k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if
(v1 == v2 || (v1 !=
null
&& v1.equals(v2)))
return
true
;
}
return
false
;
}
public
final
int
hashCode() {
return
(key==
null
?
0
: key.hashCode()) ^
(value==
null
?
0
: value.hashCode());
}
public
final
String toString() {
return
getKey() +
"="
+ getValue();
}
/**
* This method is invoked whenever the value in an entry is
* overwritten by an invocation of put(k,v) for a key k that's already
* in the HashMap.
*/
void
recordAccess(HashMap<K,V> m) {
}
/**
* This method is invoked whenever the entry is
* removed from the table.
*/
void
recordRemoval(HashMap<K,V> m) {
}
}
|
既然这样那我们再看一下Map.Entry这个接口是怎么定义的,原来他是Map的一个内部接口并且定义了一些方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
interface
Entry<K,V> {
/**
* Returns the key corresponding to this entry.
*
* @return the key corresponding to this entry
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
K getKey();
/**
* Returns the value corresponding to this entry. If the mapping
* has been removed from the backing map (by the iterator's
* <tt>remove</tt> operation), the results of this call are undefined.
*
* @return the value corresponding to this entry
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V getValue();
/**
* Replaces the value corresponding to this entry with the specified
* value (optional operation). (Writes through to the map.) The
* behavior of this call is undefined if the mapping has already been
* removed from the map (by the iterator's <tt>remove</tt> operation).
*
* @param value new value to be stored in this entry
* @return old value corresponding to the entry
* @throws UnsupportedOperationException if the <tt>put</tt> operation
* is not supported by the backing map
* @throws ClassCastException if the class of the specified value
* prevents it from being stored in the backing map
* @throws NullPointerException if the backing map does not permit
* null values, and the specified value is null
* @throws IllegalArgumentException if some property of this value
* prevents it from being stored in the backing map
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V setValue(V value);
/**
* Compares the specified object with this entry for equality.
* Returns <tt>true</tt> if the given object is also a map entry and
* the two entries represent the same mapping. More formally, two
* entries <tt>e1</tt> and <tt>e2</tt> represent the same mapping
* if<pre>
* (e1.getKey()==null ?
* e2.getKey()==null : e1.getKey().equals(e2.getKey())) &&
* (e1.getValue()==null ?
* e2.getValue()==null : e1.getValue().equals(e2.getValue()))
* </pre>
* This ensures that the <tt>equals</tt> method works properly across
* different implementations of the <tt>Map.Entry</tt> interface.
*
* @param o object to be compared for equality with this map entry
* @return <tt>true</tt> if the specified object is equal to this map
* entry
*/
boolean
equals(Object o);
/**
* Returns the hash code value for this map entry. The hash code
* of a map entry <tt>e</tt> is defined to be: <pre>
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
* (e.getValue()==null ? 0 : e.getValue().hashCode())
* </pre>
* This ensures that <tt>e1.equals(e2)</tt> implies that
* <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
* <tt>e1</tt> and <tt>e2</tt>, as required by the general
* contract of <tt>Object.hashCode</tt>.
*
* @return the hash code value for this map entry
* @see Object#hashCode()
* @see Object#equals(Object)
* @see #equals(Object)
*/
int
hashCode();
}
|
看到这里的时候大伙儿估计都明白得差不多了为什么HashMap为什么要选择Entry数组来存放key-value对了吧,因为Entry实现的Map.Entry接口里面定义了getKey(),getValue(),setKey(),setValue()等方法相当于一个javaBean,对键值对进行了一个封装便于后面的操作,从这里我们其实也可以联想到不光是HashMap,譬如LinkedHashMap,TreeMap 等继承自map的容器存储key-value对都应该使用的是Entry只不过组织Entry的形式不一样,HashMap用的是数组加链表的形式,LinkedHashMap用的是链表的形式,TreeMap应该使用的二叉树的形式,不信的话上源码 。
LinkedHashMap
1
2
3
4
5
|
/**
* The head of the doubly linked list.
*/
/定义了链头
private
transient
Entry<K,V> header;
|
初始化链表的方法:
1
2
3
4
|
void
init() {
header =
new
Entry<K,V>(-
1
,
null
,
null
,
null
);
header.before = header.after = header;
}
|
TreeMap
1
2
|
//定义根节点
private
transient
Entry<K,V> root =
null
;
|
再看他的put方法,是不是很面熟(二叉排序树的插入操作) 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
public
V put(K key, V value) {
Entry<K,V> t = root;
if
(t ==
null
) {
// TBD:
// 5045147: (coll) Adding null to an empty TreeSet should
// throw NullPointerException
//
// compare(key, key); // type check
root =
new
Entry<K,V>(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();
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<K,V>(key, value, parent);
if
(cmp <
0
)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return
null
;
}
|
ok,明白了各种Map的底层存储key-value对的方式后,再来看看如何遍历map吧,这里用HashMap来演示吧 。
Map提供了一些常用方法,如keySet()、entrySet()等方法,keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry.
so,很容易写出如下的遍历代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
1
. Map map =
new
HashMap();
Irerator iterator = map.entrySet().iterator();
while
(iterator.hasNext()) {
Map.Entry entry = iterator.next();
Object key = entry.getKey();
//
}
2
.Map map =
new
HashMap();
Set keySet= map.keySet();
Irerator iterator = keySet.iterator;
while
(iterator.hasNext()) {
Object key = iterator.next();
Object value = map.get(key);
//
}
另外,还有一种遍历方法是,单纯的遍历value值,Map有一个values方法,返回的是value的Collection集合。通过遍历collection也可以遍历value,如
[java] view plain copy
Map map =
new
HashMap();
Collection c = map.values();
Iterator iterator = c.iterator();
while
(iterator.hasNext()) {
Object value = iterator.next();
|
到此这篇关于Java Map.entry案例详解的文章就介绍到这了,更多相关Java Map.entry内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/kyi_zhu123/article/details/52769469 。
最后此篇关于Java Map.entry案例详解的文章就讲到这里了,如果你想了解更多关于Java Map.entry案例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这个问题在这里已经有了答案: Oracle: merging two different queries into one, LIKE & IN (1 个回答) 8年前关闭。 我有以下代码: case
我查阅过此页面:http://dev.mysql.com/doc/refman/5.1/en/case.html以及这个,但无法获得一个简单的程序来工作...... 更新:为了明确我想要做什么:我想从
有什么办法可以优化下面的查询吗? SELECT DATE_FORMAT(a.duedate,'%d-%b-%y') AS dte, duedate, SUM(CASE WHEN (typeofnoti
我进退两难,以下 SQL 查询的结果是什么以及它是如何工作的: SELECT ... CASE WHEN (a.FIELD=1 AND b.FIELD=2) THEN 1 WHEN
问题:输入年,月,打印对应年月的日历。 示例: 问题分析: 1,首先1970年是Unix系统诞生的时间,1970年成为Unix的元年,1970年1月1号是星期四,现在大多的手机的日历功能只能显
**摘要:**介绍了Angular中依赖注入是如何查找依赖,如何配置提供商,如何用限定和过滤作用的装饰器拿到想要的实例,进一步通过N个案例分析如何结合依赖注入的知识点来解决开发编程中会遇到的问题。 本
我想拥有自动伴侣类apply case 类的构造函数来为我执行隐式转换,但无法弄清楚如何这样做。我到处搜索,我能找到的最接近的答案是 this问题(我将解释为什么它不是我在下面寻找的)。 我有一个看起
您好,我已经浏览了“多列案例”问题,但没有看到与此相同的内容,所以我想我应该问一下。 基本上我有两个我想要连接的表(都是子查询的结果)。它们具有相同的列名称。如果我加入他们的 ID 和 SELECT
我发现了一些类型推断的非直觉行为。因此,语义等效代码的工作方式不同,具体取决于编译器推断出的有关函数返回类型的信息。当您在最小单元测试中重现此案例时,或多或少会清楚发生了什么。但我担心在编写框架代码时
CREATE TABLE test ( sts_id int , [status1] int , [status2] int , [status3] int , [status4] int ) INS
我有以下声明: SELECT Dag AS Dag, CASE Jaar WHEN 2013 THEN Levering END AS '2013', CASE
我想做的是为所有高于平均时间、平均时间和低于平均时间的游乐设施获取平均tip_portion。所以返回3行。当我运行它时,它显示: ERROR: missing FROM-clause entry
我正在尝试设置一个包含以下字段的报告: 非常需要报告来显示日期、该日期内的总记录(因此我按日期分组),然后按小时计算 12 小时工作日(从上午 8 点到晚上 8 点)我需要计算记录在这些时间内出现的时
我有这个查询 SELECT users.name FROM users LEFT JOIN weapon_stats ON users.id = weapon_stats.zp_id WHERE we
我正在尝试按收视率等级获取不同视频的计数。我有下表: vid_id views 1 6 1 10 1 900 2 850 2 125000
假设我有一个如下所示的 SQL 语句: select supplier, case when platform in (5,6) then 'mobile' when p
我有一个表测试 TestNumber (int primary key) InactiveBitwise (int) 我执行以下命令: UPDATE tests SET CASE WH
我有一个像这样的表(name=expense): id amount date 1 -1687 2014-01-02 00:00:00.0 2 11000 2014-01-02 0
我有一个 multimap 定义 typedef std::pair au_pair; //vertices typedef std::pair acq_pair; //ch qlty specifi
我有一个有点像枚举的类,它的每个实例都有一个唯一的 int 值,该值从 0 开始并在每个新实例时递增。 class MyEnumLikeClass { static int NextId =
我是一名优秀的程序员,十分优秀!