Apache Commons Lang HashCodeBuilder冲突

杰尼·杰林(Jernej Jerin)

我与使用3.4版的Apache Commons Lang HashCodeBuilder发生冲突我正在哈希一个Route对象,其中包含两个Cell对象,即开始和结束。最后,我提供了一个发生冲突时的示例。这两个类都覆盖hashCodeequals方法。首先是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();
    }
}

和Route类:

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的文档中,它明确指定:

必须传递两个随机选择的奇数。理想情况下,每个类的奇数应该不同,但这并不是至关重要的。

理想情况下,如果可能的话,我希望为示例提供完美的哈希函数(内插函数)。

科佩格

您可能能够通过在生成哈希代码时添加更多参数来更好地分配生成的哈希代码(这与Apache commons库无关)。通过此示例,您可以预先计算该类的一个或多个属性Route并在生成哈希码时使用此属性。例如,计算两个Cell对象之间的直线的斜率

double slope = (startCell.getEast() - endCell.getEast());
if ( slope == 0 ){//prevent division by 0
    slope = startCell.getSouth() - endCell.getSouth();
}else{
    slope = (startCell.getSouth() - endCell.getSouth()) / slope;
}

return new HashCodeBuilder(43, 59)
   .append(this.startCell)
   .append(this.endCell)
   .append(slope)
   .toHashCode();

用您的示例生成83091911 83088489或者(或与之一起)使用两个Cell对象之间的距离

double length = Math.sqrt(Math.pow(startCell.getSouth() - endCell.getSouth(), 2) + Math.pow(startCell.getEast() - endCell.getEast(), 2));
return new HashCodeBuilder(43, 59)
   .append(this.startCell)
   .append(this.endCell)
   .append(length)
   .toHashCode();

与您的示例一起使用的结果为83091911-486891382

并测试这是否可以防止碰撞:

List<Cell> cells = new ArrayList<Cell>();
for ( int i = 0; i < 50; i++ ){
    for ( int j = 0; j < 50; j++ ){
        Cell c = new Cell(i,j);
        cells.add(c);

    }
}
System.out.println(cells.size() + " cells generated");
System.out.println("Testing " + (cells.size()*cells.size()) + " number of Routes");
Set<Integer> set = new HashSet<Integer>();
int collisions = 0;
for ( int i = 0; i < cells.size(); i++ ){
    for ( int j = 0; j < cells.size(); j++ ){
        Route r = new Route(cells.get(i), cells.get(j));
        if ( set.contains(r.hashCode() ) ){
            collisions++;
        }
        set.add(r.hashCode());
    }
}
System.out.println(collisions);

生成的6,250,000条路线中:

  1. 没有长度坡度6,155,919次碰撞
  2. 带有长度倾斜度873,047次碰撞

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Apache Commons Lang 2与3

来自分类Dev

NoClassDefFoundError:org.apache.commons.lang.StringUtils

来自分类Dev

java.lang.ClassNotFoundException:org.apache.commons.lang.UnhandledException

来自分类Dev

org.apache.commons.lang.SerializationException:java.lang.ClassNotFoundException

来自分类Dev

java.lang.ClassNotFoundException:org.apache.commons.lang.UnhandledException

来自分类Dev

java.lang.NoClassDefFoundError:org / apache / commons / collections / Transformer

来自分类Dev

java.lang.NoClassDefFoundError:org / apache / commons / io / output / DeferredFileOutputStream

来自分类Dev

java.lang.ClassNotFoundException:org.apache.commons.fileupload.FileItemFactory

来自分类Dev

无法导入org.apache.commons.lang3.math.NumberUtils

来自分类Dev

Java: Could not find IntRange in Apache Commons Lang 3.3.2

来自分类Dev

Java:在Apache Commons Lang 3.3.2中找不到IntRange

来自分类Dev

java.lang.NoClassDefFoundError:org / apache / commons / pool / impl / GenericObjectPool

来自分类Dev

为什么无法导入org.apache.commons.lang.StringUtils?

来自分类Dev

NoClassDefFoundError:org / apache / commons / lang3 / StringUtils

来自分类Dev

奇怪的Apache Commons Lang StringUtils.join结果

来自分类Dev

java.lang.ClassNotFoundException:org.apache.commons.fileupload.FileItemFactory

