package de.uni_hamburg.fs;

/**
 * A serializable class representing an immutable name with string interning support.
 * Uses string interning for memory efficiency and fast equality comparisons,
 * maintaining this property through serialization operations.
 *
 * @see java.io.Serializable
 */

public class Name implements java.io.Serializable {
    /**
     * A constant representing an empty name.
     * This shared instance should be used instead of creating new empty names
     * for better memory efficiency and consistency.
     */
    public static final Name EMPTY = new Name("");
    /**
     * The internal string representation of this name.
     * Contains an interned string value for memory efficiency
     * and reference-based equality comparisons.
     */
    public String _name;

    /**
     * Creates a new Name instance with the given string value.
     * The provided string is automatically interned for efficient
     * storage and comparison operations.
     *
     * @param name the string value to be used as the name
     */
    public Name(String name) {
        this._name = name.intern();
    }

    @Override
    public String toString() {
        return _name;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Name) {
            return _name == ((Name) obj)._name;
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return _name.hashCode();
    }

    /**
     * Custom deserialization method to ensure string interning is maintained.
     * This method is called during deserialization to properly restore the
     * interned state of the name string.
     *
     * @param in the object input stream from which to read data
     * @throws java.io.IOException if an I/O error occurs during deserialization
     * @throws ClassNotFoundException if the class of a serialized object cannot be found
     */
    private void readObject(java.io.ObjectInputStream in)
        throws java.io.IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        _name = _name.intern();
    }
}