Skip to content

Commit dbc8b1b

Browse files
committed
Add maps concept
1 parent 3ec59e8 commit dbc8b1b

File tree

20 files changed

+1141
-6
lines changed

20 files changed

+1141
-6
lines changed

concepts/maps/.meta/config.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"blurb": "Maps are a collection of key value pairs.",
3+
"authors": [
4+
"kahgoh"
5+
],
6+
"contributors": []
7+
}

concepts/maps/about.md

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# About Maps
2+
3+
A **Map** is a data structure for storing key value pairs.
4+
It is similar to dictionaries in other programming languages.
5+
The [Map][map-javadoc] interface defines operations on a map.
6+
7+
## HashMap
8+
9+
Java has a number of Map implementations.
10+
[HashMap][hashmap-javadoc] is a commonly used one.
11+
12+
```java
13+
// Make an instance
14+
Map<String, Integer> fruitPrices = new HashMap<>();
15+
```
16+
17+
`HashMap` also has a copy constructor.
18+
19+
```java
20+
// Make a copy of a map
21+
Map<String, Integer> copy = new HashMap<>(fruitPrices);
22+
```
23+
24+
Add entries to the map using [put][map-put-javadoc].
25+
26+
```java
27+
fruitPrices.put("apple", 100);
28+
fruitPrices.put("pear", 80);
29+
// => { "apple" => 100, "pear" => 80 }
30+
```
31+
32+
Only one value can be associated with each key.
33+
Calling `put` with the same key will update the key's value.
34+
35+
```java
36+
fruitPrices.put("pear", 40);
37+
// => { "apple" => 100, "pear" => 40 }
38+
```
39+
40+
Use [get][map-get-javadoc] to get the value for a key.
41+
42+
```java
43+
fruitPrices.get("apple"); // => 100
44+
```
45+
46+
Use [containsKey][map-containskey-javadoc] to see if the map contains a particular key.
47+
48+
```java
49+
fruitPrices.containsKey("apple"); // => true
50+
fruitPrices.containsKey("orange"); // => false
51+
```
52+
53+
Remove entries with [remove][map-remove-javadoc].
54+
55+
```java
56+
fruitPrices.put("plum", 90); // Add plum to map
57+
fruitPrices.remove("plum"); // Removes plum from map
58+
```
59+
60+
The [size][map-size-javadoc] method returns the number of entries.
61+
62+
```java
63+
fruitPrices.size(); // Returns 2
64+
```
65+
66+
You can use the [keys] or [values] methods to obtain the keys or the values in a Map as a Set or collection respectively.
67+
68+
```java
69+
fruitPrices.keys(); // Returns "apple" and "pear" in a set
70+
fruitPrices.values(); // Returns 100 and 80, in a Collection
71+
```
72+
73+
## HashMap uses `hashCode` and `equals`
74+
75+
HashMaps uses the object's [hashCode][object-hashcode-javadoc] and [equals][object-equals-javadoc] method to work out where to store and how to retrieve the values for a key.
76+
For this reason, it is important that their return values do not change between storing and getting them, otherwise the HashMap may not be able to find the value.
77+
78+
For example, lets say we have the following class that will be used as the key to a map:
79+
80+
```java
81+
public class Stock {
82+
private String name;
83+
84+
public void setName(String name) {
85+
this.name = name;
86+
}
87+
88+
@Override
89+
public int hashCode() {
90+
return Objects.hash(name);
91+
}
92+
93+
@Override
94+
public boolean equals(Object obj) {
95+
if (obj == this) {
96+
return true;
97+
}
98+
if (Objects.equals(Stock.class, obj.getClass()) && obj instanceof Stock other) {
99+
return Objects.equals(name, other.name);
100+
}
101+
return false;
102+
}
103+
}
104+
```
105+
106+
The `hashCode` and `equals` depend on the `name` field, which can be changed via `setName`.
107+
Altering the `hashCode` can produce surprising results:
108+
109+
```java
110+
Stock stock = new Stock();
111+
stock.setName("Beanies");
112+
113+
Map<Stock, Integer> stockCount = new HashMap<>();
114+
stockCount.put(stock, 80);
115+
116+
stockCount.get(stock); // Returns 80
117+
118+
Stock other = new Stock();
119+
other.setName("Beanies");
120+
121+
stockCount.get(other); // Returns 80 because "other" and "stock" are equal
122+
123+
stock.setName("Choccies");
124+
stockCount.get(stock); // Returns null because hashCode value has changed
125+
126+
stockCount.get(other); // Also returns null because "other" and "stock" are not equal
127+
128+
stock.setName("Beanies");
129+
stockCount.get(stock); // HashCode restored, so returns 80 again
130+
131+
stockCount.get(other); // Also returns 80 again because "other" and "stock" are back to equal
132+
```
133+
134+
## Map.of and Map.copyOf
135+
136+
Another common way to create maps is to use [Map.of][map-of-javadoc] or [Map.ofEntries][map-ofentries-javadoc].
137+
138+
```java
139+
// Using Map.of
140+
Map<String, Integer> temperatures = Map.of("Mon", 30, "Tue", 28, "Wed", 32);
141+
142+
// or using Map.ofEntries
143+
Map<String, Integer> temperatures2 = Map.ofEntries(Map.entry("Mon", 30, "Tue", 28, "Wed", 32));
144+
```
145+
146+
Unlike `HashMap`, they populate the map upfront and become read-only once created.
147+
[Map.copyOf][map-copyof-javadoc] makes a read-only copy of a map.
148+
149+
```java
150+
Map<String, Integer> readOnlyFruitPrices = Map.copyOf(fruitPrices);
151+
```
152+
153+
Calling methods like `put`, `remove` or `clear` results in an `UnsupportedOperationException`.
154+
155+
[map-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashMap.html
156+
[hashmap-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashMap.html
157+
[map-put-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#put(K,V)
158+
[map-get-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#get(java.lang.Object)
159+
[map-containskey-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#containsKey(java.lang.Object)
160+
[map-remove-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#remove(java.lang.Object)
161+
[map-size-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#size()
162+
[map-of-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#of()
163+
[map-ofentries-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#ofEntries(java.util.Map.Entry...)
164+
[map-copyof-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#copyOf(java.util.Map)
165+
[object-hashcode-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#hashCode()
166+
[object-equals-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object)

concepts/maps/introduction.md

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Introduction
2+
3+
A **Map** is a data structure for storing key value pairs.
4+
It is similar to dictionaries in other programming languages.
5+
The [Map][map-javadoc] interface defines operations on a map.
6+
7+
Java has a number Map implementations.
8+
[HashMap][hashmap-javadoc] is a common one.
9+
10+
```java
11+
// Make an instance
12+
Map<String, Integer> fruitPrices = new HashMap<>();
13+
```
14+
15+
Add entries to the map using [put][map-put-javadoc].
16+
17+
```java
18+
fruitPrices.put("apple", 100);
19+
fruitPrices.put("pear", 80);
20+
// => { "apple" => 100, "pear" => 80 }
21+
```
22+
23+
Only one value can be associated with each key.
24+
Calling `put` with the same key will update the key's value.
25+
26+
```java
27+
fruitPrices.put("pear", 40);
28+
// => { "apple" => 100, "pear" => 40 }
29+
```
30+
31+
Use [get][map-get-javadoc] to get the value for a key.
32+
33+
```java
34+
fruitPrices.get("apple"); // => 100
35+
```
36+
37+
Use [containsKey][map-containskey-javadoc] to see if the map contains a particular key.
38+
39+
```java
40+
fruitPrices.containsKey("apple"); // => true
41+
fruitPrices.containsKey("orange"); // => false
42+
```
43+
44+
Remove entries with [remove][map-remove-javadoc].
45+
46+
```java
47+
fruitPrices.put("plum", 90); // Add plum to map
48+
fruitPrices.remove("plum"); // Removes plum from map
49+
```
50+
51+
The [size][map-size-javadoc] method returns the number of entries.
52+
53+
```java
54+
fruitPrices.size(); // Returns 2
55+
```
56+
57+
You can use the [keys] or [values] methods to obtain the keys or the values in a Map as a Set or collection respectively.studentScores
58+
59+
```java
60+
fruitPrices.keys(); // Returns "apple" and "pear" in a set
61+
fruitPrices.values(); // Returns 100 and 80, in a Collection
62+
```
63+
64+
[map-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashMap.html
65+
[hashmap-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashMap.html
66+
[map-put-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#put(K,V)
67+
[map-get-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#get(java.lang.Object)
68+
[map-containskey-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#containsKey(java.lang.Object)
69+
[map-remove-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#remove(java.lang.Object)
70+
[map-size-javadoc]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#size()

concepts/maps/links.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"url": "https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html",
4+
"description": "Interface Map documentation"
5+
},
6+
{
7+
"url": "https://dev.java/learn/api/collections-framework/maps/",
8+
"description": "Using Maps to Store Key Value Pairs"
9+
}
10+
]

config.json

+33-6
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,19 @@
308308
"generic-types"
309309
],
310310
"status": "beta"
311+
},
312+
{
313+
"slug": "international-calling-connoisseur",
314+
"name": "International Calling Connoisseur",
315+
"uuid": "03506c5a-601a-42cd-b037-c310208de84d",
316+
"concepts": [
317+
"maps"
318+
],
319+
"prerequisites": [
320+
"classes",
321+
"foreach-loops",
322+
"generic-types"
323+
]
311324
}
312325
],
313326
"practice": [
@@ -989,7 +1002,8 @@
9891002
"practices": [],
9901003
"prerequisites": [
9911004
"if-else-statements",
992-
"for-loops"
1005+
"for-loops",
1006+
"maps"
9931007
],
9941008
"difficulty": 5
9951009
},
@@ -1092,7 +1106,8 @@
10921106
"practices": [],
10931107
"prerequisites": [
10941108
"for-loops",
1095-
"arrays"
1109+
"arrays",
1110+
"maps"
10961111
],
10971112
"difficulty": 5
10981113
},
@@ -1144,7 +1159,8 @@
11441159
"practices": [],
11451160
"prerequisites": [
11461161
"chars",
1147-
"exceptions"
1162+
"exceptions",
1163+
"maps"
11481164
],
11491165
"difficulty": 6
11501166
},
@@ -1205,6 +1221,7 @@
12051221
"practices": [],
12061222
"prerequisites": [
12071223
"foreach-loops",
1224+
"maps",
12081225
"strings"
12091226
],
12101227
"difficulty": 6
@@ -1272,6 +1289,7 @@
12721289
"uuid": "38a405e8-619d-400f-b53c-2f06461fdf9d",
12731290
"practices": [],
12741291
"prerequisites": [
1292+
"maps",
12751293
"strings"
12761294
],
12771295
"difficulty": 6
@@ -1447,7 +1465,8 @@
14471465
"uuid": "2e760ae2-fadd-4d31-9639-c4554e2826e9",
14481466
"practices": [],
14491467
"prerequisites": [
1450-
"enums"
1468+
"enums",
1469+
"maps"
14511470
],
14521471
"difficulty": 7
14531472
},
@@ -1495,7 +1514,8 @@
14951514
"chars",
14961515
"if-else-statements",
14971516
"lists",
1498-
"for-loops"
1517+
"for-loops",
1518+
"maps"
14991519
],
15001520
"difficulty": 7
15011521
},
@@ -1556,7 +1576,8 @@
15561576
"prerequisites": [
15571577
"arrays",
15581578
"strings",
1559-
"if-else-statements"
1579+
"if-else-statements",
1580+
"maps"
15601581
],
15611582
"difficulty": 7
15621583
},
@@ -1703,6 +1724,7 @@
17031724
"exceptions",
17041725
"for-loops",
17051726
"if-else-statements",
1727+
"maps",
17061728
"numbers"
17071729
],
17081730
"difficulty": 8
@@ -1905,6 +1927,11 @@
19051927
"slug": "lists",
19061928
"name": "Lists"
19071929
},
1930+
{
1931+
"uuid": "2f6fdedb-a0ac-4bab-92d6-3be61520b9bc",
1932+
"slug": "maps",
1933+
"name": "Maps"
1934+
},
19081935
{
19091936
"uuid": "54118389-9c01-431b-a850-f47da498f845",
19101937
"slug": "method-overloading",

0 commit comments

Comments
 (0)