Preface

I have read several articles about Java Map Of foreign blogs , Well written , So I sorted out Java map What should be mastered 8 A question , It's a common problem in daily development , Hopefully that helped ; If there's something wrong , Welcome to , Thank you very much ~

All codes in this chapter demo Uploaded github

1、 How to put a Map Turn into List

Daily development , We often encounter this kind of scene , Put one Map Turn into List.map turn List There are three ways of transformation :

  • hold map Key key Turn into list
  • hold map Value value Turn into list
  • hold map Key value of key-value Turn into list

    The pseudocode is as follows :

// key list
List
keyList
=
new
ArrayList
(
map
.
keySet
());
// value list
List
valueList
=
new
ArrayList
(
map
.
values
());
// key-value list
List
entryList
=
new
ArrayList
(
map
.
entrySet
());

Sample code :

public
class
Test
{
public
static
void
main
(
String
[]
args
)
{
Map
<
Integer
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
2
,
"jay"
);
map
.
put
(
1
,
"whx"
);
map
.
put
(
3
,
"huaxiao"
);
// Put one map The bond of is converted to list
List
<
Integer
>
keyList
=
new
ArrayList
<>(
map
.
keySet
());
System
.
out
.
println
(
keyList
);
// hold map The value of is converted to list
List
<
String
>
valueList
=
new
ArrayList
<>(
map
.
values
());
System
.
out
.
println
(
valueList
);
hold
map
The key value of is converted to
list
List
entryList
=
new
ArrayList
(
map
.
entrySet
());
System
.
out
.
println
(
entryList
);
}
}

Running results :

[
1
,
2
,
3
]
[
whx
,
jay
,
huaxiao
]
[
1
=
whx
,
2
=
jay
,
3
=
huaxiao
]

2、 How to traverse a Map

We often need to traverse a map, There are two ways to do this :

adopt entrySet+for Implement traversal

for
(
Entry
entry
:
map
.
entrySet
())
{
// get key
K key
=
entry
.
getKey
();
// get value
V value
=
entry
.
getValue
();
}

The sample code :

public
class
EntryMapTest
{
public
static
void
main
(
String
[]
args
)
{
Map
<
Integer
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
2
,
"jay"
);
map
.
put
(
1
,
"whx"
);
map
.
put
(
3
,
"huaxiao"
);
for
(
Map
.
Entry
entry
:
map
.
entrySet
())
{
// get key
Integer
key
=
(
Integer
)
entry
.
getKey
();
// get value
String
value
=
(
String
)
entry
.
getValue
();
System
.
out
.
println
(
"key:"
+
key
+
",value:"
+
value
);
}
}
}

adopt Iterator+while Implement traversal

Iterator
itr
=
map
.
entrySet
().
iterator
();
while
(
itr
.
hasNext
())
{
Entry
entry
=
itr
.
next
();
// get key
K key
=
entry
.
getKey
();
// get value
V value
=
entry
.
getValue
();
}

The sample code :

public
class
IteratorMapTest
{
public
static
void
main
(
String
[]
args
)
{
Map
<
Integer
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
2
,
"jay"
);
map
.
put
(
1
,
"whx"
);
map
.
put
(
3
,
"huaxiao"
);
Iterator
itr
=
map
.
entrySet
().
iterator
();
while
(
itr
.
hasNext
())
{
Map
.
Entry
entry
=
(
Map
.
Entry
)
itr
.
next
();
// get key
Integer
key
=
(
Integer
)
entry
.
getKey
();
// get value
String
value
=
(
String
)
entry
.
getValue
();
System
.
out
.
println
(
"key:"
+
key
+
",value:"
+
value
);
}
}
}

Running results :

key
:
1
,
value
:
whx
key
:
2
,
value
:
jay
key
:
3
,
value
:
huaxiao

3、 How to base on Map Of keys Sort

Yes Map Of keys Sort , It's common in daily development , There are mainly two ways to achieve .

hold Map.Entry In the list, Reuse Comparator Yes list Sort

List
list
=
new
ArrayList
(
map
.
entrySet
());
Collections
.
sort
(
list
,
(
Entry
e1
,
Entry
e2
)->
{
return
e1
.
getKey
().
compareTo
(
e2
.
getKey
());
});