来自分类Dev

#java.lang.NoClassDefFoundError:org / apache / commons / digester / Digester

来自分类Dev

如何解决NoClassDefFoundError:Apache Commons Lang Android

来自分类Dev

Java:在Apache Commons Lang 3.3.2中找不到IntRange

来自分类Dev

apache.commons.lang3.DateUtils.setMonths与十二月

来自分类Dev

java.lang.NoClassDefFoundError:org / apache / commons / io / FileUtils

来自分类Dev

java.lang.ClassNotFoundException:org.apache.commons.fileupload.FileItemFactory

来自分类Dev

java.lang.AbstractMethodError:org.apache.commons.dbcp.PoolingDataSource

来自分类Dev

java.lang.ClassNotFoundException:org.apache.commons.logging.Log

来自分类Dev

抛出java.lang.ClassNotFoundException:所造成org.apache.commons.lang3.builder.EqualsBuilder

来自分类Dev

java.lang.ClassNotFoundException:org.apache.commons.lang.builder.ToStringBuilder

来自分类Dev

org.apache.commons.lang3.StringUtils 与 org.apache.logging.log4j.util.Strings

来自分类Dev

错误“ java.lang.NoClassDefFoundError:com.google.repacked.apache.commons.io.FileUtils”

来自分类Dev

错误:(3,0)原因:org / apache / commons / lang3 / StringUtils

Related 相关文章

  1. 1

    Apache Commons Lang 2与3

  2. 2

    NoClassDefFoundError:org.apache.commons.lang.StringUtils

  3. 3

    java.lang.ClassNotFoundException:org.apache.commons.lang.UnhandledException

  4. 4

    org.apache.commons.lang.SerializationException:java.lang.ClassNotFoundException

  5. 5

    java.lang.ClassNotFoundException:org.apache.commons.lang.UnhandledException

  6. 6

    java.lang.NoClassDefFoundError:org / apache / commons / collections / Transformer

  7. 7

    java.lang.NoClassDefFoundError:org / apache / commons / io / output / DeferredFileOutputStream

  8. 8

    java.lang.ClassNotFoundException:org.apache.commons.fileupload.FileItemFactory

  9. 9

    无法导入org.apache.commons.lang3.math.NumberUtils

  10. 10

    Java: Could not find IntRange in Apache Commons Lang 3.3.2

  11. 11

    Java:在Apache Commons Lang 3.3.2中找不到IntRange

  12. 12

    java.lang.NoClassDefFoundError:org / apache / commons / pool / impl / GenericObjectPool

  13. 13

    为什么无法导入org.apache.commons.lang.StringUtils?

  14. 14

    NoClassDefFoundError:org / apache / commons / lang3 / StringUtils

  15. 15

    奇怪的Apache Commons Lang StringUtils.join结果

  16. 16

    java.lang.ClassNotFoundException:org.apache.commons.fileupload.FileItemFactory

  17. 17

    #java.lang.NoClassDefFoundError:org / apache / commons / digester / Digester

  18. 18

    如何解决NoClassDefFoundError:Apache Commons Lang Android

  19. 19

    Java:在Apache Commons Lang 3.3.2中找不到IntRange

  20. 20

    apache.commons.lang3.DateUtils.setMonths与十二月

  21. 21

    java.lang.NoClassDefFoundError:org / apache / commons / io / FileUtils

  22. 22

    java.lang.ClassNotFoundException:org.apache.commons.fileupload.FileItemFactory

  23. 23

    java.lang.AbstractMethodError:org.apache.commons.dbcp.PoolingDataSource

  24. 24

    java.lang.ClassNotFoundException:org.apache.commons.logging.Log

  25. 25

    抛出java.lang.ClassNotFoundException:所造成org.apache.commons.lang3.builder.EqualsBuilder

  26. 26

    java.lang.ClassNotFoundException:org.apache.commons.lang.builder.ToStringBuilder

  27. 27

    org.apache.commons.lang3.StringUtils 与 org.apache.logging.log4j.util.Strings

  28. 28

    错误“ java.lang.NoClassDefFoundError:com.google.repacked.apache.commons.io.FileUtils”

  29. 29

    错误:(3,0)原因:org / apache / commons / lang3 / StringUtils

热门标签

归档