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值。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM