hashSet 中的重复值

Duplicate values in a hashSet

我正在尝试计算总和为 n 的 1、5、10 和 25 的组合数。鉴于我不想要任何重复(如 1+5 = 6 和 5+1 = 6)。我正在使用 hashSet。我实现了一个名为 ResultSet 的 class,它在解决方案中保存了 1、5、10 和 25 的数字,并且我覆盖了 equals 方法。但是,出于某种原因,我的解决方案 hashSet 不断返回重复值。为什么?

import java.util.HashSet;

public class Solution {

  public static void main(String[] args) {
    int N = 6;
    int combinationsSolution = new Combine(N).getSolution();
    System.out.println("N= " + N + " Number of solutions= " + combinationsSolution);

  }
}

class Combine {

  private int solution;

  private int n;

  private HashSet<ResultSet> cacheUnordered = new HashSet<ResultSet>();

  public Combine(int N) {
    this.n = N;
    this.solution = solve(n);
  }

  public int getSolution() {
    return solution;
  }

  public int solve(int N) {
    solve(N, 0, 0, 0, 0);
    for (ResultSet r:cacheUnordered){
      System.out.println(r.toString());
    }
    return cacheUnordered.size();
  }

  public void solve(int N, int substracted1, int substracted5, int substracted10, int substracted25) {
    if (N == 0) {
      cacheUnordered.add(new ResultSet(substracted1, substracted5, substracted10, substracted25));
    } else if (N > 0) {
      solve(N - 1, substracted1 + 1, substracted5, substracted10, substracted25);
      solve(N - 5, substracted1, substracted5 + 1, substracted10, substracted25);
      solve(N - 10, substracted1, substracted5, substracted10 + 1, substracted25);
      solve(N - 25, substracted1, substracted5, substracted10, substracted25 + 1);
    }
  }
}

class ResultSet {
  private int numberOf1;

  private int numberOf5;

  private int numberOf10;

  private int numberOf25;

  public ResultSet(int num1, int num5, int num10, int num25) {
    numberOf1 = num1;
    numberOf5 = num5;
    numberOf10 = num10;
    numberOf25 = num25;
  }

  @Override
  public String toString(){
    String result;
    result = numberOf1 + " " + numberOf5 + " " + numberOf10 + " " + numberOf25;
    return result;
  }

  @Override
  public boolean equals(Object r2) {
    if (r2 == null) {
      return false;
    }
    if (!(r2 instanceof ResultSet)) {
      return false;
    }
    ResultSet rr = (ResultSet) r2;
    if (rr.numberOf1 == this.numberOf1 && rr.numberOf5 == this.numberOf5
            && rr.numberOf10 == this.numberOf10 && rr.numberOf25 == this.numberOf25) {
      System.out.println("Comparing " + this.toString() + " to " + rr.toString());
      return true;
    } else {
      return false;
    }
  }

  public int getNum1() {
    return numberOf1;
  }

  public int getNum5() {
    return numberOf5;
  }

  public int getNum10() {
    return numberOf10;
  }

  public int getNum25() {
    return numberOf25;
  }
}

对于您的 ResultSet class,您定义了 equals() 方法而不是 hashCode() 方法。 HashSet 需要这两种方法才能正常工作。请看这个 explanation。 (说的是HashMap,其实也适用于HashSet。)

JavaDoc明确指定

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

而你没有遵循它,这就是你得到重复的原因,

Please Read How HashCode and Equals Work它会帮助你更好地理解上面的语句