View Javadoc

1   /*
2      Copyright 2011 Atlassian
3   
4      Licensed under the Apache License, Version 2.0 (the "License");
5      you may not use this file except in compliance with the License.
6      You may obtain a copy of the License at
7   
8          http://www.apache.org/licenses/LICENSE-2.0
9   
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15   */
16  package io.atlassian.fugue;
17  
18  import java.io.Serializable;
19  import java.util.function.BiFunction;
20  import java.util.function.Function;
21  
22  import static java.util.Objects.requireNonNull;
23  
24  /**
25   * Represents a pair of objects.
26   *
27   * @since 1.0
28   */
29  public final class Pair<A, B> implements Serializable {
30    private static final long serialVersionUID = 3054071035067921893L;
31  
32    private static final int HALF_WORD = 16;
33  
34    /**
35     * Factory method for static Pair growth.
36     *
37     * @param <A> the left value type
38     * @param <B> the right value type
39     * @param left value, cannot be null
40     * @param right value, cannot be null
41     * @return the Pair containing the passed values
42     */
43    public static <A, B> Pair<A, B> pair(final A left, final B right) {
44      return new Pair<>(left, right);
45    }
46  
47    /**
48     * Factory method for a Pair factory function.
49     *
50     * @param <A> the left value type
51     * @param <B> the right value type
52     * @return a function that constructs Pairs
53     */
54    public static <A, B> BiFunction<A, B, Pair<A, B>> pairs() {
55      return Pair::pair;
56    }
57  
58    /**
59     * Function for accessing the left value of {@link Pair pairs}.
60     *
61     * @param <A> the left value type
62     * @return a Function that given a {@link io.atlassian.fugue.Pair} returns the
63     * left side value
64     * @since 1.1
65     */
66    public static <A> Function<Pair<A, ?>, A> leftValue() {
67      return Pair::left;
68    }
69  
70    /**
71     * Function for accessing the right value of {@link Pair pairs}.
72     *
73     * @param <B> the right value type
74     * @return a Function that given a {@link io.atlassian.fugue.Pair} returns the
75     * right side value
76     * @since 1.1
77     */
78    public static <B> Function<Pair<?, B>, B> rightValue() {
79      return Pair::right;
80    }
81  
82    /**
83     * Performs function application within an homogeneous pair (applicative
84     * functor pattern).
85     *
86     * @param aa an homogeneous pair
87     * @param ff The pair of functions to apply.
88     * @return A new pair after applying the given pair of functions through aa.
89     */
90    public static <A, B> Pair<B, B> ap(final Pair<A, A> aa, final Pair<Function<A, B>, Function<A, B>> ff) {
91      return Pair.pair(ff.left().apply(aa.left()), ff.right().apply(aa.right()));
92    }
93  
94    /**
95     * Apply a function to both elements of an homogeneous pair.
96     *
97     * @param aa an homogeneous pair
98     * @param f function to apply to both elements of aa
99     * @return A new pair after applying the function to aa elements.
100    */
101   public static <A, B> Pair<B, B> map(final Pair<A, A> aa, final Function<A, B> f) {
102     return Pair.pair(f.apply(aa.left()), f.apply(aa.right()));
103   }
104 
105   /**
106    * Zips two iterables into a single iterable that produces {@link Pair pairs}.
107    *
108    * @param <A> LHS type
109    * @param <B> RHS type
110    * @param as left values
111    * @param bs right values
112    * @return an {@link Iterable iterable} of pairs, only as long as the shortest
113    * input iterable.
114    * @since 1.1
115    */
116   public static <A, B> Iterable<Pair<A, B>> zip(final Iterable<A> as, final Iterable<B> bs) {
117     return Iterables.zip(as, bs);
118   }
119 
120   //
121   // members
122   //
123 
124   private final A left;
125   private final B right;
126 
127   /**
128    * Constructor for Pair.
129    *
130    * @param left value, cannot be null
131    * @param right value, cannot be null
132    */
133   public Pair(final A left, final B right) {
134     this.left = requireNonNull(left, "Left parameter must not be null.");
135     this.right = requireNonNull(right, "Right parameter must not be null.");
136   }
137 
138   /**
139    * Accessor method for the left value of the pair.
140    *
141    * @return a A object.
142    */
143   public A left() {
144     return left;
145   }
146 
147   /**
148    * Accessor method for the right value of the pair.q
149    *
150    * @return a B object.
151    */
152   public B right() {
153     return right;
154   }
155 
156   /** {@inheritDoc} */
157   @Override public String toString() {
158     return "Pair(" + left + ", " + right + ")";
159   }
160 
161   /** {@inheritDoc} */
162   @Override public boolean equals(final Object o) {
163     if (o == null) {
164       return false;
165     }
166     if (this == o) {
167       return true;
168     }
169 
170     if (!(o instanceof Pair<?, ?>)) {
171       return false;
172     }
173     final Pair<?, ?> that = (Pair<?, ?>) o;
174     return left.equals(that.left) && right.equals(that.right);
175   }
176 
177   /** {@inheritDoc} */
178   @Override public int hashCode() {
179     final int lh = left.hashCode();
180     final int rh = right.hashCode();
181     return (((lh >> HALF_WORD) ^ lh) << HALF_WORD) | (((rh << HALF_WORD) ^ rh) >> HALF_WORD);
182   }
183 }