Java 基于基数的自定义哈希函数
我想开发一个哈希函数,该函数接收一个位集对象,并根据位集中的数字1生成哈希值。该数字使用以下公式计算:Java 基于基数的自定义哈希函数,java,hash,hashmap,Java,Hash,Hashmap,我想开发一个哈希函数,该函数接收一个位集对象,并根据位集中的数字1生成哈希值。该数字使用以下公式计算: BitSet b = new Bitset(); int card = b.cardinality(); 例如: 110 1 010 111 我想要一个按以下顺序返回元素的映射: 1 010 110 111 或 Io ho provato una soluzione Utilizando目标客户地图: map = new TObjectIntCustomHashMap<BitSet
BitSet b = new Bitset();
int card = b.cardinality();
例如:
110
1
010
111
我想要一个按以下顺序返回元素的映射:
1
010
110
111
或
Io ho provato una soluzione Utilizando目标客户地图:
map = new TObjectIntCustomHashMap<BitSet>( new HashingStrategy<BitSet>() {
@Override
public int computeHashCode( BitSet str ) {
return System.identityHashCode( str );
}
@Override
public boolean equals( BitSet str1, BitSet str2 ) {
return (str1.cardinality() < str2.cardinality());
}
});
map=new-tobjectntcustomhashmap(new-HashingStrategy()){
@凌驾
公共整数计算哈希码(位集str){
返回系统识别码(str);
}
@凌驾
公共布尔等于(位集str1、位集str2){
返回(str1.cardinality()
但是结果并不像预期的那样。我认为从用户93335240构建的最干净的解决方案是将自定义比较器应用于
树集
,从而允许像这样的O(nlogn)
解决方案:
Set<Integer> t = new TreeSet<>((a, b) -> { a.cardinality() - b.cardinality() });
t.forEach((a) -> System.out.println(a));
Set t=newtreeset((a,b)->{a.cardinality()-b.cardinality()});
t、 forEach((a)->System.out.println(a));
您可以在其中创建自己的包装器,以提供cardinality()
功能
不能使用哈希,因为它不能保证发生冲突时哈希代码值的分布。您可以尝试线性探测之类的方法,但不能保证它是正确的
事实上,如果你得到一个sub
O(nlogn)
解决方案,这将是一个很好的解决方案。来回答你,即使我认为@MathBunny是正确的。。。与其使用hashmap当前implem的副作用,不如使用专门的结构来处理您的需求。。。这是你要找的
public class HashTest {
public static class BitSet extends java.util.BitSet {
private static final long serialVersionUID = 4014851086683360760L;
public BitSet(int i) {
super(i);
}
public BitSet() {
super();
}
@Override
public int hashCode() {
return stream().map(i -> (int) Math.pow(2, i)).sum();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof java.util.BitSet) {
return obj == null ? false : obj.hashCode() == hashCode();
} else {
return false;
}
}
}
// 1
// 010
// 110
// 111
public static void main(String[] args) {
BitSet bitset1 = new BitSet(1);
bitset1.set(0);
BitSet bitset2 = new BitSet(3);
bitset2.set(1);
BitSet bitset3 = new BitSet(3);
bitset3.set(1);
bitset3.set(2);
BitSet bitset4 = new BitSet(3);
bitset4.set(0);
bitset4.set(1);
bitset4.set(2);
Map<BitSet, String> map = new HashMap<>();
map.put(bitset1, "bitset1");
map.put(bitset2, "bitset2");
map.put(bitset3, "bitset3");
map.put(bitset4, "bitset4");
map.forEach((k, v) -> System.out.println(v));
}
}
公共类HashTest{
公共静态类位集扩展了java.util.BitSet{
私有静态最终长serialVersionUID=4014851086683360760L;
公共位集(int i){
超级(i);
}
公共位集(){
超级();
}
@凌驾
公共int hashCode(){
返回流().map(i->(int)Math.pow(2,i)).sum();
}
@凌驾
公共布尔等于(对象obj){
if(obj instanceof java.util.BitSet){
返回obj==null?false:obj.hashCode()==hashCode();
}否则{
返回false;
}
}
}
// 1
// 010
// 110
// 111
公共静态void main(字符串[]args){
BitSet bitset1=新的位集(1);
比特集1.set(0);
BitSet bitset2=新的位集(3);
比特集2.set(1);
BitSet bitset3=新的位集(3);
比特集3.set(1);
比特集3.set(2);
BitSet bitset4=新的位集(3);
比特集4.set(0);
比特集4.set(1);
比特集4.set(2);
Map Map=newhashmap();
map.put(位集1,“位集1”);
map.put(比特集2,“比特集2”);
map.put(比特集3,“比特集3”);
map.put(比特集4,“比特集4”);
map.forEach((k,v)->System.out.println(v));
}
}
好的,那么你的问题是什么?执行起来似乎不是很难,到底是什么卡住了?您是否尝试了产生意外结果的操作?您需要一个“按此顺序返回元素的映射”,因此,如果您想要一个有序映射,请使用树集
,然后制作一个对象来封装卡
,然后覆盖比较器()
function他似乎想将其集成到一个Map
结构中,在Java中,你不能有一个自定义的hashCode
函数,除非你喜欢组合而不是继承。HashMap不能保证它的键按哈希顺序排列。试着在HashMap中添加一些随机整数。整数hashCode是整数本身的值。在映射上迭代,您会看到它们没有被排序。HashMaps并不总是按hashcode顺序存储条目。另外,你的答案中的哈希代码不是OP所要求的(他只希望它等于基数,即只是位数集,而不是位数集的整数表示)。我完全同意你的观点。顺序只是当前哈希映射实现的副作用。如果你使用的是大数,那么这将完全失效(超过32位时)但在J8中,这项关于小数据的工作……他要求的……我完全同意你的看法,这既不安全,也不是一个好的做法!@ArnaultLePrévost Corvellec感谢你的帮助,但如果我把001和010放在一起,哈希代码会产生相同的值,元素会重叠。这是个问题。eu nop……位集bit0=新位集(3);bit0.set(0,false);bit0.set(1,true);bit0.set(2,false);BitSet bit1=new BitSet(3);bit1.set(0,true);bit1.set(1,false);bit1.set(2,false);System.out.println(bit0+“”+bit0.hashCode());System.out.println(bit1+“”+bit1.hashCode());此显示{1}2{0}1hascode将位集的值计算为无符号整数
public class HashTest {
public static class BitSet extends java.util.BitSet {
private static final long serialVersionUID = 4014851086683360760L;
public BitSet(int i) {
super(i);
}
public BitSet() {
super();
}
@Override
public int hashCode() {
return stream().map(i -> (int) Math.pow(2, i)).sum();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof java.util.BitSet) {
return obj == null ? false : obj.hashCode() == hashCode();
} else {
return false;
}
}
}
// 1
// 010
// 110
// 111
public static void main(String[] args) {
BitSet bitset1 = new BitSet(1);
bitset1.set(0);
BitSet bitset2 = new BitSet(3);
bitset2.set(1);
BitSet bitset3 = new BitSet(3);
bitset3.set(1);
bitset3.set(2);
BitSet bitset4 = new BitSet(3);
bitset4.set(0);
bitset4.set(1);
bitset4.set(2);
Map<BitSet, String> map = new HashMap<>();
map.put(bitset1, "bitset1");
map.put(bitset2, "bitset2");
map.put(bitset3, "bitset3");
map.put(bitset4, "bitset4");
map.forEach((k, v) -> System.out.println(v));
}
}