Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8: How can I use Pair in Hashmap

I am completely new to Java: I am trying to create a HashMap in Java 8: where keys are objects of a class State and values I would like to be tuples of (string,state).
I searched the web for tuples in Java and I found this class called Pair that looked like a binary tuple ( I read here :https://docs.oracle.com/javase/8/javafx/api/javafx/util/Pair.html and here : https://www.techiedelight.com/five-alternatives-pair-class-java/ ) - But I am confused because I also read a post here in stackoverflow saying that there are no pairs in Java8.
I wrote this line:

 HashMap<State, Pair<String, State>> visited = new HashMap<>();

I imported :

import java.util.*;
javafx.util.Pair

I get error messages like:

   javafx could not be resolved  
   Pair cannot be resolved to a type

How can I do what I described in Java 8?

like image 345
tonythestark Avatar asked Jan 24 '23 07:01

tonythestark


2 Answers

tl;dr

record Pair ( String string , State state ) {}

Records

The Answer by Bykov is good if you want a general mutable pair class. Alternatively, you can whip up a specific immutable pairing quite easily in Java 16+ by using the records feature.

A record is a brief way to write a class whose main purpose is to communicate data transparently and immutably. You simply declare the type and name of each member field. The compiler implicitly creates the constructor, getters, equals & hashCode, and toString.

Here is our entire class definition in six words:

record Pair ( String string , State state ) {}

You would of course use more descriptive class and field names.

Instantiate like a conventional class.

Pair p = new Pair( "whatever" , tennessee ) ;

You can declare a record locally, as well as nested or separately.

That record above is equivalent to the conventional code seen below. Modern IDEs such IntelliJ can convert a record to a conventional class, creating this source code.

package work.basil.example;

import java.util.Objects;

public final class Pair {
    private final String string;
    private final State state;

    public Pair ( String string , State state ) {
        this.string = string;
        this.state = state;
    }

    public String string () { return string; }

    public State state () { return state; }

    @Override
    public boolean equals ( Object obj ) {
        if ( obj == this ) return true;
        if ( obj == null || obj.getClass () != this.getClass () ) return false;
        var that = ( Pair ) obj;
        return Objects.equals ( this.string , that.string ) &&
                Objects.equals ( this.state , that.state );
    }

    @Override
    public int hashCode () {
        return Objects.hash ( string , state );
    }

    @Override
    public String toString () {
        return "Pair[" +
                "string=" + string + ", " +
                "state=" + state + ']';
    }

}
like image 187
Basil Bourque Avatar answered Jan 31 '23 18:01

Basil Bourque


I'll give you advice, try to create your own Pair class implementation, it's enough easy:

public class Pair<K, V> {

    private final K first;

    private final V second;

    public Pair(final K first, final V second) {
        this.first = first;
        this.second = second;
    }

    public static <K, V> Pair<K, V> of(K first, V second) {
        return new Pair<>(first, second);
    }

    public K getFirst() {
        return first;
    }

    public V getSecond() {
        return second;
    }
}

In your implementation, you can declare any constructors, static initialize methods, or deserialize's rules. It'll more comfortable than JavaFX Pair.

like image 45
Dmitrii B Avatar answered Jan 31 '23 19:01

Dmitrii B