Skip to content

Instantly share code, notes, and snippets.

@josefbetancourt
Last active November 10, 2015 11:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josefbetancourt/59571b347bd11ae686ad to your computer and use it in GitHub Desktop.
Save josefbetancourt/59571b347bd11ae686ad to your computer and use it in GitHub Desktop.
package com.octodecillion.util;
import java.util.Map;
import java.util.Map.Entry;
/**
* A {@link Map} decorator that allows
* <a href="https://en.wikipedia.org/wiki/Fluent_interface#Java">Fluent</a>
* add of entries.<p>
*
* Example use:
* <pre>
* Map&lt;String, String> actual =
* InitMap.with(new HashMap<String,String>())
* .put("key1", "value1")
* .put("key2", "value2")
* .toMap();
* </pre>
*
* <b>Notes</b><br>
* Thread safety: Not safe.
* <p>
*
* @param <K> the entry key type
* @param <V> the entry value type
*
* @author josef betancourt
* @since Nov 7, 2015
*/
public class InitMap<K, V> {
// the decorated Map
private Map<K, V> map;
/**
* Constructor.
* @param map2 Map to decorate
*/
private InitMap(final Map<K,V> map) {
this.map = (Map<K, V>) map;
}
/**
* Factory method (?).
* @param map
* @return
*/
public static <K,V> InitMap<K, V> with(final Map<K,V> map){
if (map == null) {
throw new NullPointerException("map cannot be null");
}
return new InitMap<K, V>(map);
}
/**
* Put key,value which invokes {@link Map#put(K, V)} to internal map.
* <p>
*
* @see Map#put(Object, Object)
*
* @param key entry key
* @param value entry value
* @return the FluentMap instance
* @throws RuntimeException
* that underlying Map can throw.
*/
public InitMap<K, V> put(K key, V value) {
this.map.put(key, value);
return this;
}
/**
* Add a bunch of entries.
* <p>
* To add non-attached Entries, Entry subclasses such as Apached lang3 Pair
* can be used.
*
* Example use:
*
* <pre>
* Map&lt;String, String> actual = InitMap.with(new HashMap<String, String>())
* .put(new Pair("key1", "value1"))
* .put(new Pair("key2", "value2"))
* .toMap();
* </pre>
*
* Cons:<br>
* Too wordy! Any use case for this?
*
* @param entries
* @return
*/
public InitMap<K, V> puts(@SuppressWarnings("unchecked") Map.Entry<K, V>... entries) {
for (Entry<K, V> entry : entries) {
put(entry.getKey(), entry.getValue());
}
return this;
}
/**
* Return the client map.
*
* @return Map<K,V>
*/
public Map<K, V> toMap() {
return map;
}
}
package com.octodecillion.util;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Test {@link InitMap}.
*
* @author josef betancourt
*
*/
public class InitMapTest {
@Rule
public LogRule logRule = new LogRule();
/** Test {@link InitMap#put(Object, Object)}. */
@Test
public void shouldPut(){
Map<String, String> map = new HashMap<String,String>();
InitMap<String, String> fm = InitMap.with(map);
fm.put("key1", "value1");
Assert.assertThat(map.get("key1"),equalTo("value1"));
}
/** Test {@link InitMap#toMap()}. */
@Test
public void shouldToMap(){
Map<String, String> actual = InitMap.with(new HashMap<String,String>())
.put("key1", "value1")
.put("key2", "value2")
.toMap();
Assert.assertThat(actual,instanceOf(HashMap.class));
Assert.assertThat(actual.get("key1"),equalTo("value1"));
Assert.assertThat(actual.get("key2"),equalTo("value2"));
}
/** Test {@link InitMap#InitMap(Map)}. */
@Test(expected=NullPointerException.class)
public void should_throwNPE(){
InitMap.with(null);
}
/** */
static class LogRule implements TestRule{
@Override
public Statement apply(final Statement base, Description description ) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
System.out.println("Running ... " + description.getMethodName());
base.evaluate();
}
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment