我有个任务,这就是它必须产生用于在一组中的每个对象的唯一值。使用哈希码将是完美的,如果碰撞未在合同哈希代码允许。

一个想法:记录每个对象的散列码成多集。然后,使用散列码作为唯一标识符,但如果散列码是集合一次以上,使用不同的值,该值也未在集合。但这种感觉笨重和尴尬。

更好的想法?

下面是我已经:

public static <V> void toGraphViz(final Graph<V, DefaultWeightedEdge> g, String filename) {

    // to avoid hashcode collisions
    final Set<Integer> hashcodes = new HashSet<Integer>(g.vertexSet().size());

    DOTExporter<V, DefaultWeightedEdge> dot = new DOTExporter<V, DefaultWeightedEdge>(new VertexNameProvider<V> () {

    // vertex name must be unqiue
    @Override
    public String getVertexName(V arg0) {
        int hash = arg0.hashCode();
        while (hashcodes.contains((hash))) {
            hash += 1;
        }
        return "" + hash;
    }
}

编辑:我想这是不是原来清楚,但身份证号码确实在某种程度上需要为对象的功能,因为getVertexName(V)将被调用几次,它预期的V的相同的值,它会得到相同的结果。

另外,顶点类型是通用的。因此,我不能进行任何修改一个特定的类,以解决此问题。

有帮助吗?

解决方案

这是什么的唯一编号的寿命?就在程序的生命周期?在这种情况下,为什么在班上不只是一个简单的静态计数器,用合适的同步访问?增加它的每一个新的对象。没有必要让你使用的值,只有你已经使用了最高值的列表。

如果唯一在许多处决(也许很多并发情况下),那么也许你可以用它产生unqiue记录ID。数据库

EDITED响应于澄清

我错过了之前片是我们不能修改一个我们想产生的独特的“散列”的类。

我认为,从类的哈希码,这将有冲突的工作使生活变得艰难。假设我们可以依赖于顶点类问题具有正确实现的equals(),那么我们可以使用对象本身作为密钥所设定的,我们已经使用散列码的

public class Hasher {

    public  <V> void toGraphViz(final Graph<V, DefaultWeightedEdge> g, String filename) {
         final Map<V, Integer> hashcodes = new HashMap< V, Integer>();
         final int latestHashHolder[] = { 0 }; // array to allow access from inner class

         DOTExporter<V, DefaultWeightedEdge> dot 
                 = new DOTExporter<V, DefaultWeightedEdge>(new VertexNameProvider<V> ()) {

         // vertex name must be unqiue
            @Override
            public synchronized String getVertexName(V vertex) {
                int hashcode;
                if ( hashcodes.containsKey(vertex)){
                    hashcode = hashcodes.get(vertex);
                } else {                
                    hashcode = latestHashHolder[0];
                    latestHashHolder[0]++;
                    hashcodes.put(vertex, (Integer)latestHashHolder[0]);
                }
                return "Vertex-" + hashcode;
            }
        };
    }
}

其他提示

您可以考虑使用 UUID ,这取决于你试图完成什么...

要找到一个独特的价值为一个对象,你要知道,使对象属性的组合是唯一的。

要运行“载()”,就需要有确定“.equals()”的方法,这意味着你应该已经知道如何以唯一地识别一个顶点,所以也许可以想出的一种表达独特性质?

如, “(X,Y,Z,RGB)”

除非我误解的问题,我不会推荐与对象的用于此目的的hashCode搞混。

为什么不直接使用序列号?

static private int serial=0;
static public synchronized nextSerialNumber() { return ++serial; }

或它们的组合/混合,说一个长的((散列<< 32)| getNextSerial())。

为了解决EDIT澄清

在构造对象,分配的序列号,以一个私有成员变量和返回它的hashCode()。然后,您应该重写一起super.equals调用(等于)(因为生成的序列号是默认的equals()实现一致的),因为看到的hashCode()重写没有相应的equals()倍率红旗代码到工具(和其他程序员)。

public class Vertex
{
private final int                   serial;                                 // instance serial number

public Vertex() {
    serial=nextSerialNumber();
    ...
    }

public int hashCode() {
    return serial;
    }

public boolean equals(Object obj) {
    return super.equals(obj);                                               // serial number hash-code consistent with default equals    
    }

...        

static private int nextSerial=0;
static public synchronized nextSerialNumber() { return nextSerial++; }
}

我想你误会了哈希码。 基于合同的hascode应该是一样的,当等于(..)是真实的,反之亦然。所以你的情况只能用相同的属性都应该具有相同的hascode顶点,否则你自己写hascode计算方法应该是固定的。至于我明白你的问题本身就是一个顶点是独一无二的,所以你应该不会有问题吧?

我可能不明白你在做什么,而是考虑创建一个参考 到的每个对象。由于参考包含对象的地址,这将是 独特的每个对象。

这并不难,是吗?只需使用一个不同的哈希算法,如果一个在Java中并不保证没有冲突。发送的对象的散列算法,例如SHA-256,并用其作为重点。如果你需要保持完全相同的对象的不同副本,用不同的哈希值,使用的种子,当你执行散列,并存储这个相关与哈希对象。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top