[Java] TripleHashMap

[Java] TripleHashMap 0.8

No permission to download
Mit den hier vorhandenen Sourcen kann man eine HashMap erstellen, die zwei statt nur einem Key animmt. Dabei findet sie sowohl für den ersten als auch den zweiten Key ein Ergebnis, sollte einer von beiden vorhanden sein.

Was noch zu tun wäre:

- Ggf. Support für entrySet() und putAll() einbauen
- Es wird noch nicht verhindert, dass ein Key doppelt vergeben wird, das heißt, es ist möglich den Key "Test" sowohl als ersten und als zweiten Key zu verwenden. get() wird das erste gefundene Vorkommnis zurück geben, unvorhersagbar, welcher es ist. Aber vielleicht dient es als Ansatz-Punkt für weitere Ideen.
- Eine zusätzliche Idee wäre noch, statt zwei Keys mit zwei Values zu arbeiten. Das Vorgehen wäre ähnlich der Implementierung.

TripleHashMap.java
Java:
import java.util.HashMap;
import java.util.Map;

/**
 * A triple hash map, which is able to use two instead of one key for a value as
 * hash map
 * 
 * @param <K1>
 *          The first key
 * @param <K2>
 *          The second key
 * @param <V>
 *          The value
 * 
 *          TODO: Add support for putAll() and entrySet()
 */
public class TripleHashMap<K1, K2, V> extends HashMap<Pair<K1, K2>, V> implements Map<Pair<K1, K2>, V>
{
  private static final long serialVersionUID = 1L;

  public TripleHashMap()
  {
    super();
  }

  public TripleHashMap(int initialCapacity)
  {
    super(initialCapacity);
  }

  public TripleHashMap(int initialCapacity, float loadFactor)
  {
    super(initialCapacity, loadFactor);
  }

  @Override
  public boolean containsKey(Object key)
  {
    for (Pair<K1, K2> pair : this.keySet())
    {
      if (pair.getKey().equals(key) || pair.getValue().equals(key))
      {
        return true;
      }
    }
    return false;
  }

  public V get(Object key)
  {
    for (Pair<K1, K2> pair : this.keySet())
    {
      if (pair.getKey().equals(key) || pair.getValue().equals(key))
      {
        return super.get(pair);
      }
    }
    return null;
  }

  @Override
  public V remove(Object key)
  {
    V value = null;
    for (Pair<K1, K2> pair : this.keySet())
    {
      if (pair.getKey().equals(key) || pair.getValue().equals(key))
      {
        value = super.remove(pair);
        break;
      }
    }
    return value;
  }

  @Override
  public TripleHashMap<K1, K2, V> clone()
  {
    TripleHashMap<K1, K2, V> cloned = new TripleHashMap<>();
    for (Pair<K1, K2> pair : this.keySet())
    {
      cloned.put(pair, super.get(pair));
    }

    return cloned;
  }
}

Pair.java
Java:
import java.util.Map;

/**
 * Original code at
 * 
 * https://github.com/tonylukasavage/com.savagelook.android/blob
 * /master/com/savagelook/android/KeyValuePair.java
 * 
 * @param <K>
 * @param <V>
 */
public class Pair<K, V> implements Map.Entry<K, V>
{
  private final K key;
  private V       value;

  public Pair(K key, V value)
  {
    this.key = key;
    this.value = value;
  }

  @Override
  public K getKey()
  {
    return this.key;
  }

  @Override
  public V getValue()
  {
    return this.value;
  }

  @Override
  public V setValue(V value)
  {
    V old = this.value;
    this.value = value;
    return old;
  }

  @Override
  public String toString()
  {
    return this.key.toString();
  }

  @Override
  public int hashCode()
  {
    return this.key.hashCode() ^ this.value.hashCode();
  }

  public boolean equals(Pair<K, V> other)
  {
    return this.hashCode() == other.hashCode() && this.hashCode() != 0;
  }
}

TripleHashMapTest.java
Java:
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * This class is a junit 4 test for {@link TripleHashMap}
 * 
 * TODO: Add tests for putAll() and entrySet()
 * 
 */
public class TripleHashMapTest
{
  TripleHashMap<Integer, String, String> testMap;

