All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.stanford.nlp.util.ArrayMap Maven / Gradle / Ivy

package edu.stanford.nlp.util;

import java.io.Serializable;
import java.util.*;

/**
 * Map backed by an Array.
 *
 * @author Dan Klein
 * @author Roger Levy
 */
public final class ArrayMap extends AbstractMap implements Serializable {

  private static final long serialVersionUID = 1L;

  private Entry[] entryArray;
  private int capacity;
  private int size;

  static final class Entry implements Map.Entry, Serializable {

    private static final long serialVersionUID = 1L;

    @SuppressWarnings({"NonSerializableFieldInSerializableClass"})
    private final K key;
    @SuppressWarnings({"NonSerializableFieldInSerializableClass"})
    private V value;

    public K getKey() {
      return key;
    }

    public V getValue() {
      return value;
    }

    public V setValue(V o) {
      V old = value;
      value = o;
      return old;
    }

    @Override
    public int hashCode() {
      return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode());
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (! (o instanceof Entry)) {
        return false;
      }
      Entry e = (Entry) o;
      return (getKey() == null ? e.getKey() == null : getKey().equals(e.getKey())) && (getValue() == null ? e.getValue() == null : getValue().equals(e.getValue()));
    }


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

    public String toString() {
      return key + "=" + value;
    }
  }


  @SuppressWarnings("unchecked")
  public ArrayMap() {
    size = 0;
    capacity = 2;
    entryArray = new Entry[2];
  }

  @SuppressWarnings("unchecked")
  public ArrayMap(int capacity) {
    size = 0;
    this.capacity = capacity;
    entryArray = new Entry[capacity];
  }

  @SuppressWarnings("unchecked")
  public ArrayMap(Map m) {
	  size = 0;
	  capacity = m.size();
	  entryArray = new Entry[m.size()];
	  this.putAll(m);
  }

  @SuppressWarnings("unchecked")
  public ArrayMap(K[] keys, V[] values) {
    if (keys.length!=values.length) throw new IllegalArgumentException("different number of keys and values.");
    size = keys.length;
    capacity = size;
    entryArray = new Entry[size];
    for (int i=0; i ArrayMap newArrayMap() {
    return new ArrayMap<>();
  }

  public static  ArrayMap newArrayMap(int capacity) {
    return new ArrayMap<>(capacity);
  }

  @Override
  public Set> entrySet() {
    //throw new java.lang.UnsupportedOperationException();
    return new HashSet>(Arrays.asList(entryArray).subList(0, size)) {
      private static final long serialVersionUID = 2746535724049192751L;
      @Override
      public boolean remove(Object o) {
        if (o instanceof Map.Entry) {
          Map.Entry entry = (Map.Entry) o;
          ArrayMap.this.remove(entry.getKey());
          return super.remove(o);
        } else {
          return false;
        }
      }
      @Override
      public void clear() {
        super.clear();
        ArrayMap.this.clear();
      }
    };
  }

  @Override
  public int size() {
    return size;
  }

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

  @SuppressWarnings("unchecked")
  private void resize() {
    Entry[] oldEntryArray = entryArray;
    int newCapacity = 2*size;
    if (newCapacity==0) newCapacity=1;
    entryArray = new Entry[newCapacity];
    System.arraycopy(oldEntryArray, 0, entryArray, 0, size);
    capacity = newCapacity;
  }

  @Override
  public void clear() {
    size = 0;
  }

  @Override
  public V put(K key, V val) {
    for (int i = 0; i < size; i++) {
      if (key.equals(entryArray[i].getKey())) {
        return entryArray[i].setValue(val);
      }
    }
    if (capacity <= size) {
      resize();
    }
    entryArray[size] = new Entry<>(key, val);
    size++;
    return null;
  }

  @Override
  public V get(Object key) {
    for (int i = 0; i < size; i++) {
      if (key == null ? entryArray[i].getKey() == null : key.equals(entryArray[i].getKey())) {
        return entryArray[i].getValue();
      }
    }
    return null;
  }

  @Override
  public V remove(Object key) {
    for (int i = 0; i < size; i++) {
      if (key == null ? entryArray[i].getKey() == null : key.equals(entryArray[i].getKey())) {
        V value = entryArray[i].getValue();
        if (size > 1) {
          entryArray[i] = entryArray[size - 1];
        }
        size--;
        return value;
      }
    }
    return null;
  }

  protected int hashCodeCache; // = 0;

  @Override
  public int hashCode() {
    if (hashCodeCache == 0) {
      // this is now the djb2 (Dan Bernstein) hash; it used to be the awful K&R 1st ed. hash which simply summed hash codes, but that's very bad form.
      int hashCode = 5381;
      for (int i = 0; i < size; i++) {
        hashCode = hashCode * 33 + entryArray[i].hashCode();
      }
      hashCodeCache = hashCode;
    }
    return hashCodeCache;
  }

  @SuppressWarnings("unchecked")
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if ( ! (o instanceof Map)) {
      return false;
    }
    Map m = (Map) o;
    for (int i = 0; i < size; i++) {
      Object mVal = m.get(entryArray[i].getKey());
      if (mVal == null) {
        if (entryArray[i] != null) {
          return false;
        } else {
          continue;
        }
      }
      if (!m.get(entryArray[i].getKey()).equals(entryArray[i].getValue())) {
        return false;
      }
    }
    return true;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy