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

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

Go to download

Stanford CoreNLP provides a set of natural language analysis tools which can take raw English language text input and give the base forms of words, their parts of speech, whether they are names of companies, people, etc., normalize dates, times, and numeric quantities, mark up the structure of sentences in terms of phrases and word dependencies, and indicate which noun phrases refer to the same entities. It provides the foundational building blocks for higher level text understanding applications.

There is a newer version: 4.5.7
Show newest version
package edu.stanford.nlp.util;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.Serializable;
import java.util.Comparator;
import java.util.List;

import edu.stanford.nlp.util.logging.PrettyLoggable;
import edu.stanford.nlp.util.logging.PrettyLogger;
import edu.stanford.nlp.util.logging.Redwood.RedwoodChannels;

/**
 * Pair is a Class for holding mutable pairs of objects.
 *
 * Implementation note:
 * on a 32-bit JVM uses ~ 8 (this) + 4 (first) + 4 (second) = 16 bytes.
 * on a 64-bit JVM uses ~ 16 (this) + 8 (first) + 8 (second) = 32 bytes.
 *
 * Many applications use a lot of Pairs so it's good to keep this
 * number small.
 *
 * @author Dan Klein
 * @author Christopher Manning (added stuff from Kristina's, rounded out)
 * @version 2002/08/25
 */

public class Pair  implements Comparable>, Serializable, PrettyLoggable {

  /**
   * Direct access is deprecated.  Use first().
   *
   * @serial
   */
  public T1 first;

  /**
   * Direct access is deprecated.  Use second().
   *
   * @serial
   */
  public T2 second;

  public Pair() {
    // first = null; second = null; -- default initialization
  }

  public Pair(T1 first, T2 second) {
    this.first = first;
    this.second = second;
  }

  public T1 first() {
    return first;
  }

  public T2 second() {
    return second;
  }

  public void setFirst(T1 o) {
    first = o;
  }

  public void setSecond(T2 o) {
    second = o;
  }

  @Override
  public String toString() {
    return "(" + first + "," + second + ")";
  }

  @Override
  public boolean equals(Object o) {
    if (o instanceof Pair) {
      @SuppressWarnings("rawtypes")
      Pair p = (Pair) o;
      return (first == null ? p.first() == null : first.equals(p.first())) && (second == null ? p.second() == null : second.equals(p.second()));
    } else {
      return false;
    }
  }

  @Override
  public int hashCode() {
    int firstHash  = (first == null ? 0 : first.hashCode());
    int secondHash = (second == null ? 0 : second.hashCode());

    return firstHash*31 + secondHash;
  }

  public List asList() {
    return CollectionUtils.makeList(first, second);
  }

