package com.github.liblevenshtein.collection.dictionary; import java.io.Serializable; import it.unimi.dsi.fastutil.chars.Char2ObjectMap; import it.unimi.dsi.fastutil.chars.Char2ObjectRBTreeMap; import it.unimi.dsi.fastutil.chars.CharIterator; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NonNull; /** * Non-final element of a DAWG structure (Directed Acyclic Word Graph). * Currently, this is tightly-coupled with character-node types. * @author Dylon Edwards * @since 2.1.0 */ @Data @AllArgsConstructor public class DawgNode implements Serializable { private static final long serialVersionUID = 1L; /** * Outgoing edges of this node. */ @NonNull protected final Char2ObjectMap<DawgNode> edges; /** * Constructs a non-final {@link DawgNode}. */ public DawgNode() { this(new Char2ObjectRBTreeMap<>()); } /** * Specifies whether this node represents the last character of some term. * @return Whether this node represents the last character of some term. */ public boolean isFinal() { return false; } /** * Returns the labels of the outgoing edges of this node. * @return Labels of the outgoing edges of this node. */ public CharIterator labels() { return edges.keySet().iterator(); } /** * Accepts a label and returns the outgoing transition corresponding to it. * @param label Identifier of the outgoing transition to return * @return Outgoing transition corresponding to the label */ public DawgNode transition(final char label) { return edges.get(label); } /** * Adds an edge to the outgoing edges of this DAWG node. * @param label Identifier of the edge * @param target Neighbor receiving the directed edge * @return A DAWG node having the new edge */ public DawgNode addEdge(final char label, final DawgNode target) { edges.put(label, target); return this; } /** * Removes all outoing-edges. */ public void clear() { edges.clear(); } /** * {@inheritDoc} */ @Override public boolean equals(final Object object) { if (null == object) { return false; } if (this == object) { return true; } if (!(object instanceof DawgNode)) { return false; } final DawgNode other = (DawgNode) object; return new EqualsBuilder() .append(edges, other.edges) .append(isFinal(), other.isFinal()) .isEquals(); } /** * {@inheritDoc} */ @Override public int hashCode() { return new HashCodeBuilder(419, 181) .append(edges) .append(isFinal()) .toHashCode(); } /** * {@inheritDoc} */ @Override public String toString() { return new ToStringBuilder(this) .append("edges", edges) .append("isFinal", isFinal()) .toString(); } }