1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.base;
33
34 import org.spf4j.io.Csv;
35 import com.google.common.base.Objects;
36 import java.beans.ConstructorProperties;
37 import java.io.IOException;
38 import java.io.StringReader;
39 import java.io.UncheckedIOException;
40 import java.util.LinkedHashMap;
41 import java.util.List;
42 import java.util.Map;
43 import javax.annotation.Nonnull;
44 import javax.annotation.Nullable;
45
46
47
48
49
50 public class Pair<A, B> implements Map.Entry<A, B>, Writeable {
51
52
53 @Nullable
54 protected final A first;
55
56 @Nullable
57 protected final B second;
58
59
60 @ConstructorProperties({"first", "second"})
61 public Pair(@Nullable final A first, @Nullable final B second) {
62 this.first = first;
63 this.second = second;
64 }
65
66 public static <A, B> Pair<A, B> of(@Nullable final A first, @Nullable final B second) {
67 return new Pair<>(first, second);
68 }
69
70
71
72
73
74
75
76 @Nullable
77 public static Pair<String, String> from(@Nonnull final String stringPair) {
78 if (stringPair.isEmpty()) {
79 return null;
80 }
81 int commaIdx = stringPair.indexOf(',');
82 if (commaIdx < 0) {
83 return null;
84 }
85 StringReader sr = new StringReader(stringPair);
86 StringBuilder first = new StringBuilder();
87 StringBuilder second = new StringBuilder();
88 int comma;
89 try {
90 comma = Csv.readCsvElement(sr, first);
91 if (comma != ',') {
92 return null;
93 }
94 int last = Csv.readCsvElement(sr, second);
95 if (last >= 0) {
96 return null;
97 }
98 } catch (IOException ex) {
99 throw new UncheckedIOException(ex);
100 }
101 return Pair.of(first.toString(), second.toString());
102 }
103
104 public final A getFirst() {
105 return first;
106 }
107
108 public final B getSecond() {
109 return second;
110 }
111
112 @Override
113 public final boolean equals(final Object obj) {
114 if (obj == null) {
115 return false;
116 }
117 if (getClass() != obj.getClass()) {
118 return false;
119 }
120 final Pair<A, B> other = (Pair<A, B>) obj;
121 if (this.first != other.first && (this.first == null || !this.first.equals(other.first))) {
122 return false;
123 }
124 return (!(this.second != other.second && (this.second == null || !this.second.equals(other.second))));
125 }
126
127 @Override
128 public final int hashCode() {
129 return Objects.hashCode(first, second);
130 }
131
132
133
134
135
136 @Override
137 public String toString() {
138 StringBuilder result = new StringBuilder(32);
139 writeTo(result);
140 return result.toString();
141 }
142
143 @Override
144 public final void writeTo(final Appendable appendable) throws IOException {
145 Csv.writeCsvElement(first == null ? "" : first.toString(), appendable);
146 appendable.append(',');
147 Csv.writeCsvElement(second == null ? "" : second.toString(), appendable);
148 }
149
150 public final List<Object> toList() {
151 return java.util.Arrays.asList(first, second);
152 }
153
154 public static <K, V extends Object> Map<K, V> asMap(final Pair<K, ? extends V>... pairs) {
155 Map<K, V> result = new LinkedHashMap<>(pairs.length);
156 for (Pair<K, ? extends V> pair : pairs) {
157 result.put(pair.getFirst(), pair.getSecond());
158 }
159 return result;
160 }
161
162 @Override
163 public final A getKey() {
164 return first;
165 }
166
167 @Override
168 public final B getValue() {
169 return second;
170 }
171
172 @Override
173 public final B setValue(final B value) {
174 throw new UnsupportedOperationException("Object not mutable");
175 }
176
177 }