The sample code :

public
class
SortKeysMapTest
{
public
static
void
main
(
String
[]
args
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"2010"
,
"jay"
);
map
.
put
(
"1999"
,
"whx"
);
map
.
put
(
"3010"
,
"huaxiao"
);
List
<
Map
.
Entry
<
String
,
String
>>
list
=
new
ArrayList
<>(
map
.
entrySet
());
Collections
.
sort
(
list
,
(
Map
.
Entry
e1
,
Map
.
Entry
e2
)->
{
return
e1
.
getKey
().
toString
().
compareTo
(
e2
.
getKey
().
toString
());
});
for
(
Map
.
Entry
entry
:
list
)
{
System
.
out
.
println
(
"key:"
+
entry
.
getKey
()
+
",value:"
+
entry
.
getValue
());
}
}
}

Use SortedMap+TreeMap+Comparator Realization

SortedMap
sortedMap
=
new
TreeMap
(
new
Comparator
()
{
@Override
public
int
compare
(
K k1
,
K k2
)
{
return
k1
.
compareTo
(
k2
);
}
});
sortedMap
.
putAll
(
map
);

The sample code :

public
class
SortKeys2MapTest
{
public
static
void
main
(
String
[]
args
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"2010"
,
"jay"
);
map
.
put
(
"1999"
,
"whx"
);
map
.
put
(
"3010"
,
"huaxiao"
);
SortedMap
sortedMap
=
new
TreeMap
(
new
Comparator
<
String
>()
{
@Override
public
int
compare
(
String
k1
,
String
k2
)
{
return
k1
.
compareTo
(
k2
);
}
});
sortedMap
.
putAll
(
map
);
Iterator
itr
=
sortedMap
.
entrySet
().
iterator
();
while
(
itr
.
hasNext
())
{
Map
.
Entry
entry
=
(
Map
.
Entry
)
itr
.
next
();
// get key
String
key
=
(
String
)
entry
.
getKey
();
// get value
String
value
=
(
String
)
entry
.
getValue
();
System
.
out
.
println
(
"key:"
+
key
+
",value:"
+
value
);
}
}
}

Running results :

key
:
1999
,
value
:
whx
key
:
2010
,
value
:
jay
key
:
3010
,
value
:
huaxiao

4、 How to Map Of values Sort

List
list
=
new
ArrayList
(
map
.
entrySet
());
Collections
.
sort
(
list
,
(
Entry
e1
,
Entry
e2
)
->{
return
e1
.
getValue
().
compareTo
(
e2
.
getValue
());
});

The sample code :

public
class
SortValuesMapTest
{
public
static
void
main
(
String
[]
args
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"2010"
,
"jay"
);
map
.
put
(
"1999"
,
"whx"
);
map
.
put
(
"3010"
,
"huaxiao"
);
List
<
Map
.
Entry
<
String
,
String
>>
list
=
new
ArrayList
<>(
map
.
entrySet
());
Collections
.
sort
(
list
,
(
Map
.
Entry
e1
,
Map
.
Entry
e2
)->
{
return
e1
.
getValue
().
toString
().
compareTo
(
e2
.
getValue
().
toString
());
}
);
for
(
Map
.
Entry
entry
:
list
)
{
System
.
out
.
println
(
"key:"
+
entry
.
getKey
()
+
",value:"
+
entry
.
getValue
());
}
}
}

Running results :

key
:
3010
,
value
:
huaxiao
key
:
2010
,
value
:
jay
key
:
1999
,
value
:
whx

5、 How to initialize a static / Immutable Map

Initialize a static immutable map, only static final+static Code blocks still don't work , as follows :

public
class
Test1
{
private
static
final
Map
<
Integer
,
String
>
map
;
static
{
map
=
new
HashMap
<
Integer
,
String
>();
map
.
put
(
1
,
"one"
);
map
.
put
(
2
,
"two"
);
}
public
static
void
main
(
String
[]
args
)
{
map
.
put
(
3
,
"three"
);
Iterator
itr
=
map
.
entrySet
().
iterator
();
while
(
itr
.
hasNext
())
{
Map
.
Entry
entry
=
(
Map
.
Entry
)
itr
.
next
();
// get key
Integer
key
=
(
Integer
)
entry
.
getKey
();
// get value
String
value
=
(
String
)
entry
.
getValue
();
System
.
out
.
println
(
"key:"
+
key
+
",value:"
+
value
);
}
}
}

