I want to store two primitive values (and I'm including String as a primitive here) inside a field. For example, I may want to store a String and an int as below:
("hello", 42)
So if the type I'm looking for is X, I'd like to be able to declare a field
private X myX = new X("hello", 42);
or some other incantation that gives me the same result.
I'm trying to figure out what type that field has to be. It has to accept any Java primitive type and String so it could be a String + int or String + float... actually any combination of primitive (+ String) types. Essentially, to borrow a concept from functional languages, I just want a tuple that's restricted to primitives. But Java doesn't have that.
Since they are primitives, generics don't work very well. And I'm not sure how I feel about boxing/unboxing.
What is the best data type/structure I can use in Java to do it?
Don't think that there is a way to do it with built-in Java libraries. However one could write Tuple class identical to Tuple2 class in Scala language like this:
public class Tuple<K, V> {
private K first;
private V second;
// create tuple only with static method "of"
private Tuple(K first, V second) {
this.first = first;
this.second = second;
}
public static <K, V> Tuple<K, V> of(K a, V b) {
return new Tuple<K, V>(a, b);
}
public Tuple<V, K> swap() {
return new Tuple<V, K>(second, first);
}
public K getFirst() {
return this.first;
}
public V getSecond() {
return this.second;
}
#Override
public String toString() {
return "(" + first.toString() + "," + second.toString() + ")";
}
public static void main(String[] args) {
Tuple myTuple = Tuple.of("hello", 2);
System.out.println("toString: "+myTuple);
System.out.println("First: "+myTuple.getFirst());
System.out.println("Swap: "+ myTuple.swap());
}
}
Output:
toString: (hello,2)
First: hello
Swap: (2,hello)
If you really want to store the values as one primitive type, you have to 'encode' them.
For example:
String field = "hello;42";
String[] values = field.split(";");
int intValue = Integer.parseInt(values[1]);
Since you're working with only primitives (and String) it seems that you'd like to avoid auto-boxing and unboxing if possible. That means you can't use generics. (Primitive types can't be used as type arguments.) It also seems as though you'd like to avoid unnecessary promotion (e.g. if you stored floats as doubles you'd preserve the original value, but lose the fact that it's actually a float).
A rather elaborate solution would be to create a set of PrimitivePair classes, one for each combination of primitive types that you want to store, along with a factory class for constructing them easily. For example, you might have the following three classes to store various pairs of primitives:
package primitivepair;
public class PrimitivePairStringInt
{
final String s;
final int i;
PrimitivePairStringInt(final String s, final int i)
{
this.s = s;
this.i = i;
}
public String getFirstValue()
{
return s;
}
public int getSecondValue()
{
return i;
}
}
package primitivepair;
public class PrimitivePairFloatDouble
{
final float f;
final double d;
PrimitivePairFloatDouble(final float f, final double d)
{
this.f = f;
this.d = d;
}
public float getFirstValue()
{
return f;
}
public double getSecondValue()
{
return d;
}
}
package primitivepair;
public class PrimitivePairCharByte
{
final char c;
final byte b;
PrimitivePairCharByte(final char c, final byte b)
{
this.c = c;
this.b = b;
}
public char getFirstValue()
{
return c;
}
public byte getSecondValue()
{
return b;
}
}
They would be created by the following factory class:
package primitivepair;
public class PrimitivePairFactory
{
public static PrimitivePairCharByte createPrimitivePair(final char c, final byte b)
{
return new PrimitivePairCharByte(c, b);
}
public static PrimitivePairFloatDouble createPrimitivePair(final float f, final double d)
{
return new PrimitivePairFloatDouble(f, d);
}
public static PrimitivePairStringInt createPrimitivePair(final String s, final int i)
{
return new PrimitivePairStringInt(s, i);
}
}
You can of course add more classes and factory methods for other combinations.
I wanted to make an abstract PrimitivePair class that would have the creation methods and method declarations for the getFirstValue() and getSecondValue() methods, but that would have required that return type covariance works for primitives, and I don't believe it does.
Java does not have a built-in Tuple type.
You might use the standard Map.Entry<K,V> but I would personally suggest Apache Commons Lang3's Tuple type if possible.
This is more of a logical question than code specific, I have some twenty functions, each function calculates two values of my interest. However I can only return one value from a function. Now the other option I have is to make a class and implement setter and getter with global variables. I want to know if this is a feasible and recommended way? Or there is a better way to do this?
Don't use global variables! Use some class that has your data as private fileds, and provide getters for it. Like in
class Pair<A,B> {
final A one;
final B two;
public Pair(A fst, B snd) { one = fst; two = snd; }
public A getFst() { return one; }
public B getSnd() { return two; }
}
Then you can elsewhere say something like:
return new Pair(42, "a result");
Return a Collection from your function containing your values of interest.
Depends on the problem. But 2 solutions are :
Make new class which instances will be returned by all this functions. This class would have 2 attributes for each needed answer.
Return array or Collection with this 2 answers.
You have to return a List or a array.
But if return types are different you can create custom class and use it as return type.
Example
public class Result {
private String name;
private int age;
// getters and setters;
}
Now you can have some thing like following
public static Result getInfo(){
Result result=new Result();
result.setName("name");
result.setAge(10);
return result;//now you can have String and int values return from the method
}
There are many ways: collections, arrays ...
In my opinion the only way is to define a class with these values.
you do not need getter and setter methods if you don't need to regulate the visibility of the contents
class MyReturnValue {
public int a;
public int b;
}
in your code:
...
MyReturnValue result=new MyReturnValue();
result.a=5;
result.b=6;
return result;
It is better to make a class and implement setter and getter with global variables rather than to Return Collection further it depends on your use.
You can do this
long[] function() {
long[] ret = { a, b };
return ret;
}
or
long[] a = { 0 }, b = { 0 };
void function(long[] a, long[] b) {
a[0] = ...
b[0] = ...
or add properties to an object.
private long a,b;
void function() {
a = ...
b = ...
}
in the last case you can value.
class Results {
public final long a;
public final Date b; // note: Date is not immutable.
// add constructor
}
public Results function() {
long a = ...
Date b = ...
return new Results(a, b);
}
I think making a Record class is the most suitable.
public class Record {
public final int a;
public final int b;
public Record(final int a, final int b) {
this.a = a;
this.b = b;
}
}
Then your functions can return type Record, and you can access it with let's say record.a and record.b.
This is also one of the few cases where public variables and no getters and setters can be justified.
UPDATE: Implemented a proposed change, now everything is final, which means that Record cannot be modified when you get it back, which seems to be in line with expectations. You only want the results and use those.
What about adopting varargs with generic helper function for getting around of number of returning variable limitation: In this solution, we won't have to declare a new class every time when number of returning variable changes.
class Results
{
private final Object[] returnedObj;
public Results(Object... returnedObj)
{
this.returnedObj = returnedObj;
}
public <E> E getResult(int index)
{
return (E)returnedObj[index];
}
}
Test case:
public static Results Test()
{
return new Results(12, "ABCD EFG", 12.45);
// or return larger number of value
}
//// And then returning the result
Results result = Test();
String x = result.<String>getResult(1);
System.out.println(x); // prints "ABCD EFG"
You could even return the values separated by a special character say a "~" if you are sure that the "~" won't appear in your results.
Is there a good reason why there is no Pair<L,R> in Java? What would be the equivalent of this C++ construct? I would rather avoid reimplementing my own.
It seems that 1.6 is providing something similar (AbstractMap.SimpleEntry<K,V>), but this looks quite convoluted.
In a thread on comp.lang.java.help, Hunter Gratzner gives some arguments against the presence of a Pair construct in Java. The main argument is that a class Pair doesn't convey any semantics about the relationship between the two values (how do you know what "first" and "second" mean ?).
A better practice is to write a very simple class, like the one Mike proposed, for each application you would have made of the Pair class. Map.Entry is an example of a pair that carry its meaning in its name.
To sum up, in my opinion it is better to have a class Position(x,y), a class Range(begin,end) and a class Entry(key,value) rather than a generic Pair(first,second) that doesn't tell me anything about what it's supposed to do.
This is Java. You have to make your own tailored Pair class with descriptive class and field names, and not to mind that you will reinvent the wheel by writing hashCode()/equals() or implementing Comparable again and again.
HashMap compatible Pair class:
public class Pair<A, B> {
private A first;
private B second;
public Pair(A first, B second) {
super();
this.first = first;
this.second = second;
}
public int hashCode() {
int hashFirst = first != null ? first.hashCode() : 0;
int hashSecond = second != null ? second.hashCode() : 0;
return (hashFirst + hashSecond) * hashSecond + hashFirst;
}
public boolean equals(Object other) {
if (other instanceof Pair) {
Pair otherPair = (Pair) other;
return
(( this.first == otherPair.first ||
( this.first != null && otherPair.first != null &&
this.first.equals(otherPair.first))) &&
( this.second == otherPair.second ||
( this.second != null && otherPair.second != null &&
this.second.equals(otherPair.second))) );
}
return false;
}
public String toString()
{
return "(" + first + ", " + second + ")";
}
public A getFirst() {
return first;
}
public void setFirst(A first) {
this.first = first;
}
public B getSecond() {
return second;
}
public void setSecond(B second) {
this.second = second;
}
}
The shortest pair that I could come up with is the following, using Lombok:
#Data
#AllArgsConstructor(staticName = "of")
public class Pair<F, S> {
private F first;
private S second;
}
It has all the benefits of the answer from #arturh (except the comparability), it has hashCode, equals, toString and a static “constructor”.
Apache Commons Lang 3.0+ has a few Pair classes:
http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
Another way to implement Pair with.
Public immutable fields, i.e. simple data structure.
Comparable.
Simple hash and equals.
Simple factory so you don't have to provide the types. e.g. Pair.of("hello", 1);
public class Pair<FIRST, SECOND> implements Comparable<Pair<FIRST, SECOND>> {
public final FIRST first;
public final SECOND second;
private Pair(FIRST first, SECOND second) {
this.first = first;
this.second = second;
}
public static <FIRST, SECOND> Pair<FIRST, SECOND> of(FIRST first,
SECOND second) {
return new Pair<FIRST, SECOND>(first, second);
}
#Override
public int compareTo(Pair<FIRST, SECOND> o) {
int cmp = compare(first, o.first);
return cmp == 0 ? compare(second, o.second) : cmp;
}
// todo move this to a helper class.
private static int compare(Object o1, Object o2) {
return o1 == null ? o2 == null ? 0 : -1 : o2 == null ? +1
: ((Comparable) o1).compareTo(o2);
}
#Override
public int hashCode() {
return 31 * hashcode(first) + hashcode(second);
}
// todo move this to a helper class.
private static int hashcode(Object o) {
return o == null ? 0 : o.hashCode();
}
#Override
public boolean equals(Object obj) {
if (!(obj instanceof Pair))
return false;
if (this == obj)
return true;
return equal(first, ((Pair) obj).first)
&& equal(second, ((Pair) obj).second);
}
// todo move this to a helper class.
private boolean equal(Object o1, Object o2) {
return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2));
}
#Override
public String toString() {
return "(" + first + ", " + second + ')';
}
}
How about http://www.javatuples.org/index.html I have found it very useful.
The javatuples offers you tuple classes from one to ten elements:
Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)
Quartet<A,B,C,D> (4 elements)
Quintet<A,B,C,D,E> (5 elements)
Sextet<A,B,C,D,E,F> (6 elements)
Septet<A,B,C,D,E,F,G> (7 elements)
Octet<A,B,C,D,E,F,G,H> (8 elements)
Ennead<A,B,C,D,E,F,G,H,I> (9 elements)
Decade<A,B,C,D,E,F,G,H,I,J> (10 elements)
android provides Pairclass (http://developer.android.com/reference/android/util/Pair.html) , here the implementation:
public class Pair<F, S> {
public final F first;
public final S second;
public Pair(F first, S second) {
this.first = first;
this.second = second;
}
#Override
public boolean equals(Object o) {
if (!(o instanceof Pair)) {
return false;
}
Pair<?, ?> p = (Pair<?, ?>) o;
return Objects.equal(p.first, first) && Objects.equal(p.second, second);
}
#Override
public int hashCode() {
return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
}
public static <A, B> Pair <A, B> create(A a, B b) {
return new Pair<A, B>(a, b);
}
}
It depends on what you want to use it for. The typical reason to do so is to iterate over maps, for which you simply do this (Java 5+):
Map<String, Object> map = ... ; // just an example
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.printf("%s -> %s\n", entry.getKey(), entry.getValue());
}
The biggest problem is probably that one can't ensure immutability on A and B (see How to ensure that type parameters are immutable) so hashCode() may give inconsistent results for the same Pair after is inserted in a collection for instance (this would give undefined behavior, see Defining equals in terms of mutable fields). For a particular (non generic) Pair class the programmer may ensure immutability by carefully choosing A and B to be immutable.
Anyway, clearing generic's warnings from #PeterLawrey's answer (java 1.7) :
public class Pair<A extends Comparable<? super A>,
B extends Comparable<? super B>>
implements Comparable<Pair<A, B>> {
public final A first;
public final B second;
private Pair(A first, B second) {
this.first = first;
this.second = second;
}
public static <A extends Comparable<? super A>,
B extends Comparable<? super B>>
Pair<A, B> of(A first, B second) {
return new Pair<A, B>(first, second);
}
#Override
public int compareTo(Pair<A, B> o) {
int cmp = o == null ? 1 : (this.first).compareTo(o.first);
return cmp == 0 ? (this.second).compareTo(o.second) : cmp;
}
#Override
public int hashCode() {
return 31 * hashcode(first) + hashcode(second);
}
// TODO : move this to a helper class.
private static int hashcode(Object o) {
return o == null ? 0 : o.hashCode();
}
#Override
public boolean equals(Object obj) {
if (!(obj instanceof Pair))
return false;
if (this == obj)
return true;
return equal(first, ((Pair<?, ?>) obj).first)
&& equal(second, ((Pair<?, ?>) obj).second);
}
// TODO : move this to a helper class.
private boolean equal(Object o1, Object o2) {
return o1 == o2 || (o1 != null && o1.equals(o2));
}
#Override
public String toString() {
return "(" + first + ", " + second + ')';
}
}
Additions/corrections much welcome :) In particular I am not quite sure about my use of Pair<?, ?>.
For more info on why this syntax see Ensure that objects implement Comparable and for a detailed explanation How to implement a generic max(Comparable a, Comparable b) function in Java?
Good News JavaFX has a key value Pair.
Just add JavaFX as a dependency and import javafx.util.Pair, and use simply as in C++.
Pair <Key, Value>
e.g.
Pair <Integer, Integer> pr = new Pair<Integer, Integer>()
pr.get(key);// will return corresponding value
In my opinion, there is no Pair in Java because, if you want to add extra functionality directly on the pair (e.g. Comparable), you must bound the types. In C++, we just don't care, and if types composing a pair do not have operator <, the pair::operator < will not compile as well.
An example of Comparable with no bounding:
public class Pair<F, S> implements Comparable<Pair<? extends F, ? extends S>> {
public final F first;
public final S second;
/* ... */
public int compareTo(Pair<? extends F, ? extends S> that) {
int cf = compare(first, that.first);
return cf == 0 ? compare(second, that.second) : cf;
}
//Why null is decided to be less than everything?
private static int compare(Object l, Object r) {
if (l == null) {
return r == null ? 0 : -1;
} else {
return r == null ? 1 : ((Comparable) (l)).compareTo(r);
}
}
}
/* ... */
Pair<Thread, HashMap<String, Integer>> a = /* ... */;
Pair<Thread, HashMap<String, Integer>> b = /* ... */;
//Runtime error here instead of compile error!
System.out.println(a.compareTo(b));
An example of Comparable with compile-time check for whether type arguments are comparable:
public class Pair<
F extends Comparable<? super F>,
S extends Comparable<? super S>
> implements Comparable<Pair<? extends F, ? extends S>> {
public final F first;
public final S second;
/* ... */
public int compareTo(Pair<? extends F, ? extends S> that) {
int cf = compare(first, that.first);
return cf == 0 ? compare(second, that.second) : cf;
}
//Why null is decided to be less than everything?
private static <
T extends Comparable<? super T>
> int compare(T l, T r) {
if (l == null) {
return r == null ? 0 : -1;
} else {
return r == null ? 1 : l.compareTo(r);
}
}
}
/* ... */
//Will not compile because Thread is not Comparable<? super Thread>
Pair<Thread, HashMap<String, Integer>> a = /* ... */;
Pair<Thread, HashMap<String, Integer>> b = /* ... */;
System.out.println(a.compareTo(b));
This is good, but this time you may not use non-comparable types as type arguments in Pair.
One may use lots of Comparators for Pair in some utility class, but C++ people may not get it. Another way is to write lots of classes in a type hierarchy with different bounds on type arguments, but there are too many possible bounds and their combinations...
Map.Entry interface come pretty close to c++ pair. Look at the concrete implementation, like AbstractMap.SimpleEntry and AbstractMap.SimpleImmutableEntry
First item is getKey() and second is getValue().
According to the nature of Java language, I suppose people do not actually require a Pair, an interface is usually what they need. Here is an example:
interface Pair<L, R> {
public L getL();
public R getR();
}
So, when people want to return two values they can do the following:
... //Calcuate the return value
final Integer v1 = result1;
final String v2 = result2;
return new Pair<Integer, String>(){
Integer getL(){ return v1; }
String getR(){ return v2; }
}
This is a pretty lightweight solution, and it answers the question "What is the semantic of a Pair<L,R>?". The answer is, this is an interface build with two (may be different) types, and it has methods to return each of them. It is up to you to add further semantic to it. For example, if you are using Position and REALLY want to indicate it in you code, you can define PositionX and PositionY that contains Integer, to make up a Pair<PositionX,PositionY>. If JSR 308 is available, you may also use Pair<#PositionX Integer, #PositionY Ingeger> to simplify that.
EDIT:
One thing I should indicate here is that the above definition explicitly relates the type parameter name and the method name. This is an answer to those argues that a Pair is lack of semantic information. Actually, the method getL means "give me the element that correspond to the type of type parameter L", which do means something.
EDIT:
Here is a simple utility class that can make life easier:
class Pairs {
static <L,R> Pair<L,R> makePair(final L l, final R r){
return new Pair<L,R>(){
public L getL() { return l; }
public R getR() { return r; }
};
}
}
usage:
return Pairs.makePair(new Integer(100), "123");
JavaFX (which comes bundled with Java 8) has the Pair< A,B > class
As many others have already stated, it really depends on the use case if a Pair class is useful or not.
I think for a private helper function it is totally legitimate to use a Pair class if that makes your code more readable and is not worth the effort of creating yet another value class with all its boiler plate code.
On the other hand, if your abstraction level requires you to clearly document the semantics of the class that contains two objects or values, then you should write a class for it. Usually that's the case if the data is a business object.
As always, it requires skilled judgement.
For your second question I recommend the Pair class from the Apache Commons libraries. Those might be considered as extended standard libraries for Java:
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html
You might also want to have a look at Apache Commons' EqualsBuilder, HashCodeBuilder and ToStringBuilder which simplify writing value classes for your business objects.
You can use javafx utility class, Pair which serves the same purpose as pair <> in c++. https://docs.oracle.com/javafx/2/api/javafx/util/Pair.html
Collections.singletonMap(left, rigth);
another terse lombok implementation
import lombok.Value;
#Value(staticConstructor = "of")
public class Pair<F, S> {
private final F first;
private final S second;
}
Simple way Object [] - can be use as anу dimention tuple
Despite being syntactically similar, Java and C++ have very different paradigms. Writing C++ like Java is bad C++, and writing Java like C++ is bad Java.
With a reflection based IDE like Eclipse, writing the necessarily functionality of a "pair" class is quick and simple. Create class, define two fields, use the various "Generate XX" menu options to fill out the class in a matter of seconds. Maybe you'd have to type a "compareTo" real quick if you wanted the Comparable interface.
With separate declaration / definition options in the language C++ code generators aren't so good, so hand writing little utility classes is more time consuming tedium. Because the pair is a template, you don't have to pay for functions you don't use, and the typedef facility allows assigning meaningful typenames to the code, so the objections about "no semantics" don't really hold up.
Pair would be a good stuff, to be a basic construction unit for a complex generics, for instance, this is from my code:
WeakHashMap<Pair<String, String>, String> map = ...
It is just the same as Haskell's Tuple
For programming languages like Java, the alternate data structure used by most programmers to represent pair like data-structures are two array, and data is accessed via the same index
example: http://www-igm.univ-mlv.fr/~lecroq/string/node8.html#SECTION0080
This isn't ideal as the data should be bound together, but also turn out to be pretty cheap. Also, if your use case demands storing co-ordinates then its better to build your own data structure.
I've something like this in my library
public class Pair<First,Second>{.. }
You can use Google's AutoValue library - https://github.com/google/auto/tree/master/value.
You create a very small abstract class and annotate it with #AutoValue and the annotation processor generates a concrete class for you that has a value semantic.
Here are some libraries that have multiple degrees of tuples for your convenience:
JavaTuples. Tuples from degree 1-10 is all it has.
JavaSlang. Tuples from degree 0-8 and lots of other functional goodies.
jOOλ. Tuples from degree 0-16 and some other functional goodies. (Disclaimer, I work for the maintainer company)
Functional Java. Tuples from degree 0-8 and lots of other functional goodies.
Other libraries have been mentioned to contain at least the Pair tuple.
Specifically, in the context of functional programming which makes use of a lot of structural typing, rather than nominal typing (as advocated in the accepted answer), those libraries and their tuples come in very handy.
Brian Goetz, Paul Sandoz and Stuart Marks explain why during QA session at Devoxx'14.
Having generic pair class in standard library will turn into technical debt once value types introduced.
See also: Does Java SE 8 have Pairs or Tuples?
I noticed all the Pair implementations being strewn around here attribute meaning to the order of the two values. When I think of a pair, I think of a combination of two items in which the order of the two is of no importance. Here's my implementation of an unordered pair, with hashCode and equals overrides to ensure the desired behaviour in collections. Also cloneable.
/**
* The class <code>Pair</code> models a container for two objects wherein the
* object order is of no consequence for equality and hashing. An example of
* using Pair would be as the return type for a method that needs to return two
* related objects. Another good use is as entries in a Set or keys in a Map
* when only the unordered combination of two objects is of interest.<p>
* The term "object" as being a one of a Pair can be loosely interpreted. A
* Pair may have one or two <code>null</code> entries as values. Both values
* may also be the same object.<p>
* Mind that the order of the type parameters T and U is of no importance. A
* Pair<T, U> can still return <code>true</code> for method <code>equals</code>
* called with a Pair<U, T> argument.<p>
* Instances of this class are immutable, but the provided values might not be.
* This means the consistency of equality checks and the hash code is only as
* strong as that of the value types.<p>
*/
public class Pair<T, U> implements Cloneable {
/**
* One of the two values, for the declared type T.
*/
private final T object1;
/**
* One of the two values, for the declared type U.
*/
private final U object2;
private final boolean object1Null;
private final boolean object2Null;
private final boolean dualNull;
/**
* Constructs a new <code>Pair<T, U></code> with T object1 and U object2 as
* its values. The order of the arguments is of no consequence. One or both of
* the values may be <code>null</code> and both values may be the same object.
*
* #param object1 T to serve as one value.
* #param object2 U to serve as the other value.
*/
public Pair(T object1, U object2) {
this.object1 = object1;
this.object2 = object2;
object1Null = object1 == null;
object2Null = object2 == null;
dualNull = object1Null && object2Null;
}
/**
* Gets the value of this Pair provided as the first argument in the constructor.
*
* #return a value of this Pair.
*/
public T getObject1() {
return object1;
}
/**
* Gets the value of this Pair provided as the second argument in the constructor.
*
* #return a value of this Pair.
*/
public U getObject2() {
return object2;
}
/**
* Returns a shallow copy of this Pair. The returned Pair is a new instance
* created with the same values as this Pair. The values themselves are not
* cloned.
*
* #return a clone of this Pair.
*/
#Override
public Pair<T, U> clone() {
return new Pair<T, U>(object1, object2);
}
/**
* Indicates whether some other object is "equal" to this one.
* This Pair is considered equal to the object if and only if
* <ul>
* <li>the Object argument is not null,
* <li>the Object argument has a runtime type Pair or a subclass,
* </ul>
* AND
* <ul>
* <li>the Object argument refers to this pair
* <li>OR this pair's values are both null and the other pair's values are both null
* <li>OR this pair has one null value and the other pair has one null value and
* the remaining non-null values of both pairs are equal
* <li>OR both pairs have no null values and have value tuples <v1, v2> of
* this pair and <o1, o2> of the other pair so that at least one of the
* following statements is true:
* <ul>
* <li>v1 equals o1 and v2 equals o2
* <li>v1 equals o2 and v2 equals o1
* </ul>
* </ul>
* In any other case (such as when this pair has two null parts but the other
* only one) this method returns false.<p>
* The type parameters that were used for the other pair are of no importance.
* A Pair<T, U> can return <code>true</code> for equality testing with
* a Pair<T, V> even if V is neither a super- nor subtype of U, should
* the the value equality checks be positive or the U and V type values
* are both <code>null</code>. Type erasure for parameter types at compile
* time means that type checks are delegated to calls of the <code>equals</code>
* methods on the values themselves.
*
* #param obj the reference object with which to compare.
* #return true if the object is a Pair equal to this one.
*/
#Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(this == obj)
return true;
if(!(obj instanceof Pair<?, ?>))
return false;
final Pair<?, ?> otherPair = (Pair<?, ?>)obj;
if(dualNull)
return otherPair.dualNull;
//After this we're sure at least one part in this is not null
if(otherPair.dualNull)
return false;
//After this we're sure at least one part in obj is not null
if(object1Null) {
if(otherPair.object1Null) //Yes: this and other both have non-null part2
return object2.equals(otherPair.object2);
else if(otherPair.object2Null) //Yes: this has non-null part2, other has non-null part1
return object2.equals(otherPair.object1);
else //Remaining case: other has no non-null parts
return false;
} else if(object2Null) {
if(otherPair.object2Null) //Yes: this and other both have non-null part1
return object1.equals(otherPair.object1);
else if(otherPair.object1Null) //Yes: this has non-null part1, other has non-null part2
return object1.equals(otherPair.object2);
else //Remaining case: other has no non-null parts
return false;
} else {
//Transitive and symmetric requirements of equals will make sure
//checking the following cases are sufficient
if(object1.equals(otherPair.object1))
return object2.equals(otherPair.object2);
else if(object1.equals(otherPair.object2))
return object2.equals(otherPair.object1);
else
return false;
}
}
/**
* Returns a hash code value for the pair. This is calculated as the sum
* of the hash codes for the two values, wherein a value that is <code>null</code>
* contributes 0 to the sum. This implementation adheres to the contract for
* <code>hashCode()</code> as specified for <code>Object()</code>. The returned
* value hash code consistently remain the same for multiple invocations
* during an execution of a Java application, unless at least one of the pair
* values has its hash code changed. That would imply information used for
* equals in the changed value(s) has also changed, which would carry that
* change onto this class' <code>equals</code> implementation.
*
* #return a hash code for this Pair.
*/
#Override
public int hashCode() {
int hashCode = object1Null ? 0 : object1.hashCode();
hashCode += (object2Null ? 0 : object2.hashCode());
return hashCode;
}
}
This implementation has been properly unit tested and the use in a Set and Map has been tried out.
Notice I'm not claiming to release this in the public domain. This is code I've just written for use in an application, so if you're going to use it, please refrain from making a direct copy and mess about with the comments and names a bit. Catch my drift?
If anyone wants a dead-simple and easy to use version I made my available at https://github.com/lfac-pt/Java-Pair. Also, improvements are very much welcome!
com.sun.tools.javac.util.Pair is an simple implementation of a pair.
It can be found in jdk1.7.0_51\lib\tools.jar.
Other than the org.apache.commons.lang3.tuple.Pair, it's not just an interface.
public class Pair<K, V> {
private final K element0;
private final V element1;
public static <K, V> Pair<K, V> createPair(K key, V value) {
return new Pair<K, V>(key, value);
}
public Pair(K element0, V element1) {
this.element0 = element0;
this.element1 = element1;
}
public K getElement0() {
return element0;
}
public V getElement1() {
return element1;
}
}
usage :
Pair<Integer, String> pair = Pair.createPair(1, "test");
pair.getElement0();
pair.getElement1();
Immutable, only a pair !