这是Line对象的参考实现,我的混淆是从第40行到第43行,问题是,如果两条线不同,但是斜率/截距的OR结果恰好相同,是否有任何问题(例如,由于相同的哈希值,处理不同的行相同)?因为我认为相同的哈希值意味着相同的行。
如果哈希值的当前实现确实存在我提到的问题,请欣赏是否有人可以帮助提供一些见解在我的情况下什么是哈希值的良好实现。
1 public static Line findBestLine(GraphPoint[] points) {
2 Line bestLine = null;
3 HashMap<Line, Integer> line_count = new HashMap<Line, Integer>();
4 for (int i = 0; i < points.length; i++) {
5 for (int j = i + 1; j < points.length; j++) {
6 Line line = new Line(points[i], points[j]);
7 if (!line_count.containsKey(line)) {
8 line_count.put(line, 0);
9 }
10 line_count.put(line, line_count.get(line) + 1);
11 if (bestLine == null ||
12 line_count.get(line) > line_count.get(bestLine)) {
13 bestLine = line;
14 }
15 }
16 }
17 return bestLine;
18 }
19
20 public class Line {
21 private static double epsilon = .0001;
22 public double slope;
23 public double intercept;
24 private boolean infinite_slope = false;
25 public Line(GraphPoint p, GraphPoint q) {
26 if (Math.abs(p.x - q.x) > epsilon) { // if x’s are different
27 slope = (p.y - q.y) / (p.x - q.x); // compute slope
28 intercept = p.y - slope * p.x; // y intercept from y=mx+b
29 } else {
30 infinite_slope = true;
31 intercept = p.x; // x-intercept, since slope is infinite
32 }
33 }
34
35 public boolean isEqual(double a, double b) {
36 return (Math.abs(a - b) < epsilon);
37 }
38
39 @Override
40 public int hashCode() {
41 int sl = (int)(slope * 1000);
42 int in = (int)(intercept * 1000);
43 return sl | in;
44 }
45
46 @Override
47 public boolean equals(Object o) {
48 Line l = (Line) o;
49 if (isEqual(l.slope, slope) && isEqual(l.intercept, intercept)
50 && (infinite_slope == l.infinite_slope)) {
51 return true;
52 }
53 return false;
54 }
55 }
答案 0 :(得分:3)
因为我认为相同的哈希值意味着同一行。
不,它没有。这是一个普遍的误解。如果两个对象具有相同的哈希码,则它们可能相等 - 但它们不必相同。您应该永远将相等的哈希码视为两个对象相等的证明。
这里使用的哈希码在各方面都很差,但它至少是有效的。
作为一个极端的例子,它总是有效(但几乎总是无益)写:
public override int hashCode() {
return 5;
}
这保证了相同的对象将具有相同的哈希码,这是正确性所需要的。除了正确性之外,确保不相等的对象具有不同的哈希码是使高效在基于散列的查找中使用该类型的问题。