Inside this ,map Continue to add elements (3,"three"), Found to be OK Of , The operation results are as follows :

key
:
1
,
value
:
one
key
:
2
,
value
:
two
key
:
3
,
value
:
three

To really implement a static immutable map, need Collections.unmodifiableMap, The code is as follows :

public
class
Test2
{
private
static
final
Map
<
Integer
,
String
>
map
;
static
{
Map
<
Integer
,
String
>
aMap
=
new
HashMap
<>();
aMap
.
put
(
1
,
"one"
);
aMap
.
put
(
2
,
"two"
);
map
=
Collections
.
unmodifiableMap
(
aMap
);
}
public
static
void
main
(
String
[]
args
)
{
map
.
put
(
3
,
"3"
);
Iterator
itr
=
map
.
entrySet
().
iterator
();
while
(
itr
.
hasNext
())
{
Map
.
Entry
entry
=
(
Map
.
Entry
)
itr
.
next
();
// get key
Integer
key
=
(
Integer
)
entry
.
getKey
();
// get value
String
value
=
(
String
)
entry
.
getValue
();
System
.
out
.
println
(
"key:"
+
key
+
",value:"
+
value
);
}
}
}

The operation results are as follows :
 About Java Map, What should be mastered 8 A question

You can find , Keep going map Adding elements will report an error , To achieve what is truly immutable map.

6、HashMap, TreeMap, and Hashtable,ConcurrentHashMap The difference between

HashMap TreeMap Hashtable ConcurrentHashMap
Orderliness no yes no no
null k-v yes - yes no - yes no - no no - no
Linear safety no no yes yes
Time complexity O(1) O(log n) O(1) O(log n)
The underlying structure Array + Linked list Red and black trees Array + Linked list Red and black trees

7、 How to create an empty map

If map It's immutable , You can create :

Map
map
=
Collections
.
emptyMap
();
or
Map
<
String
,
String
>
map
=
Collections
.<
String
,
String
>
emptyMap
();
//map1.put("1", "1"); Operation error 

If you want your space map Can add elements to , You can create

Map
map
=
new
HashMap
();

8、 About map Copy

About hashmap Copy , In daily development , It's also used more . There are mainly =,clone,putAll, But they're all shallow copies , Pay attention to , Take a look at the following example :

Example a , Use = Copy a map:

public
class
CopyMapAssignTest
{
public
static
void
main
(
String
[]
args
)
{
Map
<
Integer
,
User
>
userMap
=
new
HashMap
<>();
userMap
.
put
(
1
,
new
User
(
"jay"
,
26
));
userMap
.
put
(
2
,
new
User
(
"fany"
,
25
));
//Shallow clone
Map
<
Integer
,
User
>
clonedMap
=
userMap
;
//Same as userMap
System
.
out
.
println
(
clonedMap
);
System
.
out
.
println
(
"\nChanges reflect in both maps \n"
);
//Change a value is clonedMap
clonedMap
.
get
(
1
).
setName
(
"test"
);
//Verify content of both maps
System
.
out
.
println
(
userMap
);
System
.
out
.
println
(
clonedMap
);
}
}

Running results :

