1 /*
2  * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package jdk.internal.vm.compiler.collections;
26 
27 import java.util.Objects;
28 
29 /**
30  * Utility class representing a pair of values.
31  *
32  * @since 1.0
33  */
34 public final class Pair<L, R> {
35 
36     private static final Pair<Object, Object> EMPTY = new Pair<>(null, null);
37 
38     private final L left;
39     private final R right;
40 
41     /**
42      * Returns an empty pair.
43      *
44      * @since 1.0
45      */
46     @SuppressWarnings("unchecked")
empty()47     public static <L, R> Pair<L, R> empty() {
48         return (Pair<L, R>) EMPTY;
49     }
50 
51     /**
52      * Constructs a pair with its left value being {@code left}, or returns an empty pair if
53      * {@code left} is null.
54      *
55      * @return the constructed pair or an empty pair if {@code left} is null.
56      * @since 1.0
57      */
createLeft(L left)58     public static <L, R> Pair<L, R> createLeft(L left) {
59         if (left == null) {
60             return empty();
61         } else {
62             return new Pair<>(left, null);
63         }
64     }
65 
66     /**
67      * Constructs a pair with its right value being {@code right}, or returns an empty pair if
68      * {@code right} is null.
69      *
70      * @return the constructed pair or an empty pair if {@code right} is null.
71      * @since 1.0
72      */
createRight(R right)73     public static <L, R> Pair<L, R> createRight(R right) {
74         if (right == null) {
75             return empty();
76         } else {
77             return new Pair<>(null, right);
78         }
79     }
80 
81     /**
82      * Constructs a pair with its left value being {@code left}, and its right value being
83      * {@code right}, or returns an empty pair if both inputs are null.
84      *
85      * @return the constructed pair or an empty pair if both inputs are null.
86      * @since 1.0
87      */
create(L left, R right)88     public static <L, R> Pair<L, R> create(L left, R right) {
89         if (right == null && left == null) {
90             return empty();
91         } else {
92             return new Pair<>(left, right);
93         }
94     }
95 
Pair(L left, R right)96     private Pair(L left, R right) {
97         this.left = left;
98         this.right = right;
99     }
100 
101     /**
102      * Returns the left value of this pair.
103      *
104      * @since 1.0
105      */
getLeft()106     public L getLeft() {
107         return left;
108     }
109 
110     /**
111      * Returns the right value of this pair.
112      *
113      * @since 1.0
114      */
getRight()115     public R getRight() {
116         return right;
117     }
118 
119     /**
120      * {@inheritDoc}
121      *
122      * @since 1.0
123      */
124     @Override
hashCode()125     public int hashCode() {
126         return Objects.hashCode(left) + 31 * Objects.hashCode(right);
127     }
128 
129     /**
130      * {@inheritDoc}
131      *
132      * @since 1.0
133      */
134     @SuppressWarnings("unchecked")
135     @Override
equals(Object obj)136     public boolean equals(Object obj) {
137         if (obj == this) {
138             return true;
139         }
140 
141         if (obj instanceof Pair) {
142             Pair<L, R> pair = (Pair<L, R>) obj;
143             return Objects.equals(left, pair.left) && Objects.equals(right, pair.right);
144         }
145 
146         return false;
147     }
148 
149     /**
150      * {@inheritDoc}
151      *
152      * @since 1.0
153      */
154     @Override
toString()155     public String toString() {
156         return String.format("(%s, %s)", left, right);
157     }
158 }
159