Java的HashSet中包含的功能不工作(Java HashSet contains functi

2019-10-21 13:55发布

我写一个简单的程序如下:给定两个数M和N,p为[M,N],并且q是从[1,P-1],求P / Q的所有最简分数。 我的想法是蛮力P,Q的所有可能的值。 并使用HashSet的,以避免重复分数。 然而,不知何故包含功能无法按预期工作。

我的代码

import java.util.HashSet;
import java.util.Set;

public class Fraction {
    private int p;
    private int q;

    Fraction(int p, int q) {
        this.p = p;
        this.q = q;
    }

    public static int getGCD(int a, int b) {
        if (b == 0)
            return a;
        else 
            return getGCD(b, a % b);
    }

    public static Fraction reduce(Fraction f) {
        int c = getGCD(f.p, f.q);
        return new Fraction(f.p / c, f.q / c);
    }

    public static HashSet<Fraction> getAll(int m, int n) {
        HashSet<Fraction> res = new HashSet<Fraction>();
        for (int p = m; p <= n; p++)
            for (int q = 1; q < p; q++) {
                Fraction f = new Fraction(p,q);
                Fraction fr = reduce(f);
                if (!res.contains(fr))
                    res.add(fr);
            }
        return res;
    }

    public static void print(Fraction f) {
        System.out.println(f.p + "/" + f.q);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        HashSet<Fraction> res = getAll(2, 4);
        for (Fraction f : res)
            print(f);
    }

}

下面是程序的输出

4/3
3/1
4/1
2/1
3/2
2/1

你可以看到分数2/1是重复的。 任何人都可以帮我找出原因和如何解决它。 非常感谢。

Answer 1:

覆盖Object#equalsObject#hashCode的方法Fraction类。 这些方法使用HashSet确定两个对象是相同的。 当你不覆盖它们,等号,而他们的字段值的平等的对象的引用的方法测试平等。

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + p;
    result = prime * result + q;
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Fraction other = (Fraction) obj;
    if (p != other.p)
        return false;
    if (q != other.q)
        return false;
    return true;
}


Answer 2:

您需要实现Fraction#equals()Fraction#hashcode() ,因为这是用于确定天气集合中包含一定的价值或没有。 没有它,对象引用进行比较,这不会给你想要的结果。



Answer 3:

你的Fraction类没有重载hashCodeequals 。 一个HashMap包含试图找到相同的hashCode一个键(等于)为您提供的一个。 当你创建一个新的实例Fraction ,它永远不会是一样的一个已经在HashMap 。 这里是你会怎么做hashCodeequals

@Override
public int hashCode() {
    return super.hashCode() + p * 24 + q * 24;
}

@Override
public boolean equals(Object other) {
    if (!(other instanceof Fraction)) return false;
    return ((Fraction) other).p == this.p && ((Fraction) other).q == this.q;
}


文章来源: Java HashSet contains function not working