{
1
=
User
{
name
=
'jay'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
Changes
reflect
in
both maps
{
1
=
User
{
name
=
'test'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
{
1
=
User
{
name
=
'test'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}

From the operation results, it can be seen that , Yes cloneMap modify , Two map It's all changed , therefore = It's light copy .

Example 2 , Use hashmap Of clone Copy :

public
class
CopyCloneMapTest
{
public
static
void
main
(
String
[]
args
)
{
HashMap
<
Integer
,
User
>
userMap
=
new
HashMap
<>();
userMap
.
put
(
1
,
new
User
(
"jay"
,
26
));
userMap
.
put
(
2
,
new
User
(
"fany"
,
25
));
//Shallow clone
HashMap
<
Integer
,
User
>
clonedMap
=
(
HashMap
<
Integer
,
User
>)
userMap
.
clone
();
//Same as userMap
System
.
out
.
println
(
clonedMap
);
System
.
out
.
println
(
"\nChanges reflect in both maps \n"
);
//Change a value is clonedMap
clonedMap
.
get
(
1
).
setName
(
"test"
);
//Verify content of both maps
System
.
out
.
println
(
userMap
);
System
.
out
.
println
(
clonedMap
);
}
}

Running results :

{
1
=
User
{
name
=
'jay'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
Changes
reflect
in
both maps
{
1
=
User
{
name
=
'test'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
{
1
=
User
{
name
=
'test'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}

From the operation results, it can be seen that , Yes cloneMap modify , Two map It's all changed , therefore hashmap Of clone It's also a shallow copy .

Example 3 , adopt putAll operation

public
class
CopyPutAllMapTest
{
public
static
void
main
(
String
[]
args
)
{
HashMap
<
Integer
,
User
>
userMap
=
new
HashMap
<>();
userMap
.
put
(
1
,
new
User
(
"jay"
,
26
));
userMap
.
put
(
2
,
new
User
(
"fany"
,
25
));
//Shallow clone
HashMap
<
Integer
,
User
>
clonedMap
=
new
HashMap
<>();
clonedMap
.
putAll
(
userMap
);
//Same as userMap
System
.
out
.
println
(
clonedMap
);
System
.
out
.
println
(
"\nChanges reflect in both maps \n"
);
//Change a value is clonedMap
clonedMap
.
get
(
1
).
setName
(
"test"
);
//Verify content of both maps
System
.
out
.
println
(
userMap
);
System
.
out
.
println
(
clonedMap
);
}
}

Running results :

{
1
=
User
{
name
=
'jay'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
Changes
reflect
in
both maps
{
1
=
User
{
name
=
'test'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
{
1
=
User
{
name
=
'test'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}

From the operation results, it can be seen that , Yes cloneMap modify , Two map It's all changed , therefore putAll Or light copy .

that , How to achieve deep replication ?

You can use serialization to achieve , Here's Google Gson serialize HashMap, Examples of implementing deep replication :

public
class
CopyDeepMapTest
{
public
static
void
main
(
String
[]
args
)
{
HashMap
<
Integer
,
User
>
userMap
=
new
HashMap
<>();
userMap
.
put
(
1
,
new
User
(
"jay"
,
26
));
userMap
.
put
(
2
,
new
User
(
"fany"
,
25
));
//Shallow clone
Gson
gson
=
new
Gson
();
String
jsonString
=
gson
.
toJson
(
userMap
);
Type
type
=
new
TypeToken
<
HashMap
<
Integer
,
User
>>(){}.
getType
();
HashMap
<
Integer
,
User
>
clonedMap
=
gson
.
fromJson
(
jsonString
,
type
);
//Same as userMap
System
.
out
.
println
(
clonedMap
);
System
.
out
.
println
(
"\nChanges reflect in only one map \n"
);
//Change a value is clonedMap
clonedMap
.
get
(
1
).
setName
(
"test"
);
//Verify content of both maps
System
.
out
.
println
(
userMap
);
System
.
out
.
println
(
clonedMap
);
}
}

Running results :


{
1
=
User
{
name
=
'jay'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
Changes
reflect
in
only one map
{
1
=
User
{
name
=
'jay'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}
{
1
=
User
{
name
=
'test'
,
age
=
26
},
2
=
User
{
name
=
'fany'
,
age
=
25
}}

From the operation results, it can be seen that , Yes cloneMap modify ,userMap Not changed , So it's deep replication .

Reference and thanks

  • Top 9 questions about Java Maps
  • Best way to create an empty map in Java
  • How to clone HashMap – Shallow and Deep Copy

Official account number

 About Java Map, What should be mastered 8 A question

  • If you are a good child who loves learning , You can pay attention to my official account. , Study and discuss together .
  • If you think there is something wrong with this article , Can comment , You can also pay attention to my official account. , Talk to me in private , Let's learn and improve together .