From 89f7dfff5ad657d8da828d7c7cd01a51f577729d Mon Sep 17 00:00:00 2001 From: wangweicugw Date: Sat, 6 May 2023 15:51:27 +0800 Subject: [PATCH] add pair&triple --- .../jd/jdbc/common/tuple/ImmutablePair.java | 210 ++++++++++++++++ .../jd/jdbc/common/tuple/ImmutableTriple.java | 159 +++++++++++++ .../com/jd/jdbc/common/tuple/MutablePair.java | 180 ++++++++++++++ .../jd/jdbc/common/tuple/MutableTriple.java | 168 +++++++++++++ .../java/com/jd/jdbc/common/tuple/Pair.java | 224 ++++++++++++++++++ .../java/com/jd/jdbc/common/tuple/Triple.java | 187 +++++++++++++++ 6 files changed, 1128 insertions(+) create mode 100644 src/main/java/com/jd/jdbc/common/tuple/ImmutablePair.java create mode 100644 src/main/java/com/jd/jdbc/common/tuple/ImmutableTriple.java create mode 100644 src/main/java/com/jd/jdbc/common/tuple/MutablePair.java create mode 100644 src/main/java/com/jd/jdbc/common/tuple/MutableTriple.java create mode 100644 src/main/java/com/jd/jdbc/common/tuple/Pair.java create mode 100644 src/main/java/com/jd/jdbc/common/tuple/Triple.java 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 the left element type + * @param the right element type + * @since 3.0 + */ +public final class ImmutablePair extends Pair { + + /** + * An empty array. + *

+ * 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. + * + * @param the left element type + * @param the right element type + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10. + */ + @SuppressWarnings("unchecked") + public static ImmutablePair[] emptyArray() { + return (ImmutablePair[]) EMPTY_ARRAY; + } + + /** + *

Creates 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.

+ * + * @param the left element type + * @param the right element type + * @param left the left element, may be null + * @return a pair formed from the two parameters, not null + * @since 3.11 + */ + public static Pair left(final L left) { + return ImmutablePair.of(left, null); + } + + /** + * Returns an immutable pair of nulls. + * + * @param the left element of this pair. Value is {@code null}. + * @param the right element of this pair. Value is {@code null}. + * @return an immutable pair of nulls. + * @since 3.6 + */ + public static ImmutablePair nullPair() { + return NULL; + } + + /** + *

Creates 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.

+ * + * @param the left element type + * @param the right element type + * @param left the left element, may be null + * @param right the right element, may be null + * @return a pair formed from the two parameters, not null + */ + public static ImmutablePair of(final L left, final R right) { + return new ImmutablePair<>(left, right); + } + + /** + *

Creates an immutable pair from an existing pair.

+ * + *

This factory allows the pair to be created using inference to + * obtain the generic types.

+ * + * @param the left element type + * @param the right element type + * @param pair the existing pair. + * @return a pair formed from the two parameters, not null + * @since 3.10 + */ + public static ImmutablePair of(final Map.Entry pair) { + final L left; + final R right; + if (pair != null) { + left = pair.getKey(); + right = pair.getValue(); + } else { + left = null; + right = null; + } + return new ImmutablePair<>(left, right); + } + + /** + *

Creates 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.

+ * + * @param the left element type + * @param the right element type + * @param right the right element, may be null + * @return a pair formed from the two parameters, not null + * @since 3.11 + */ + public static Pair right(final R right) { + return ImmutablePair.of(null, right); + } + + /** + * Left object + */ + public final L left; + + /** + * Right object + */ + public final R right; + + /** + * Create a new pair instance. + * + * @param left the left value, may be null + * @param right the right value, may be null + */ + public ImmutablePair(final L left, final R right) { + super(); + this.left = left; + this.right = right; + } + + /** + * {@inheritDoc} + */ + @Override + public L getLeft() { + return left; + } + + /** + * {@inheritDoc} + */ + @Override + public R getRight() { + return right; + } + + /** + *

Throws {@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 the left element type + * @param the middle element type + * @param the right element type + * @since 3.2 + */ +public final class ImmutableTriple extends Triple { + + /** + * An empty array. + *

+ * 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. + * + * @param the left element type + * @param the middle element type + * @param the right element type + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10. + */ + @SuppressWarnings("unchecked") + public static ImmutableTriple[] emptyArray() { + return (ImmutableTriple[]) EMPTY_ARRAY; + } + + /** + * Returns an immutable triple of nulls. + * + * @param the left element of this triple. Value is {@code null}. + * @param the middle element of this triple. Value is {@code null}. + * @param the right element of this triple. Value is {@code null}. + * @return an immutable triple of nulls. + * @since 3.6 + */ + public static ImmutableTriple nullTriple() { + return NULL; + } + + /** + *

Obtains 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.

+ * + * @param the left element type + * @param the middle element type + * @param the right element type + * @param left the left element, may be null + * @param middle the middle element, may be null + * @param right the right element, may be null + * @return a triple formed from the three parameters, not null + */ + public static ImmutableTriple of(final L left, final M middle, final R right) { + return new ImmutableTriple<>(left, middle, right); + } + + /** + * Left object + */ + public final L left; + + /** + * Middle object + */ + public final M middle; + + /** + * Right object + */ + public final R right; + + /** + * Create a new triple instance. + * + * @param left the left value, may be null + * @param middle the middle value, may be null + * @param right the right value, may be null + */ + public ImmutableTriple(final L left, final M middle, final R right) { + super(); + this.left = left; + this.middle = middle; + this.right = right; + } + + //----------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public L getLeft() { + return left; + } + + /** + * {@inheritDoc} + */ + @Override + public M getMiddle() { + return middle; + } + + /** + * {@inheritDoc} + */ + @Override + public R getRight() { + return right; + } +} + diff --git a/src/main/java/com/jd/jdbc/common/tuple/MutablePair.java b/src/main/java/com/jd/jdbc/common/tuple/MutablePair.java new file mode 100644 index 0000000..7e4c635 --- /dev/null +++ b/src/main/java/com/jd/jdbc/common/tuple/MutablePair.java @@ -0,0 +1,180 @@ +/* + * 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; + +/** + *

A mutable pair consisting of two {@code Object} elements.

+ * + *

Not #ThreadSafe#

+ * + * @param the left element type + * @param the right element type + * @since 3.0 + */ +public class MutablePair extends Pair { + + /** + * An empty array. + *

+ * 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. + * + * @param the left element type + * @param the right element type + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10. + */ + @SuppressWarnings("unchecked") + public static MutablePair[] emptyArray() { + return (MutablePair[]) EMPTY_ARRAY; + } + + /** + *

Creates 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.

+ * + * @param the left element type + * @param the right element type + * @param left the left element, may be null + * @param right the right element, may be null + * @return a pair formed from the two parameters, not null + */ + public static MutablePair of(final L left, final R right) { + return new MutablePair<>(left, right); + } + + /** + *

Creates a mutable pair from an existing pair.

+ * + *

This factory allows the pair to be created using inference to + * obtain the generic types.

+ * + * @param the left element type + * @param the right element type + * @param pair the existing pair. + * @return a pair formed from the two parameters, not null + */ + public static MutablePair of(final Map.Entry pair) { + final L left; + final R right; + if (pair != null) { + left = pair.getKey(); + right = pair.getValue(); + } else { + left = null; + right = null; + } + return new MutablePair<>(left, right); + } + + /** + * Left object + */ + public L left; + + /** + * Right object + */ + public R right; + + /** + * Create a new pair instance of two nulls. + */ + public MutablePair() { + super(); + } + + /** + * Create a new pair instance. + * + * @param left the left value, may be null + * @param right the right value, may be null + */ + public MutablePair(final L left, final R right) { + super(); + this.left = left; + this.right = right; + } + + //----------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public L getLeft() { + return left; + } + + /** + * {@inheritDoc} + */ + @Override + public R getRight() { + return right; + } + + /** + * Sets the left element of the pair. + * + * @param left the new value of the left element, may be null + */ + public void setLeft(final L left) { + this.left = left; + } + + /** + * Sets the right element of the pair. + * + * @param right the new value of the right element, may be null + */ + public void setRight(final R right) { + this.right = right; + } + + /** + * Sets the {@code Map.Entry} value. + * This sets the right element of the pair. + * + * @param value the right value to set, not null + * @return the old value for the right element + */ + @Override + public R setValue(final R value) { + final R result = getRight(); + setRight(value); + return result; + } + +} diff --git a/src/main/java/com/jd/jdbc/common/tuple/MutableTriple.java b/src/main/java/com/jd/jdbc/common/tuple/MutableTriple.java new file mode 100644 index 0000000..a81fc79 --- /dev/null +++ b/src/main/java/com/jd/jdbc/common/tuple/MutableTriple.java @@ -0,0 +1,168 @@ +/* + * 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; + +/** + *

A mutable triple consisting of three {@code Object} elements.

+ * + *

Not #ThreadSafe#

+ * + * @param the left element type + * @param the middle element type + * @param the right element type + * @since 3.2 + */ +public class MutableTriple extends Triple { + + /** + * The empty array singleton. + *

+ * 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. + * + * @param the left element type + * @param the middle element type + * @param the right element type + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10. + */ + @SuppressWarnings("unchecked") + public static MutableTriple[] emptyArray() { + return (MutableTriple[]) EMPTY_ARRAY; + } + + /** + *

Obtains 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.

+ * + * @param the left element type + * @param the middle element type + * @param the right element type + * @param left the left element, may be null + * @param middle the middle element, may be null + * @param right the right element, may be null + * @return a triple formed from the three parameters, not null + */ + public static MutableTriple of(final L left, final M middle, final R right) { + return new MutableTriple<>(left, middle, right); + } + + /** + * Left object + */ + public L left; + + /** + * Middle object + */ + public M middle; + + /** + * Right object + */ + public R right; + + /** + * Create a new triple instance of three nulls. + */ + public MutableTriple() { + super(); + } + + /** + * Create a new triple instance. + * + * @param left the left value, may be null + * @param middle the middle value, may be null + * @param right the right value, may be null + */ + public MutableTriple(final L left, final M middle, final R right) { + super(); + this.left = left; + this.middle = middle; + this.right = right; + } + + //----------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public L getLeft() { + return left; + } + + /** + * {@inheritDoc} + */ + @Override + public M getMiddle() { + return middle; + } + + /** + * {@inheritDoc} + */ + @Override + public R getRight() { + return right; + } + + /** + * Sets the left element of the triple. + * + * @param left the new value of the left element, may be null + */ + public void setLeft(final L left) { + this.left = left; + } + + /** + * Sets the middle element of the triple. + * + * @param middle the new value of the middle element, may be null + */ + public void setMiddle(final M middle) { + this.middle = middle; + } + + /** + * Sets the right element of the triple. + * + * @param right the new value of the right element, may be null + */ + public void setRight(final R right) { + this.right = right; + } +} + diff --git a/src/main/java/com/jd/jdbc/common/tuple/Pair.java b/src/main/java/com/jd/jdbc/common/tuple/Pair.java new file mode 100644 index 0000000..384257e --- /dev/null +++ b/src/main/java/com/jd/jdbc/common/tuple/Pair.java @@ -0,0 +1,224 @@ +/* + * 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.Map; +import java.util.Objects; + +/** + *

A 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 the left element type + * @param the right element type + * @since 3.0 + */ +public abstract class Pair implements Map.Entry, Serializable { + + private static final class PairAdapter extends Pair { + + private static final long serialVersionUID = 1L; + + @Override + public L getLeft() { + return null; + } + + @Override + public R getRight() { + return null; + } + + @Override + public R setValue(final R value) { + return null; + } + + } + + /** + * Serialization version + */ + private static final long serialVersionUID = 4954918890077093841L; + + /** + * An empty array. + *

+ * 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. + * + * @param the left element type + * @param the right element type + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10. + */ + @SuppressWarnings("unchecked") + public static Pair[] emptyArray() { + return (Pair[]) EMPTY_ARRAY; + } + + /** + *

Creates 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.

+ * + * @param the left element type + * @param the right element type + * @param left the left element, may be null + * @param right the right element, may be null + * @return a pair formed from the two parameters, not null + */ + public static Pair of(final L left, final R right) { + return ImmutablePair.of(left, right); + } + + /** + *

Creates an immutable pair from an existing pair.

+ * + *

This factory allows the pair to be created using inference to + * obtain the generic types.

+ * + * @param the left element type + * @param the right element type + * @param pair the existing pair. + * @return a pair formed from the two parameters, not null + * @since 3.10 + */ + public static Pair of(final Map.Entry pair) { + return ImmutablePair.of(pair); + } + + /** + *

Compares 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 the left element type + * @param the middle element type + * @param the right element type + * @since 3.2 + */ +public abstract class Triple implements Serializable { + + private static final class TripleAdapter extends Triple { + + private static final long serialVersionUID = 1L; + + @Override + public L getLeft() { + return null; + } + + @Override + public M getMiddle() { + return null; + } + + @Override + public R getRight() { + return null; + } + + } + + /** + * Serialization version + */ + private static final long serialVersionUID = 1L; + + /** + * An empty array. + *

+ * 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. + * + * @param the left element type + * @param the middle element type + * @param the right element type + * @return the empty array singleton that can be assigned without compiler warning. + * @since 3.10. + */ + @SuppressWarnings("unchecked") + public static Triple[] emptyArray() { + return (Triple[]) EMPTY_ARRAY; + } + + /** + *

Obtains 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.

+ * + * @param the left element type + * @param the middle element type + * @param the right element type + * @param left the left element, may be null + * @param middle the middle element, may be null + * @param right the right element, may be null + * @return a triple formed from the three parameters, not null + */ + public static Triple of(final L left, final M middle, final R right) { + return new ImmutableTriple<>(left, middle, right); + } + + /** + *

Compares 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()); + } + +} +