001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.util;
021
022import java.util.Iterator;
023
024import org.apache.commons.lang3.NotImplementedException;
025import org.apache.hadoop.hbase.HConstants;
026import org.apache.yetus.audience.InterfaceAudience;
027
028/**
029 * A generic, immutable class for pairs of objects both of type <code>T</code>.
030 * @param <T>
031 * @see Pair if Types differ.
032 */
033@InterfaceAudience.Public
034public class PairOfSameType<T> implements Iterable<T> {
035  private final T first;
036  private final T second;
037
038  /**
039   * Constructor
040   * @param a operand
041   * @param b operand
042   */
043  public PairOfSameType(T a, T b) {
044    this.first = a;
045    this.second = b;
046  }
047
048  /**
049   * Return the first element stored in the pair.
050   * @return T
051   */
052  public T getFirst() {
053    return first;
054  }
055
056  /**
057   * Return the second element stored in the pair.
058   * @return T
059   */
060  public T getSecond() {
061    return second;
062  }
063
064  private static boolean equals(Object x, Object y) {
065     return (x == null && y == null) || (x != null && x.equals(y));
066  }
067
068  @Override
069  @SuppressWarnings("unchecked")
070  public boolean equals(Object other) {
071    return other instanceof PairOfSameType &&
072      equals(first, ((PairOfSameType)other).first) &&
073      equals(second, ((PairOfSameType)other).second);
074  }
075
076  @Override
077  public int hashCode() {
078    if (first == null)
079      return (second == null) ? 0 : second.hashCode() + 1;
080    else if (second == null)
081      return first.hashCode() + 2;
082    else
083      return first.hashCode() * 17 + second.hashCode();
084  }
085
086  @Override
087  public String toString() {
088    return "{" + getFirst() + "," + getSecond() + "}";
089  }
090
091  @Override
092  public Iterator<T> iterator() {
093    return new Iterator<T>() {
094      private int returned = 0;
095
096      @Override
097      public boolean hasNext() {
098        return this.returned < 2;
099      }
100
101      @Override
102      public T next() {
103        if (++this.returned == 1) return getFirst();
104        else if (this.returned == 2) return getSecond();
105        else throw new IllegalAccessError("this.returned=" + this.returned);
106      }
107
108      @Override
109      public void remove() {
110        throw new NotImplementedException(HConstants.NOT_IMPLEMENTED);
111      }
112    };
113  }
114}