  /**
   * Read a string representation of a Pair from a DataStream.
   * This might not work correctly unless the pair of objects are of type
   * String.
   */
  public static Pair readStringPair(DataInputStream in) {
    Pair p = new Pair<>();
    try {
      p.first = in.readUTF();
      p.second = in.readUTF();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return p;
  }

  /**
   * Returns a Pair constructed from X and Y.  Convenience method; the
   * compiler will disambiguate the classes used for you so that you
   * don't have to write out potentially long class names.
   */
  public static  Pair makePair(X x, Y y) {
    return new Pair<>(x, y);
  }

  /**
   * Write a string representation of a Pair to a DataStream.
   * The toString() method is called on each of the pair
   * of objects and a String representation is written.
   * This might not allow one to recover the pair of objects unless they
   * are of type String.
   */
  public void save(DataOutputStream out) {
    try {
      out.writeUTF(first.toString());
      out.writeUTF(second.toString());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Compares this Pair to another object.
   * If the object is a Pair, this function will work providing
   * the elements of the Pair are themselves comparable.
   * It will then return a value based on the pair of objects, where
   * p > q iff p.first() > q.first() ||
   * (p.first().equals(q.first()) && p.second() > q.second()).
   * If the other object is not a Pair, it throws a
   * ClassCastException.
   *
   * @param another the Object to be compared.
   * @return the value 0 if the argument is a
   *         Pair equal to this Pair; a value less than
   *         0 if the argument is a Pair
   *         greater than this Pair; and a value
   *         greater than 0 if the argument is a
   *         Pair less than this Pair.
   * @throws ClassCastException if the argument is not a
   *                            Pair.
   * @see java.lang.Comparable
   */
  @SuppressWarnings("unchecked")
  public int compareTo(Pair another) {
    if (first() instanceof Comparable) {
      int comp = ((Comparable) first()).compareTo(another.first());
      if (comp != 0) {
        return comp;
      }
    }

    if (second() instanceof Comparable) {
      return ((Comparable) second()).compareTo(another.second());
    }

    if ((!(first() instanceof Comparable)) && (!(second() instanceof Comparable))) {
      throw new AssertionError("Neither element of pair comparable");
    }

    return 0;
  }

  /**
   * If first and second are Strings, then this returns an MutableInternedPair
   * where the Strings have been interned, and if this Pair is serialized
   * and then deserialized, first and second are interned upon
   * deserialization.
   *
   * @param p A pair of Strings
   * @return MutableInternedPair, with same first and second as this.
   */
  public static Pair stringIntern(Pair p) {
    return new MutableInternedPair(p);
  }

  /**
   * Returns an MutableInternedPair where the Strings have been interned.
   * This is a factory method for creating an
   * MutableInternedPair.  It requires the arguments to be Strings.
   * If this Pair is serialized
   * and then deserialized, first and second are interned upon
   * deserialization.
   * 

Note: I put this in thinking that its use might be * faster than calling x = new Pair(a, b).stringIntern() * but it's not really clear whether this is true. * * @param first The first object * @param second The second object * @return An MutableInternedPair, with given first and second */ public static Pair internedStringPair(String first, String second) { return new MutableInternedPair(first, second); } /** * use serialVersionUID for cross version serialization compatibility */ private static final long serialVersionUID = 1360822168806852921L; static class MutableInternedPair extends Pair { private MutableInternedPair(Pair p) { super(p.first, p.second); internStrings(); } private MutableInternedPair(String first, String second) { super(first, second); internStrings(); } protected Object readResolve() { internStrings(); return this; } private void internStrings() { if (first != null) { first = first.intern(); } if (second != null) { second = second.intern(); } } // use serialVersionUID for cross version serialization compatibility private static final long serialVersionUID = 1360822168806852922L; } /** * {@inheritDoc} */ public void prettyLog(RedwoodChannels channels, String description) { PrettyLogger.log(channels, description, this.asList()); } /** * Compares a Pair to another Pair according to the first object of the pair only * This function will work providing * the first element of the Pair is comparable, otherwise will throw a * ClassCastException * @author jonathanberant * * @param * @param */ public static class ByFirstPairComparator implements Comparator> { @SuppressWarnings("unchecked") @Override public int compare(Pair pair1, Pair pair2) { return ((Comparable) pair1.first()).compareTo(pair2.first()); } } /** * Compares a Pair to another Pair according to the first object of the pair only in decreasing order * This function will work providing * the first element of the Pair is comparable, otherwise will throw a * ClassCastException * @author jonathanberant * * @param * @param */ public static class ByFirstReversePairComparator implements Comparator> { @SuppressWarnings("unchecked") @Override public int compare(Pair pair1, Pair pair2) { return -((Comparable) pair1.first()).compareTo(pair2.first()); } } /** * Compares a Pair to another Pair according to the second object of the pair only * This function will work providing * the first element of the Pair is comparable, otherwise will throw a * ClassCastException * @author jonathanberant * * @param * @param */ public static class BySecondPairComparator implements Comparator> { @SuppressWarnings("unchecked") @Override public int compare(Pair pair1, Pair pair2) { return ((Comparable) pair1.second()).compareTo(pair2.second()); } } /** * Compares a Pair to another Pair according to the second object of the pair only in decreasing order * This function will work providing * the first element of the Pair is comparable, otherwise will throw a * ClassCastException * @author jonathanberant * * @param * @param */ public static class BySecondReversePairComparator implements Comparator> { @SuppressWarnings("unchecked") @Override public int compare(Pair pair1, Pair pair2) { return -((Comparable) pair1.second()).compareTo(pair2.second()); } } }