zoukankan      html  css  js  c++  java
  • Guava包学习--Hash

    我们HashMap会有一个rehash的过程,为什么呢?因为java内建的散列码被限制为32位,而且没有分离散列算法和所作用的数据,所以替代算法比较难做。我们使用HashMap的时候它自身有一个rehash的过程,所以我们无需操心。但是如果我们自己离开hashmap的内容,去使用Object.hashCode()就不有可能会比较坑爹了,碰撞处理我们自己去做并不容易。但是,我们可以使用Guava的hash功能。

    Guava的Hash package底下的内容比较多:

    它提供了不同的Hash算的实现,然后我们需要先从继承体系上面去看一下。

    Hash算法的继承体系:

    Function函数的继承体系:

    然后还有Funnel接口等,基本上已经包括Hash的组成内容,下面我们挨个来看下都是做什么的。

    /**
     * An object which can receive a stream of primitive values.
    @Beta
    public interface PrimitiveSink {···}------------------一个能接收原始数据类型流的对象?

    里面定义了一堆方法,都是putxxxxvalue:

      PrimitiveSink putBytes(byte[] bytes, int off, int len);
    
      PrimitiveSink putShort(short s);
    
      PrimitiveSink putInt(int i);
    
      PrimitiveSink putLong(long l);
    
      PrimitiveSink putFloat(float f);
    
      PrimitiveSink putDouble(double d);
    
      PrimitiveSink putBoolean(boolean b);
    
      PrimitiveSink putChar(char c);
    
      PrimitiveSink putUnencodedChars(CharSequence charSequence);
    
      PrimitiveSink putString(CharSequence charSequence, Charset charset);

    非常好理解,不赘述。然后我们看Hasher这个核心类(接口)是干啥的:

    @Beta
    public interface Hasher extends PrimitiveSink {
      @Override
      Hasher putByte(byte b);
    
      @Override
      Hasher putBytes(byte[] bytes);
    }

    好吧,其实它就是把PrimitiveSink的方法给全部override了一遍,然后它新增了几个方法:

      <T> Hasher putObject(T instance, Funnel<? super T> funnel);------------一个简化的put object进行hash的方法
    
      @CheckReturnValue
      HashCode hash();---实际做hash的方法
    
      @Override
      @Deprecated
      int hashCode();----不推荐使用,但是必须覆盖的hashcode

     上个代码示例:

    package com.congsg.learning;
    
    import com.google.common.base.Charsets;
    import com.google.common.hash.*;
    
    import java.nio.charset.Charset;
    
    /**
     * Created by congshaogang on 16/3/29.
     */
    public class GuavaHashTest {
    
        public static void main(String[] args) {
    
    
            HashFunction function_0 = Hashing.md5();
            HashFunction function_1 = Hashing.murmur3_128();
            Hasher hasher_0 = function_0.newHasher();
            Hasher hasher_1 = function_1.newHasher();
    
            Person person = new Person();
            person.setAge(27);
            person.setName("hahahah");
            person.setAddress("北京三里屯");
            person.setPhoneNumber(16666666666L);
            person.setMale(Male.man);
    
            HashCode code_0 = hasher_0.putInt(person.getAge())
                    .putString(person.getName(), Charsets.UTF_8)
                    .putString(person.getAddress(), Charsets.UTF_8)
                    .putLong(person.getPhoneNumber())
                    .putObject(person.getMale(), new Funnel<Male>() {
                        @Override
                        public void funnel(Male from, PrimitiveSink into) {
                            into.putString(from.name(),Charsets.UTF_8);
                        }
                    }).hash();
            HashCode code_1 = hasher_1.putInt(person.getAge())
                    .putString(person.getName(), Charsets.UTF_8)
                    .putString(person.getAddress(), Charsets.UTF_8)
                    .putLong(person.getPhoneNumber())
                    .putObject(person.getMale(), new Funnel<Male>() {
                        @Override
                        public void funnel(Male from, PrimitiveSink into) {
                            into.putString(from.name(),Charsets.UTF_8);
                        }
                    }).hash();
            System.out.println(code_0.asLong());
            System.out.println(code_1.asLong());
        }
    
    
        public enum Male {
            man, woman;
        }
    
        public static class Person {
            int age;
            String name;
            String address;
            long phoneNumber;
            Male male;
    
            public int getAge() {
                return age;
            }
    
            public void setAge(int age) {
                this.age = age;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getAddress() {
                return address;
            }
    
            public void setAddress(String address) {
                this.address = address;
            }
    
            public long getPhoneNumber() {
                return phoneNumber;
            }
    
            public void setPhoneNumber(long phoneNumber) {
                this.phoneNumber = phoneNumber;
            }
    
            public Male getMale() {
                return male;
            }
    
            public void setMale(Male male) {
                this.male = male;
            }
        }
    }

    我们可以利用自己去构造一些primitive的数据类型去进行hash操作,最后获得hash值。

  • 相关阅读:
    20140710 sequence 前缀和
    20140709 testC 数学题
    20140708 testA 组合数学
    20140708 testB DP 组合数学
    Sad :(
    已经是一个废人了……
    Game Theory
    HDU Math Problems
    2-sat问题
    并查集
  • 原文地址:https://www.cnblogs.com/congsg2016/p/5143658.html
Copyright © 2011-2022 走看看