Skip to content

Commit 6f4835a

Browse files
committed
Simple BiMap implementation
DEVSIX-2121
1 parent b08a237 commit 6f4835a

File tree

2 files changed

+277
-0
lines changed
  • commons/src

2 files changed

+277
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.itextpdf.commons.datastructures;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* A simple bi-directional map.
8+
*
9+
* @param <K> the type of the first key
10+
* @param <V> the type of the second key
11+
*/
12+
public final class BiMap<K, V> {
13+
14+
private final Map<K, V> map = new HashMap<K, V>();
15+
private final Map<V, K> inverseMap = new HashMap<V, K>();
16+
17+
/**
18+
* Creates a new {@link BiMap} instance.
19+
*/
20+
public BiMap() {
21+
// empty constructor
22+
}
23+
24+
/**
25+
* Puts the entry into the map.
26+
* If the key already exists, the value will be overwritten.
27+
* If the value already exists, the key will be overwritten.
28+
* If both key and value already exist, the entry will be overwritten.
29+
* If neither key nor value already exist, the entry will be added.
30+
*
31+
* @param k the key
32+
* @param v the value
33+
*/
34+
public void put(K k, V v) {
35+
map.put(k, v);
36+
inverseMap.put(v, k);
37+
}
38+
39+
/**
40+
* Gets the value by key.
41+
*
42+
* @param value the key
43+
*
44+
* @return the value
45+
*/
46+
public V getByKey(K value) {
47+
return map.get(value);
48+
}
49+
50+
/**
51+
* Gets the key by value.
52+
*
53+
* @param key the value
54+
*
55+
* @return the key
56+
*/
57+
public K getByValue(V key) {
58+
return inverseMap.get(key);
59+
}
60+
61+
/**
62+
* Removes the entry by key.
63+
*
64+
* @param k the key
65+
*/
66+
public void removeByKey(K k) {
67+
V v = map.remove(k);
68+
if (v != null) {
69+
inverseMap.remove(v);
70+
}
71+
}
72+
73+
/**
74+
* Removes the entry by value.
75+
*
76+
* @param v the value
77+
*/
78+
public void removeByValue(V v) {
79+
K k = inverseMap.remove(v);
80+
if (k != null) {
81+
map.remove(k);
82+
}
83+
}
84+
85+
/**
86+
* Gets the size of the map.
87+
*
88+
* @return the size of the map
89+
*/
90+
public int size() {
91+
return map.size();
92+
}
93+
94+
/**
95+
* removes all entries from the map.
96+
*/
97+
public void clear() {
98+
map.clear();
99+
inverseMap.clear();
100+
}
101+
102+
/**
103+
* Checks if the map is empty.
104+
*
105+
* @return true, if the map is empty
106+
*/
107+
public boolean isEmpty() {
108+
return map.isEmpty();
109+
}
110+
111+
112+
/**
113+
* Checks if the map contains the key.
114+
*
115+
* @param k the key
116+
*
117+
* @return true, if the map contains the key
118+
*/
119+
public boolean containsKey(K k) {
120+
return map.containsKey(k);
121+
}
122+
123+
/**
124+
* Checks if the map contains the value.
125+
*
126+
* @param v the value
127+
*
128+
* @return true, if the map contains the value
129+
*/
130+
public boolean containsValue(V v) {
131+
return inverseMap.containsKey(v);
132+
}
133+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package com.itextpdf.commons.datastructures;
2+
3+
import com.itextpdf.test.annotations.type.UnitTest;
4+
5+
import org.junit.Assert;
6+
import org.junit.Test;
7+
import org.junit.experimental.categories.Category;
8+
9+
@Category(UnitTest.class)
10+
public class BiMapTest {
11+
12+
@Test
13+
public void sizeTest01() {
14+
BiMap<String, Integer> map = new BiMap<String, Integer>();
15+
Assert.assertEquals(0, map.size());
16+
}
17+
18+
@Test
19+
public void sizeTest02() {
20+
BiMap<String, Integer> map = new BiMap<String, Integer>();
21+
map.put("a", 1);
22+
Assert.assertEquals(1, map.size());
23+
}
24+
25+
@Test
26+
public void isEmptyTest01() {
27+
BiMap<String, Integer> map = new BiMap<String, Integer>();
28+
map.put("a", 1);
29+
Assert.assertFalse(map.isEmpty());
30+
}
31+
32+
33+
@Test
34+
public void putTest() {
35+
BiMap<String, Integer> map = new BiMap<String, Integer>();
36+
map.put("a", 1);
37+
Assert.assertEquals(1, (int) map.getByKey("a"));
38+
Assert.assertEquals("a", map.getByValue(1));
39+
}
40+
41+
@Test
42+
public void putOnExistingKey() {
43+
BiMap<String, Integer> map = new BiMap<String, Integer>();
44+
map.put("a", 1);
45+
map.put("a", 2);
46+
Assert.assertEquals(2, (int) map.getByKey("a"));
47+
Assert.assertEquals("a", map.getByValue(2));
48+
}
49+
50+
@Test
51+
public void putOnExistingValue() {
52+
BiMap<String, Integer> map = new BiMap<String, Integer>();
53+
map.put("a", 1);
54+
map.put("b", 1);
55+
Assert.assertEquals(1, (int) map.getByKey("b"));
56+
Assert.assertEquals("b", map.getByValue(1));
57+
}
58+
59+
@Test
60+
public void putOnExistingKeyAndValue() {
61+
BiMap<String, Integer> map = new BiMap<String, Integer>();
62+
map.put("a", 1);
63+
map.put("a", 1);
64+
Assert.assertEquals(1, (int) map.getByKey("a"));
65+
Assert.assertEquals("a", map.getByValue(1));
66+
}
67+
68+
@Test
69+
public void putMultipleValues() {
70+
BiMap<String, Integer> map = new BiMap<String, Integer>();
71+
map.put("a", 1);
72+
map.put("b", 2);
73+
map.put("c", 3);
74+
Assert.assertEquals(1, (int) map.getByKey("a"));
75+
Assert.assertEquals("a", map.getByValue(1));
76+
Assert.assertEquals(2, (int) map.getByKey("b"));
77+
Assert.assertEquals("b", map.getByValue(2));
78+
Assert.assertEquals(3, (int) map.getByKey("c"));
79+
Assert.assertEquals("c", map.getByValue(3));
80+
Assert.assertEquals(3, map.size());
81+
}
82+
83+
84+
@Test
85+
public void clearTest() {
86+
BiMap<String, Integer> map = new BiMap<String, Integer>();
87+
map.put("a", 1);
88+
map.clear();
89+
Assert.assertEquals(0, map.size());
90+
}
91+
92+
@Test
93+
public void containsKeyTest() {
94+
BiMap<String, Integer> map = new BiMap<String, Integer>();
95+
map.put("a", 1);
96+
Assert.assertTrue(map.containsKey("a"));
97+
}
98+
99+
@Test
100+
public void containsValueTest() {
101+
BiMap<String, Integer> map = new BiMap<String, Integer>();
102+
map.put("a", 1);
103+
Assert.assertTrue(map.containsValue(1));
104+
}
105+
106+
@Test
107+
public void getByValue() {
108+
BiMap<String, Integer> map = new BiMap<String, Integer>();
109+
map.put("a", 1);
110+
Assert.assertEquals(1, (int) map.getByKey("a"));
111+
}
112+
113+
@Test
114+
public void getByKey() {
115+
BiMap<String, Integer> map = new BiMap<String, Integer>();
116+
map.put("a", 1);
117+
Assert.assertEquals("a", map.getByValue(1));
118+
}
119+
120+
@Test
121+
public void removeByKey() {
122+
BiMap<String, Integer> map = new BiMap<String, Integer>();
123+
map.put("a", 1);
124+
map.removeByKey("a");
125+
Assert.assertEquals(0, map.size());
126+
}
127+
128+
@Test
129+
public void removeByValue() {
130+
BiMap<String, Integer> map = new BiMap<String, Integer>();
131+
map.put("a", 1);
132+
map.removeByValue(1);
133+
Assert.assertEquals(0, map.size());
134+
}
135+
136+
@Test
137+
public void removeOnEmptyMap() {
138+
BiMap<String, Integer> map = new BiMap<String, Integer>();
139+
map.removeByKey("a");
140+
map.removeByValue(1);
141+
Assert.assertEquals(0, map.size());
142+
}
143+
144+
}

0 commit comments

Comments
 (0)