我与使用 Apache Commons Lang HashCodeBuilder使用 release 3.4发生冲突。我正在散列一个 Route 对象,其中包含两个 Cell 对象,start 和 end。最后,我提供了一个发生碰撞的示例。这两个类都覆盖了 hashCode和equals方法。首先是 Cell 类:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Cell {
private int east;
private int south;
public Cell(int east, int south) {
this.east = east;
this.south = south;
}
public int getEast() {
return east;
}
public void setEast(int east) {
this.east = east;
}
public int getSouth() {
return south;
}
public void setSouth(int south) {
this.south = south;
}
@Override
/**
* Compute hash code by using Apache Commons Lang HashCodeBuilder.
*/
public int hashCode() {
return new HashCodeBuilder(17, 31)
.append(this.south)
.append(this.east)
.toHashCode();
}
@Override
/**
* Compute equals by using Apache Commons Lang EqualsBuilder.
*/
public boolean equals(Object obj) {
if (!(obj instanceof Cell))
return false;
if (obj == this)
return true;
Cell cell = (Cell) obj;
return new EqualsBuilder()
.append(this.south, cell.south)
.append(this.east, cell.east)
.isEquals();
}
}
和路线类:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.*;
public class Route {
private Cell startCell;
private Cell endCell;
public Route(Cell startCell, Cell endCell) {
this.startCell = startCell;
this.endCell = endCell;
}
public Cell getStartCell() {
return startCell;
}
public void setStartCell(Cell startCell) {
this.startCell = startCell;
}
public Cell getEndCell() {
return endCell;
}
public void setEndCell(Cell endCell) {
this.endCell = endCell;
}
@Override
public int hashCode() {
return new HashCodeBuilder(43, 59)
.append(this.startCell)
.append(this.endCell)
.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Route))
return false;
if (obj == this)
return true;
Route route = (Route) obj;
return new EqualsBuilder()
.append(this.startCell, route.startCell)
.append(this.endCell, route.endCell)
.isEquals();
}
}
碰撞示例:
public class Collision {
public static void main(String[] args) {
Route route1 = new Route(new Cell(154, 156), new Cell(154, 156));
Route route2 = new Route(new Cell(153, 156), new Cell(151, 158));
System.out.println(route1.hashCode() + " " + route2.hashCode());
}
}
输出为1429303 1429303。现在,如果我将两个类的初始奇数和乘数奇数更改为相同,则此示例不会发生冲突。但在 HashCodeBuilder 的文档中,它明确指定:
必须传入两个随机选择的奇数。理想情况下 ,每个类应该不同,但这并不重要。
理想情况下,如果可能的话,我希望为我的示例提供完美的散列函数(内射函数)。