  /**
   * @throws java.lang.Exception
   */
  @Before
  public void setUp() throws Exception
  {
    testMap = new TripleHashMap<>();
    testMap.put(new Pair<Integer, String>(1, "Identifier for first element"), "Some plain text");
    testMap.put(new Pair<Integer, String>(26, "The magic number"), "Between a square and triple");
    testMap.put(new Pair<Integer, String>(4711, "Some random lorem ipsum"), "What do you expect?");

  }

  /**
   * @throws java.lang.Exception
   */
  @After
  public void tearDown() throws Exception
  {
  }

  /**
   * Test method for {@link java.util.HashMap#clone()}.
   */
  @Test
  public void testClone()
  {
    TripleHashMap<Integer, String, String> cloned = this.testMap.clone();
    Assert.assertTrue(cloned.containsKey(26));
  }

  /**
   * Test method for {@link java.util.HashMap#size()}.
   */
  @Test
  public void testSize()
  {
    Assert.assertEquals(3L, this.testMap.size());
    Assert.assertEquals(0L, new TripleHashMap<>(5).size());
  }

  /**
   * Test method for {@link java.util.HashMap#isEmpty()}.
   */
  @Test
  public void testIsEmpty()
  {
    Assert.assertFalse(this.testMap.isEmpty());
    Assert.assertTrue(new TripleHashMap<>().isEmpty());
  }

  /**
   * Test method for {@link java.util.HashMap#containsValue(java.lang.Object)}.
   */
  @Test
  public void testContainsValue()
  {
    Assert.assertFalse(this.testMap.containsValue("A Foo Bar Text"));
    Assert.assertTrue(this.testMap.containsValue("Some plain text"));
  }

  /**
   * Test method for {@link java.util.HashMap#containsKey(java.lang.Object)}.
   */
  @Test
  public void testContainsKey()
  {
    Assert.assertTrue(this.testMap.containsKey(4711));
    Assert.assertFalse(this.testMap.containsKey(815));
  }

  /**
   * Test method for {@link java.util.HashMap#get(java.lang.Object)}.
   */
  @Test
  public void testGet()
  {
    Assert.assertEquals("Between a square and triple", this.testMap.get("The magic number"));
    Assert.assertEquals("What do you expect?", this.testMap.get(4711));
  }

  /**
   * Test method for
   * {@link java.util.HashMap#put(java.lang.Object, java.lang.Object)}.
   */
  @Test
  public void testPut()
  {
    TripleHashMap<Integer, String, String> cloned = this.testMap.clone();
    cloned.put(new Pair<Integer, String>(65535, "Upper limit of 16 bit"), "Yes, it is 2^16-1");
    Assert.assertTrue(cloned.containsKey(65535));
    Assert.assertTrue(cloned.containsValue("Yes, it is 2^16-1"));
    Assert.assertFalse(this.testMap.containsKey(65535));
  }

  /**
   * Test method for {@link java.util.HashMap#remove(java.lang.Object)}.
   */
  @Test
  public void testRemove()
  {
    TripleHashMap<Integer, String, String> cloned = this.testMap.clone();
    Assert.assertTrue(cloned.containsKey(26));

    cloned.remove(26);

    Assert.assertFalse(cloned.containsKey(26));
  }

  /**
   * Test method for {@link java.util.HashMap#clear()}.
   */
  @Test
  public void testClear()
  {
    TripleHashMap<Integer, String, String> cloned = this.testMap.clone();
    Assert.assertFalse(cloned.isEmpty());

    cloned.clear();

    Assert.assertTrue(cloned.isEmpty());
  }

  /**
   * Test method for {@link java.util.HashMap#keySet()}.
   */
  @Test
  public void testKeySet()
  {
    for (Pair<Integer, String> keys : this.testMap.keySet())
    {
      Assert.assertTrue(keys.equals(new Pair<Integer, String>(1, "Identifier for first element"))
          || keys.equals(new Pair<Integer, String>(26, "The magic number"))
          || keys.equals(new Pair<Integer, String>(4711, "Some random lorem ipsum")));
    }
  }

  /**
   * Test method for {@link java.util.HashMap#values()}.
   */
  @Test
  public void testValues()
  {
    for (String value : this.testMap.values())
    {
      Assert.assertTrue(value.equals("Some plain text") || value.equals("Between a square and triple")
          || value.equals("What do you expect?"));
    }
  }
}
Autor
saftmeister
Downloads
2
Aufrufe
81
First release
Last update
Bewertung
0,00 Stern(e) 0 Bewertungen

More resources from saftmeister