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

com.healthmarketscience.common.util.Tuple1 Maven / Gradle / Ivy

The newest version!
/*
Copyright (c) 2007 Health Market Science, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.healthmarketscience.common.util;

import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.RandomAccess;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * Simple class for holding a single typed object (useful for returning
 * additional objects from a method call).  For convenience, a Tuple can act
 * like an unmodifiable List of Object of a fixed size (the number of
 * elements in the tuple).
 *
 * @author James Ahlborn
 */
public class Tuple1
  extends AbstractList
  implements Serializable, List, RandomAccess, Cloneable
{

  private static final long serialVersionUID = 20071230;
  
  /** 
   * Helper array to get direct indexed access to the tuple values.
   */
  static final Accessor[] ACCESSORS1 = {
    new Accessor() {
      @Override
      public Object get(Tuple1 tuple) { return tuple.get0(); }
    }
  };
  
  /** 
   * The value stored in this tuple.
   */
  private ObjType0 _obj0;
  
  /**
   * Initializes a new Tuple1 with a null object.
   */
  public Tuple1() {
    this(null);
  }

  /**
   * Initializes a new Tuple1 with the provided object. You may want to use
   * {@link #create} instead, since it infers the type parameter based on
   * its argument.
   *
   * @param obj the object to store in this Tuple1.
   */
  public Tuple1(ObjType0 obj) {
    _obj0 = obj;
  }

  /**
   * Creates a new Tuple1 with the provided object.
   *
   * @param obj0 the object to store in this Tuple1.
   * @return a new Tuple1 with the provided object.
   */
  public static  Tuple1 create(InObjType0 obj0)
  {
    return new Tuple1(obj0);
  }

  /**
   * Returns an Iterable adapter that returns an Iterator that iterates over
   * element 0 of the tuples within the given Iterable/Iterator.  The returned
   * Iterator supports element removal if the given Iterable supports element 
   * removal. 
   *
   * @return an Iterable adapter that returns an Iterator that iterates
   *         over element 0 of the Tuples within the given Iterable/Iterator.
   *         
   */
  public static  Iterable iterable0(
      final Iterable> iable)
  {
    return new IterableIterator()
      {
        private final Iterator> _iter =
          iable.iterator();
        public boolean hasNext() {
          return _iter.hasNext();
        }
        public InObjType0 next() {
          return _iter.next().get0();
        }
        public void remove() {
          _iter.remove();
        }
      };
  }

  /** 
   * Returns a Collection adapter for element 0 of the Tuples of the given
   * Collection.  The returned Collection supports element removal if the given
   * Collection supports element removal, but does not support element 
   * addition.
   *
   * @return a Collection adapter for element 0 of the Tuples of the given
   *         Collection.  
   */
  public static  Collection collection0(
      final Collection> col)
  {
    return new AbstractCollection()
      {
        private final Collection> _col = col;
        @Override
        public Iterator iterator() {
          return iterable0(_col).iterator();
        }
        @Override
        public int size() { return _col.size(); }
      };
  }
  
  /**
   * Get the object of this tuple.
   *
   * @return the object of this tuple.
   */
  public final ObjType0 get0() { return _obj0; }

  /**
   * Sets the object of this tuple.
   *
   * @param obj the object to store in this tuple.
   */
  public final void set0(ObjType0 obj) { _obj0 = obj; }

  /**
   * Gets the object value of this tuple as an Object array.
   *
   * @return the object value of this tuple as an Object array.
   */
  public Object[] get() { return new Object[]{get0()}; }

  /** 
   * Get the value of this tuple identified by index, which must always be
   * 0, since this tuple class stores exactly one object.
   *
   * @param index the index of the object to retrieve.  Must be 0.
   * @return the object in this tuple with the given index.
   */
  @Override
  public Object get(int index) { return ACCESSORS1[index].get(this); }

  /**
   * Sets the value of this tuple.
   *
   * @param obj0 the value to store in this tuple.
   */
  public final void set(ObjType0 obj0) { set0(obj0); }

  /** 
   * Get the size of this tuple, which is always 1.
   *
   * @return 1
   */
  @Override
  public int size() { return 1; }

  /** 
   * Makes a copy of this Tuple1.
   * 
   * @return a copy of this Tuple1.
   */
  @SuppressWarnings({"unchecked",
                     "PMD.CloneThrowsCloneNotSupportedException"})
  @Override
    //@SuppressWarnings("unchecked")
  public Tuple1 clone() {
    try {
      return (Tuple1)super.clone();
    } catch(CloneNotSupportedException e) {
      // this shouldn't happen, since we are Cloneable
      throw new UnsupportedOperationException(e);
    }
  }

  /** 
   * Indicates whether the given Object is equal to this Tuple1.
   * @return 
   *  
  • {@code true} if the given Object refers to this Tuple1.
  • *
  • {@code true} if the given Object is an instance of Tuple1 for which * the contained object is equal to this Tuple1's object.
  • *
  • {@code false} otherwise.
  • */ @Override public boolean equals(Object o) { if(this == o) { return true; } if((o == null) || (o.getClass() != getClass())) { return false; } return new EqualsBuilder() .append(get0(), ((Tuple1)o).get0()) .isEquals(); } /** * Returns a hash code for this Tuple1, based on the object it contains. * * @return a hash code for this Tuple1. */ @Override public int hashCode() { return new HashCodeBuilder() .append(get0()) .toHashCode(); } /** * Helper class to enable direct indexed access to the tuple values. */ protected abstract static class Accessor { public abstract Object get(Tuple1 tuple); } /** * An Iterable whose iterator method returns itself. */ protected static abstract class IterableIterator implements Iterable, Iterator { public Iterator iterator() { return this; } } }