My Hashtable in Java would benefit from a value having a tuple structure. What data structure can I use in Java to do that?
Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ...
My Hashtable in Java would benefit from a value having a tuple structure. What data structure can I use in Java to do that?
Hashtable<Long, Tuple<Set<Long>,Set<Long>>> table = ...
I don't think there is a general purpose tuple class in Java but a custom one might be as easy as the following:
public class Tuple<X, Y> {
public final X x;
public final Y y;
public Tuple(X x, Y y) {
this.x = x;
this.y = y;
}
}
Of course, there are some important implications of how to design this class further regarding equality, immutability, etc., especially if you plan to use instances as keys for hashing.
x
and y
as public final
and get rid of those getters. –
Lintwhite equals()
and hashCode()
must be overriden. –
Dyeing public record Pair<X, Y>(X x, Y y) {}
. You get tuple semantics for equality checks and hash code calculations out of the box. –
Galleass javatuples is a dedicated project for tuples in Java.
Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)
Unit
, which has different semantics from the Unit
in Kotlin, Scala etc. –
Steam Apache Commons provided some common java utilities including a Pair. It implements Map.Entry
, Comparable
and Serializable
.
Pair
is exactly what he need. –
Nakesha Tuple<T1,T2>
, Tuple<T1,T2,T3>
, etc. The names are not good in Java, which does not allow such distinction, but that doesn't mean Tuple
is not a good name for classes with hardcoded number of types in languages with "real" generic types. –
Pegram Pair
class in Apache Commons is in the org.apache.commons.lang3.tuple
package, just to find out that a pair is the only type of tuple implemented :( –
Orlon If you are looking for a built-in Java two-element tuple, try AbstractMap.SimpleEntry
.
class Tuple extends AbstractMap.SimpleEntry {}
Then you can refer to the class as Tuple
. –
Jelsma AbstractMap.SimpleEntry
? Create your own type with exactly the semantics you need and your callers will expect. –
Cupcake Tuple
then key
and value
maybe good names and the result might already be perfectly what you need. Of course if this is not the case then of course you are right that a custom implementation is a good idea. –
Jelsma getKey
and getValue
which is not really what you mean when you want a simple two element tuple. –
Wheat As an extension to @maerics nice answer, I've added a few useful methods:
public class Tuple<X, Y> {
public final X x;
public final Y y;
public Tuple(X x, Y y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "(" + x + "," + y + ")";
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof Tuple)){
return false;
}
Tuple<X,Y> other_ = (Tuple<X,Y>) other;
// this may cause NPE if nulls are valid values for x or y. The logic may be improved to handle nulls properly, if needed.
return other_.x.equals(this.x) && other_.y.equals(this.y);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((x == null) ? 0 : x.hashCode());
result = prime * result + ((y == null) ? 0 : y.hashCode());
return result;
}
}
Hashtable
(as requested in the question) since the hasCode()
and equals()
of 2 same couples will differ. –
Dyeing equals()
to return Objects.equals(other_.x == this.x) && Objects.equals(other_.y == this.y)
in Java 7 or an equalily comparson with null check. –
Dyeing Objects.equals(other.x, this.x)
, etc? The method accepts two Object references as parameters, not a boolean value. –
Swetiana Another 2 cents : Starting with Java 7, there is now a class for this in standard Lib : javafx.util.Pair.
And Yes, It is standard Java, now that JavaFx is included in the JDK :)
With lombok it's easy to declare a Pair
class:
@Data(staticConstructor = "of")
public class Pair<A, B> {
private final A left;
private final B right;
}
This will generates getters, static constructor named "of", equals()
, hashcode()
and toString()
.
see @Data
documentation for more information
final
here ensure we get a static constructor with "left" and "right" arguments and no setters –
Aubigny final
, but the class isn't. You need the class to be extendable to do things like proxying. Also, final
s carry only so much weight when reflection is considered (see Class.setAccessible(boolean)
). –
Grangerize Here's this exact same question elsewhere, that includes a more robust equals
, hash
that maerics alludes to:
That discussion goes on to mirror the maerics vs ColinD approaches of "should I re-use a class Tuple with an unspecific name, or make a new class with specific names each time I encounter this situation". Years ago I was in the latter camp; I've evolved into supporting the former.
double[]
and compute the minimum, maximum, average, and standard deviation, having it store the values into a passed-in double[4]
may be less elegant than having it use a type with named fields, but someone who wants to know what's going on will only have to read the documentation for the method, instead of having to also read the documentation for a custom return type (or examine the code of it directly). Being able to return anonymous value types would be nicer, but Java doesn't support anything like that. Actually, if I had control over Java... –
Pegram Thread
named tempLong1
, tempLong2
, tempObject1
, TempObject2
, etc. to minimize the number of temporary objects that need to be created purely for the purpose of being able to return more than one thing from a method. Icky, but there is no other clean solution. –
Pegram This object provides a sensible implementation of equals(), returning true if equals() is true on each of the contained objects.
Though the article is pretty old now, and though I understand that I'm not really very helpful, I think the proposal described in Adding tuples to Java: a study in lightweight data structures, would have been nice in mainstream Java.
You can do things like:
int a;
char b;
float c;
[a,b,c] = [3,'a',2.33];
or
[int,int,char] x = [1,2,'a'];
or
public [int,boolean] Find(int i)
{
int idx = FindInArray(A,i);
return [idx,idx>=0];
}
[idx, found] = Find(7);
Here tuples are:
This approach increases
Create a class that describes the concept you're actually modeling and use that. It can just store two Set<Long>
and provide accessors for them, but it should be named to indicate what exactly each of those sets is and why they're grouped together.
Pair
or Tuple
type. –
Cupcake To supplement @maerics's answer, here is the Comparable
tuple:
import java.util.*;
/**
* A tuple of two classes that implement Comparable
*/
public class ComparableTuple<X extends Comparable<? super X>, Y extends Comparable<? super Y>>
extends Tuple<X, Y>
implements Comparable<ComparableTuple<X, Y>>
{
public ComparableTuple(X x, Y y) {
super(x, y);
}
/**
* Implements lexicographic order
*/
public int compareTo(ComparableTuple<X, Y> other) {
int d = this.x.compareTo(other.x);
if (d == 0)
return this.y.compareTo(other.y);
return d;
}
}
I will start from a general point of view about tuples in Java and finish with an implication for your concrete problem.
1) The way tuples are used in non-generic languages is avoided in Java because they are not type-safe (e.g. in Python: tuple = (4, 7.9, 'python')
). If you still want to use something like a general purpose tuple (which is not recommended), you should use Object[]
or List<Object>
and cast the elements after a check with instanceof
to assure type-safety.
Usually, tuples in a certain setting are always used the same way with containing the same structure. In Java, you have to define this structure explicitly in a class
to provide well-defined, type-safe values and methods. This seems annoying and unnecessairy at first but prevents errors already at compile-time.
2) If you need a tuple containing the same (super-)classes Foo
, use Foo[]
, List<Foo>
, or List<? extends Foo>
(or the lists's immutable counterparts). Since a tuple is not of a defined length, this solution is equivalent.
3) In your case, you seem to need a Pair
(i.e. a tuple of well-defined length 2). This renders maerics's answer or one of the supplementary answers the most efficient since you can reuse the code in the future.
© 2022 - 2024 — McMap. All rights reserved.
Record
type? – Aesthesia