5

I am trying to implement a HashTable that uses tuples of integers as keys. What i have done so far:

import java.util.*; 

    public class Hash_Table_Demo { 
        public static void main(String[] args) 
        {           
            Hashtable<Integer, String> marks =  
                      new Hashtable<Integer, String>(); 

            marks.put(33,"test");                                 

            System.out.println(marks.get(33));                           
        } 
    }

So far i have achieved this only for integers and not for pairs. How could this be done?

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • 4
    JDK does not include any tuple types. If you want tuple, you will need to write one yourself, use a library, or adapt some other type from JDK or said libraries to do act as a tuple (latter with obvious downside of not expressing proper intention for its key type). – M. Prokhorov Jul 29 '19 at 17:26
  • 1
    Just create a custom `Pair` class and use it as key? Or what is the problem here? And don"t forget to implement `equals()` and `hashcode()` methods – UninformedUser Jul 29 '19 at 17:31
  • 1
    do u want HashMap< , String> ? – MD Ruhul Amin Jul 29 '19 at 17:34
  • 4
    "If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable." – Alexey Romanov Jul 29 '19 at 17:40
  • But what is your question? When you google for "java pair class", you get a ton of suggestions, like: https://stackoverflow.com/questions/5303539/didnt-java-once-have-a-pair-class ... so: what is your question? – GhostCat Jul 29 '19 at 17:52
  • Short version of what Alexey said: Don't ever use `Hashtable`. Use `HashMap` unless you have a specific reason to choose something else. – chrylis -cautiouslyoptimistic- Jul 29 '19 at 18:26

2 Answers2

4

Updated version

To avoid the dependency to JavaFX we can create a simple generic class for the tuple

class Tuple<Value> {
    Value first;
    Value second;

    Tuple(Value first, Value second) {
        this.first = first;
        this.second = second;
    }
}

and also avoid using Hashtable and replace it with for instance. HashMap

Map<Tuple<Integer>, String> map = new HashMap();
map.put(new Tuple(1,2), "Hello");
map.put(new Tuple(3,3), "World");

Old version

Using the existing Pair class you can define your hash table like

Map<Pair<Integer, Integer>, String> marks = new Hashtable<>(); 

And then create a new Pair instance as key

marks.put(new Pair(1,33),"test");                                 

System.out.println(marks.get(new Pair(1,33)));     
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • `existing Pair class`. Is there such class in any standard Java version or you mean he should implement it himself? – Michał Krzywański Jul 29 '19 at 17:42
  • 1
    @michalk I have included a link. – Joakim Danielson Jul 29 '19 at 17:44
  • 2
    Nope, there isn't a really "nice" standard Pair class. Adding the dependency on JavaFX **just** for its Pair class is definitely bad practice. Consider JavaFX to be a liability that you *avoid* if possible. – GhostCat Jul 29 '19 at 17:50
  • @Epitheoritis32 See the link in my comment. You need **some** sort of Pair class, and depending on your exact setup, you simply dont have any of them in your project setup. – GhostCat Jul 29 '19 at 18:00
  • 1
    Don't include `Hashtable` just because a misguided question used it as an example. – chrylis -cautiouslyoptimistic- Jul 29 '19 at 18:25
  • @GhostCat of course there is, `SimpleEntry` and even nicer since java-9, `Map::entry` – Eugene Jul 29 '19 at 18:56
  • @Eugene Naming accounts for "nice", too. A map entry isn't a generic Pair in my book. I get your point, but I think proper naming communicates intent, and the fact that Java missed to have a proper and simple java.util.Pair or so ... just sucks. – GhostCat Jul 29 '19 at 18:59
  • 1
    @NestorMilyaev, thanks for the reminder. I have updated the answer with another solution. – Joakim Danielson Apr 27 '22 at 15:27
1

So long story short, unlike c# that has value tuples since version 7 and you can use

(string name, int age) info = GetStudentInfo("100-000-1000"); 

As you can see, it is a tuple, but elements have strong types and names. You can compare them and most of it works nicely. Python is scripting language and has had this support for ages. In java, if you create a class you need to override its hashcode, tostring, ... and if you want to have multi threading guarantees it is just hard.

Thankfully Google engineers have stumbled upon this multiple times and have solved this issue as best as it is possible, for more info check out Guava horrible ideas: https://github.com/google/guava/wiki/IdeaGraveyard

The solution is to use AutoValue that generates immutable value classes https://github.com/google/auto/tree/master/value

import com.google.auto.value.AutoValue;

@AutoValue
public abstract class Pair {

  public static Pair of(int first, int second) {
    return new AutoValue_Pair(first, second);
  }

  public abstract int first();    
  public abstract int second();
}

To use it you could just type

Hashtable<Pair, String> marks = new Hashtable<Pair, String>();
marks.put(Pair.of(1, 2), "test"); 

The real strengths start to shine when you scale your problem or when you use it with google guava with it. For example:

Map<Pair, String> map = Maps.newLinkedHashMap();
Margus
  • 19,694
  • 14
  • 55
  • 103
  • @GhostCat chill, i am not as fast of a typer and type from memory. I will add code exmple. – Margus Jul 29 '19 at 17:53
  • 1
    Great, but suggest to him to use Map/HashMap, too. Hashtable is seriously not to be used any more. – GhostCat Jul 29 '19 at 18:12
  • @GhostCat Your vanilla solution works as well and for people not planning to have any dependencies it is still a good answer. +1 from me – Margus Jul 29 '19 at 18:20