diff --git a/src/main/java/com/jd/jdbc/common/tuple/ImmutablePair.java b/src/main/java/com/jd/jdbc/common/tuple/ImmutablePair.java new file mode 100644 index 0000000..5848d9c --- /dev/null +++ b/src/main/java/com/jd/jdbc/common/tuple/ImmutablePair.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.jd.jdbc.common.tuple; + +import java.util.Map; + +/** + *
An immutable pair consisting of two {@code Object} elements.
+ * + *Although the implementation is immutable, there is no restriction on the objects + * that may be stored. If mutable objects are stored in the pair, then the pair + * itself effectively becomes mutable. The class is also {@code final}, so a subclass + * can not add undesirable behavior.
+ * + *#ThreadSafe# if both paired objects are thread-safe
+ * + * @param+ * Consider using {@link #emptyArray()} to avoid generics warnings. + *
+ * + * @since 3.10. + */ + public static final ImmutablePair, ?>[] EMPTY_ARRAY = new ImmutablePair[0]; + + /** + * An immutable pair of nulls. + */ + // This is not defined with generics to avoid warnings in call sites. + @SuppressWarnings("rawtypes") + private static final ImmutablePair NULL = of(null, null); + + /** + * Serialization version + */ + private static final long serialVersionUID = 4954918890077093841L; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @paramCreates an immutable pair of two objects inferring the generic types.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramCreates an immutable pair of two objects inferring the generic types.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramCreates an immutable pair from an existing pair.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramCreates an immutable pair of two objects inferring the generic types.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramThrows {@code UnsupportedOperationException}.
+ * + *This pair is immutable, so this operation is not supported.
+ * + * @param value the value to set + * @return never + * @throws UnsupportedOperationException as this operation is not supported + */ + @Override + public R setValue(final R value) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/main/java/com/jd/jdbc/common/tuple/ImmutableTriple.java b/src/main/java/com/jd/jdbc/common/tuple/ImmutableTriple.java new file mode 100644 index 0000000..0e33cab --- /dev/null +++ b/src/main/java/com/jd/jdbc/common/tuple/ImmutableTriple.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.jd.jdbc.common.tuple; + +/** + *An immutable triple consisting of three {@code Object} elements.
+ * + *Although the implementation is immutable, there is no restriction on the objects + * that may be stored. If mutable objects are stored in the triple, then the triple + * itself effectively becomes mutable. The class is also {@code final}, so a subclass + * can not add undesirable behavior.
+ * + *#ThreadSafe# if all three objects are thread-safe
+ * + * @param+ * Consider using {@link #emptyArray()} to avoid generics warnings. + *
+ * + * @since 3.10. + */ + public static final ImmutableTriple, ?, ?>[] EMPTY_ARRAY = new ImmutableTriple[0]; + + /** + * An immutable triple of nulls. + */ + // This is not defined with generics to avoid warnings in call sites. + @SuppressWarnings("rawtypes") + private static final ImmutableTriple NULL = of(null, null, null); + + /** + * Serialization version + */ + private static final long serialVersionUID = 1L; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @paramObtains an immutable triple of three objects inferring the generic types.
+ * + *This factory allows the triple to be created using inference to + * obtain the generic types.
+ * + * @paramA mutable pair consisting of two {@code Object} elements.
+ * + *Not #ThreadSafe#
+ * + * @param+ * Consider using {@link #emptyArray()} to avoid generics warnings. + *
+ * + * @since 3.10. + */ + public static final MutablePair, ?>[] EMPTY_ARRAY = new MutablePair[0]; + + /** + * Serialization version + */ + private static final long serialVersionUID = 4954918890077093841L; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @paramCreates a mutable pair of two objects inferring the generic types.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramCreates a mutable pair from an existing pair.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramA mutable triple consisting of three {@code Object} elements.
+ * + *Not #ThreadSafe#
+ * + * @param+ * Consider using {@link #emptyArray()} to avoid generics warnings. + *
+ * + * @since 3.10. + */ + public static final MutableTriple, ?, ?>[] EMPTY_ARRAY = new MutableTriple[0]; + + /** + * Serialization version + */ + private static final long serialVersionUID = 1L; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @paramObtains a mutable triple of three objects inferring the generic types.
+ * + *This factory allows the triple to be created using inference to + * obtain the generic types.
+ * + * @paramA pair consisting of two elements.
+ * + *This class is an abstract implementation defining the basic API. + * It refers to the elements as 'left' and 'right'. It also implements the + * {@code Map.Entry} interface where the key is 'left' and the value is 'right'.
+ * + *Subclass implementations may be mutable or immutable. + * However, there is no restriction on the type of the stored objects that may be stored. + * If mutable objects are stored in the pair, then the pair itself effectively becomes mutable.
+ * + * @param+ * Consider using {@link #emptyArray()} to avoid generics warnings. + *
+ * + * @since 3.10. + */ + public static final Pair, ?>[] EMPTY_ARRAY = new PairAdapter[0]; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @paramCreates an immutable pair of two objects inferring the generic types.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramCreates an immutable pair from an existing pair.
+ * + *This factory allows the pair to be created using inference to + * obtain the generic types.
+ * + * @paramCompares this pair to another based on the two elements.
+ * + * @param obj the object to compare to, null returns false + * @return true if the elements of the pair are equal + */ + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Map.Entry, ?>) { + final Map.Entry, ?> other = (Map.Entry, ?>) obj; + return Objects.equals(getKey(), other.getKey()) + && Objects.equals(getValue(), other.getValue()); + } + return false; + } + + /** + *Gets the key from this pair.
+ * + *This method implements the {@code Map.Entry} interface returning the + * left element as the key.
+ * + * @return the left element as the key, may be null + */ + @Override + public final L getKey() { + return getLeft(); + } + + //----------------------------------------------------------------------- + + /** + *Gets the left element from this pair.
+ * + *When treated as a key-value pair, this is the key.
+ * + * @return the left element, may be null + */ + public abstract L getLeft(); + + /** + *Gets the right element from this pair.
+ * + *When treated as a key-value pair, this is the value.
+ * + * @return the right element, may be null + */ + public abstract R getRight(); + + /** + *Gets the value from this pair.
+ * + *This method implements the {@code Map.Entry} interface returning the + * right element as the value.
+ * + * @return the right element as the value, may be null + */ + @Override + public R getValue() { + return getRight(); + } + + /** + *Returns a suitable hash code. + * The hash code follows the definition in {@code Map.Entry}.
+ * + * @return the hash code + */ + @Override + public int hashCode() { + // see Map.Entry API specification + return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); + } + + /** + *Returns a String representation of this pair using the format {@code ($left,$right)}.
+ * + * @return a string describing this object, not null + */ + @Override + public String toString() { + return "(" + getLeft() + ',' + getRight() + ')'; + } + + /** + *Formats the receiver using the given format.
+ * + *This uses {@link java.util.Formattable} to perform the formatting. Two variables may + * be used to embed the left and right elements. Use {@code %1$s} for the left + * element (key) and {@code %2$s} for the right element (value). + * The default format used by {@code toString()} is {@code (%1$s,%2$s)}.
+ * + * @param format the format string, optionally containing {@code %1$s} and {@code %2$s}, not null + * @return the formatted string, not null + */ + public String toString(final String format) { + return String.format(format, getLeft(), getRight()); + } + +} diff --git a/src/main/java/com/jd/jdbc/common/tuple/Triple.java b/src/main/java/com/jd/jdbc/common/tuple/Triple.java new file mode 100644 index 0000000..5cadfe4 --- /dev/null +++ b/src/main/java/com/jd/jdbc/common/tuple/Triple.java @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.jd.jdbc.common.tuple; + +import java.io.Serializable; +import java.util.Objects; + +/** + *A triple consisting of three elements.
+ * + *This class is an abstract implementation defining the basic API. + * It refers to the elements as 'left', 'middle' and 'right'.
+ * + *Subclass implementations may be mutable or immutable. + * However, there is no restriction on the type of the stored objects that may be stored. + * If mutable objects are stored in the triple, then the triple itself effectively becomes mutable.
+ * + * @param+ * Consider using {@link #emptyArray()} to avoid generics warnings. + *
+ * + * @since 3.10. + */ + public static final Triple, ?, ?>[] EMPTY_ARRAY = new TripleAdapter[0]; + + /** + * Returns the empty array singleton that can be assigned without compiler warning. + * + * @paramObtains an immutable triple of three objects inferring the generic types.
+ * + *This factory allows the triple to be created using inference to + * obtain the generic types.
+ * + * @paramCompares this triple to another based on the three elements.
+ * + * @param obj the object to compare to, null returns false + * @return true if the elements of the triple are equal + */ + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Triple, ?, ?>) { + final Triple, ?, ?> other = (Triple, ?, ?>) obj; + return Objects.equals(getLeft(), other.getLeft()) + && Objects.equals(getMiddle(), other.getMiddle()) + && Objects.equals(getRight(), other.getRight()); + } + return false; + } + + //----------------------------------------------------------------------- + + /** + *Gets the left element from this triple.
+ * + * @return the left element, may be null + */ + public abstract L getLeft(); + + /** + *Gets the middle element from this triple.
+ * + * @return the middle element, may be null + */ + public abstract M getMiddle(); + + /** + *Gets the right element from this triple.
+ * + * @return the right element, may be null + */ + public abstract R getRight(); + + /** + *Returns a suitable hash code.
+ * + * @return the hash code + */ + @Override + public int hashCode() { + return Objects.hashCode(getLeft()) ^ Objects.hashCode(getMiddle()) ^ Objects.hashCode(getRight()); + } + + /** + *Returns a String representation of this triple using the format {@code ($left,$middle,$right)}.
+ * + * @return a string describing this object, not null + */ + @Override + public String toString() { + return "(" + getLeft() + "," + getMiddle() + "," + getRight() + ")"; + } + + /** + *Formats the receiver using the given format.
+ * + *This uses {@link java.util.Formattable} to perform the formatting. Three variables may + * be used to embed the left and right elements. Use {@code %1$s} for the left + * element, {@code %2$s} for the middle and {@code %3$s} for the right element. + * The default format used by {@code toString()} is {@code (%1$s,%2$s,%3$s)}.
+ * + * @param format the format string, optionally containing {@code %1$s}, {@code %2$s} and {@code %3$s}, not null + * @return the formatted string, not null + */ + public String toString(final String format) { + return String.format(format, getLeft(), getMiddle(), getRight()); + } + +} +