class ScoredConfusionSet {

  private List<ConfusionString> confusionWords;
  private final float score;

  /**
   * @param score the score that a string must get at least to be considered a correction, must be &gt; 0
   */
  public ScoredConfusionSet(float score, List<ConfusionString> words) {
    if (score <= 0) {
      throw new IllegalArgumentException("factor must be > 0: " + score);
    }
    this.score = score;
    confusionWords = words;
  }

  /* Alternative must be at least this much more probable to be considered correct. */
  public float getScore() {
    return score;
  }

  public List<String> getConfusionTokens() {
    return confusionWords.stream().map(ConfusionString::getString).collect(Collectors.toList());
  }

  public List<Optional<String>> getTokenDescriptions() {
    return confusionWords.stream()
            .map(ConfusionString::getDescription)
            .map(Optional::ofNullable)
            .collect(Collectors.toList());
  }

  @Override
  public String toString() {
    return confusionWords.toString();
  }

  @Override
  public boolean equals(Object o) {<FILL_FUNCTION_BODY>}

  @Override
  public int hashCode() {
    return Objects.hash(confusionWords, score);
  }

}

    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    org.languagetool.rules.ScoredConfusionSet other = (org.languagetool.rules.ScoredConfusionSet) o;
    return Objects.equals(confusionWords, other.confusionWords) && Objects.equals(score, other.score);
  
<no_super_class>