Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 150 additions & 4 deletions src/main/java/de/comparus/opensource/longmap/LongMapImpl.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,189 @@
package de.comparus.opensource.longmap;

import java.util.Arrays;

public class LongMapImpl<V> implements LongMap<V> {

private static final int DEFAULT_CAPACITY = 20;

private int size;
private int capacity;
private Entry<V>[] table;

public LongMapImpl() {
this.capacity = DEFAULT_CAPACITY;
this.table = new Entry[capacity];
}

public V put(long key, V value) {
int index = indexFor((int) key);
if (index >= table.length) {
resize(index * 2);
}
Entry<V>[] table = this.table;
for (Entry<V> e = table[index]; e != null; e = e.next) {
if (e.getKey() == key) {
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
if (++size > capacity) {
resize(table.length * 2);
table = this.table;
index = indexFor((int) key);
}
Entry<V> e = table[index];
table[index] = new Entry<>(key, value, e);
return null;
}

public V get(long key) {
int index = indexFor((int) key);
if (index > table.length) {
return null;
}
for (Entry<V> e = table[index]; e != null; e = e.next) {
if (e.getKey() == key) {
return e.getValue();
}
}
return null;
}

public V remove(long key) {
int index = indexFor((int) key);
if (index > table.length) {
return null;
}
Entry<V> prev = null;
Entry<V> e = table[index];
while (e != null) {
if (e.getKey() == key) {
if (prev == null) {
table[index] = e.next;
} else {
prev.next = e.next;
}
size--;
return e.value;
}
prev = e;
e = e.next;
}
return null;
}

public boolean isEmpty() {
return false;
return size == 0;
}

public boolean containsKey(long key) {
int index = indexFor((int) key);
if (index > table.length) {
return false;
}
for (Entry<V> e = table[index]; e != null; e = e.next) {
if (e.getKey() == key) {
return true;
}
}
return false;
}

public boolean containsValue(V value) {
if (value == null) {
for (int i = 0; i < table.length; i++) {
for (Entry<V> e = table[i]; e != null; e = e.next) {
if (e.value == null) {
return true;
}
}
}
} else {
for (int i = 0; i < table.length; i++) {
for (Entry<V> e = table[i]; e != null; e = e.next) {
if (value.equals(e.value)) {
return true;
}
}
}
}
return false;
}

public long[] keys() {
return null;
long[] result = new long[size];
int i = 0;
for (Entry<V> entry : table) {
while (entry != null) {
result[i++] = entry.key;
entry = entry.next;
}
}
return result;
}

public V[] values() {
return null;
V[] result = (V[]) new Object[size];
int i = 0;
for (Entry<V> e : table) {
while (e != null) {
result[i++] = e.value;
e = e.next;
}
}
return result;
}

public long size() {
return 0;
return size;
}

public void clear() {
Arrays.fill(table, null);
size = 0;
}

private int indexFor(int hash) {
return Math.abs(hash);
}

private void resize(int newCapacity) {
Entry<V>[] newTable = new Entry[newCapacity];
for (Entry<V> vEntry : table) {
Entry<V> entry = vEntry;
while (entry != null) {
int newIndex = indexFor((int) entry.getKey());
Entry<V> next = entry.next;

entry.next = newTable[newIndex];
newTable[newIndex] = entry;

entry = next;
}
}
table = newTable;
capacity = newCapacity;
}

private static class Entry<V> {
final long key;
V value;
Entry<V> next;

Entry(long key, V value, Entry<V> next) {
this.key = key;
this.value = value;
this.next = next;
}

public long getKey() {
return key;
}

public V getValue() {
return value;
}
}
}
132 changes: 132 additions & 0 deletions src/test/java/de/comparus/opensource/longmap/LongMapImplTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package de.comparus.opensource.longmap;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class LongMapImplTest {
private LongMapImpl<String> map;

@Before
public void setUp() {
map = new LongMapImpl<>();
}

@Test
public void testPutAndGet() {
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(-4, "minus four");
map.put(-1, "minus one");
map.put(20, "twenty");
map.put(50, "fifty");
map.put(-500, "minus five hundred");
map.put(0, null);

assertEquals("one", map.get(1));
assertEquals("two", map.get(2));
assertEquals("three", map.get(3));
assertEquals("minus one", map.get(-1));
assertEquals("minus four", map.get(-4));
assertEquals("twenty", map.get(20));
assertEquals("fifty", map.get(50));
assertEquals("minus five hundred", map.get(-500));
assertEquals(9, map.size());
assertNull(map.get(0));
assertNull(map.get(5));
assertNull(map.get(500));
}

@Test
public void testRemove() {
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");

assertEquals("two", map.remove(2));
assertNull(map.get(2));
assertEquals(2, map.size());
assertNull(map.remove(4));
assertNull(map.remove(500));
}

@Test
public void testIsEmpty() {
assertTrue(map.isEmpty());

map.put(1, "one");
assertFalse(map.isEmpty());

map.remove(1);
assertTrue(map.isEmpty());
}

@Test
public void testContainsKey() {
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");

assertTrue(map.containsKey(1));
assertTrue(map.containsKey(2));
assertTrue(map.containsKey(3));
assertFalse(map.containsKey(4));
assertFalse(map.containsKey(500));
}

@Test
public void testContainsValue() {
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(10, null);

assertTrue(map.containsValue("one"));
assertTrue(map.containsValue("two"));
assertTrue(map.containsValue("three"));
assertTrue(map.containsValue(null));
assertFalse(map.containsValue("four"));
}

@Test
public void testKeys() {
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(-1, "minus one");
map.put(-2, "minus two");
map.put(-3, "minus three");

long[] keys = map.keys();
assertEquals(6, keys.length);
assertEquals(-1, keys[0]);
assertEquals(1, keys[1]);
assertEquals(-2, keys[2]);
assertEquals(2, keys[3]);
assertEquals(-3, keys[4]);
assertEquals(3, keys[5]);
}

@Test
public void testValues() {
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(-1, "minus one");
map.put(-2, "minus two");
map.put(-3, "minus three");
map.put(10, null);

Object[] values = map.values();
assertEquals(7, values.length);
assertEquals("minus one", values[0]);
assertEquals("one", values[1]);
assertEquals("minus two", values[2]);
assertEquals("two", values[3]);
assertEquals("minus three", values[4]);
assertEquals("three", values[5]);
assertNull(values[6]);
}
}