Skip to content

Instantly share code, notes, and snippets.

@bcalmac
Created March 10, 2015 18:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcalmac/79ed077c723197c111d7 to your computer and use it in GitHub Desktop.
Save bcalmac/79ed077c723197c111d7 to your computer and use it in GitHub Desktop.
Case insensitive SetMultimap using Guava
import com.google.common.collect.ForwardingSetMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
/** SetMultimap decorator that coverts keys to lower case before delegation */
public class CaseInsensitiveSetMultimap<V> extends ForwardingSetMultimap<String, V> {
private final SetMultimap<String, V> delegate;
private final Locale locale;
public CaseInsensitiveSetMultimap() {
this(LinkedHashMultimap.create());
}
public CaseInsensitiveSetMultimap(SetMultimap<String, V> delegate) {
this(delegate, Locale.ENGLISH);
}
public CaseInsensitiveSetMultimap(SetMultimap<String, V> delegate, Locale locale) {
this.delegate = delegate;
this.locale = locale;
}
@Override
protected SetMultimap<String, V> delegate() {
return delegate;
}
private String internalKey(Object key) {
return key == null ? null : key.toString().toLowerCase(locale);
}
@Override
public Set<V> get(String key) {
return super.get(internalKey(key));
}
@Override
public Set<V> removeAll(Object key) {
return super.removeAll(internalKey(key));
}
@Override
public Set<V> replaceValues(String key, Iterable<? extends V> values) {
return super.replaceValues(internalKey(key), values);
}
@Override
public boolean containsEntry(Object key, Object value) {
return super.containsEntry(internalKey(key), value);
}
@Override
public boolean containsKey(Object key) {
return super.containsKey(internalKey(key));
}
@Override
public boolean put(String key, V value) {
return super.put(internalKey(key), value);
}
@Override
public boolean putAll(String key, Iterable<? extends V> values) {
return super.putAll(internalKey(key), values);
}
@Override
public boolean putAll(Multimap<? extends String, ? extends V> multimap) {
// copied from AbstractMultimap
boolean changed = false;
for (Map.Entry<? extends String, ? extends V> entry : multimap.entries()) {
changed |= put(internalKey(entry.getKey()), entry.getValue());
}
return changed;
}
@Override
public boolean remove(Object key, Object value) {
return super.remove(internalKey(key), value);
}
}
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class CaseInsensitiveSetMultimapTest {
private CaseInsensitiveSetMultimap<Integer> m = new CaseInsensitiveSetMultimap<>();
@Test
public void testPutGet() {
assertTrue(m.put("first", 1));
assertEquals(ImmutableSet.of(1), m.get("first"));
assertFalse(m.put("FIRST", 1));
assertEquals(ImmutableSet.of(1), m.get("FIRST"));
assertFalse(m.put("First", 1));
assertEquals(ImmutableSet.of(1), m.get("First"));
assertTrue(m.put("FIRST", 10));
assertEquals(ImmutableSet.of(1, 10), m.get("First"));
}
@Test
public void testRemove() {
assertTrue(m.put("first", 1));
assertTrue(m.put("FIRST", 10));
assertTrue(m.remove("First", 10));
assertEquals(ImmutableSet.of(1), m.get("First"));
}
@Test
public void testContainsEntry() {
m.put("first", 1);
assertTrue(m.containsEntry("FIRST", 1));
}
@Test
public void testContainsKey() {
m.put("first", 1);
assertTrue(m.containsKey("FIRST"));
}
@Test
public void testNull() {
assertTrue(m.put(null, 1));
assertEquals(ImmutableSet.of(1), m.get(null));
assertTrue(m.containsEntry(null, 1));
assertTrue(m.containsKey(null));
assertTrue(m.remove(null, 1));
}
@Test
public void testPutAllIterable() {
m.put("first", 1);
m.put("FIRST", 10);
m.put("second", 2);
m.put("SECOND", 20);
assertTrue(m.putAll("First", ImmutableList.of(100, 1000)));
assertEquals(ImmutableSet.of(1, 10, 100, 1000), m.get("FIRST"));
}
@Test
public void testPutAllMultimap() {
m.put("first", 1);
m.put("FIRST", 10);
m.put("second", 2);
m.put("SECOND", 20);
assertTrue(m.putAll(ImmutableMultimap.of("First", 100, "third", 3)));
assertEquals(ImmutableSet.of(1, 10, 100), m.get("First"));
assertEquals(ImmutableSet.of(2, 20), m.get("Second"));
assertEquals(ImmutableSet.of(3), m.get("Third"));
}
@Test
public void replaceAll() {
m.put("first", 1);
m.put("FIRST", 10);
assertEquals(ImmutableSet.of(1, 10), m.replaceValues("First", ImmutableSet.of(10, 100)));
}
@Test
public void testRemoveAll() {
m.put("first", 1);
m.put("FIRST", 10);
m.put("second", 2);
assertEquals(ImmutableSet.of(1, 10), m.removeAll("First"));
assertFalse(m.containsKey("first"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment