Java hashCode原理
ステップ1:非効率性を見つけるための一覧
リストには重複した名前を保持しない、200万ヒーローのないオーダーがないと仮定すると、
見つけるために、「英雄1000000」オブジェクトnameというなければならない
名前は「英雄1000000」の主人公である見つけるまでの練習の一覧は、各トラバースに1つずつ行われます。
最悪のケースでは、我々は2つの万回を反復して比較する必要が対応する英雄を見つけるために。
テストロジック:
- ArrayListに200万オブジェクトの初期化
- スクランブルデータコンテナ
- 10回の照会、統計がで消費されるたびに
、コンピュータの異なる構成は、時間差があります過ごしました。機械では、費やした時間は、おそらく約600ミリ秒であります
package collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import charactor.Hero;
public class TestCollection {
public static void main(String[] args) {
List<Hero> heros = new ArrayList<Hero>();
for (int j = 0; j < 2000000; j++) {
Hero h = new Hero("Hero " + j);
heros.add(h);
}
// 进行10次查找,观察大体的平均值
for (int i = 0; i < 10; i++) {
// 打乱heros中元素的顺序
Collections.shuffle(heros);
long start = System.currentTimeMillis();
String target = "Hero 1000000";
for (Hero hero : heros) {
if (hero.name.equals(target)) {
System.out.println("找到了 hero!" );
break;
}
}
long end = System.currentTimeMillis();
long elapsed = end - start;
System.out.println("一共花了:" + elapsed + " 毫秒");
}
}
}
ステップ2:HashMapのパフォーマンス
HashMapを使用して同じ外観を行います
- HashMapのに200万オブジェクトを初期化。
- クエリの10倍
- 統計クエリは、すべての時間を消費し
観察することができ、少し時間を費やし、1ミリ秒未満で過ごした時間
package collection;
import java.util.HashMap;
import charactor.Hero;
public class TestCollection {
public static void main(String[] args) {
HashMap<String,Hero> heroMap = new HashMap<String,Hero>();
for (int j = 0; j < 2000000; j++) {
Hero h = new Hero("Hero " + j);
heroMap.put(h.name, h);
}
System.out.println("数据准备完成");
for (int i = 0; i < 10; i++) {
long start = System.currentTimeMillis();
//查找名字是Hero 1000000的对象
Hero target = heroMap.get("Hero 1000000");
System.out.println("找到了 hero!" + target.name);
long end = System.currentTimeMillis();
long elapsed = end - start;
System.out.println("一共花了:" + elapsed + " 毫秒");
}
}
}
ステップ3:HashMapの原理と辞書
HashMapの開始は、原理を説明する前に、まずリコールの我々は、中・高校英語の辞書で使用すること。
例えば、単語がLengendaryあると仮定して、意味に対応する中国語の単語を見つけるために、最初のディレクトリ内のページ555にLengendaryを見つけます。
その後、このページには、複数の単語を持っていますが、量は非常に少ない、一つ一つが比較的速やかに目標単語Lengendaryを見つけてきました、555頁に向けます。
555は、対応するLengendaryと同等であり、ハッシュコード
ステップ4:理由優れた性能のHashMap
----- -----ハッシュコードの概念
のすべてのオブジェクト、対応があるハッシュコード(ハッシュ値)
例えば1001に文字列「gareen」に対応するように(実際には、理解の容易さがある、の値をとります)
このような1004列「temoo」に対応するとして
、このような文字列「DB」として1008年に相当する
ような文字列として「アニー」もに相当1008
データは----- -----格納されている
すべての文字列をハッシュコードを対応するように、長さが2000である配列を作成し、設定された特定のハッシュコードアルゴリズム、0-1999の間に落ちる
」の名前を格納しますgareen「英雄、英雄の名前を入れて作るのキーと値のペアを、配列の場所に1001に保存されている
名前を保存するために」temoo「英雄、英雄は、アレイの場所に1004に店舗を置く
の名前を格納しますである「DB」の主人公は、ヒーローは、アレイの場所に1008年に店舗を置く
「アニー」の主人公、しかし、対応する位置1008は「アニー」ハッシュコード名を格納するDBの英雄た、そして、ここで作成しリストは、その後、バックアニーデシベルのヒーローに保存されています
----- -----検索データ
ようgareenを見つけることとしては、第一の計算「gareen」ハッシュコード1001指数によれば、1001、配列を見つけるために、(配列の添字に基づいてターゲット、非常に高速でありますA)を主人公がgareenある、唯一主人公1001この位置を見つけ。
、1008を見つける。例えば、この位置はアニー、第一の計算「アニー」ハッシュコードは、1008である配列に、このインデックスは、見つけるために1008に応じを見つけるために、両者を有します英雄、2人の英雄(の1つの比較ずつの後、名前イコール)、量は少なく、多くと比較する必要があるため、すばやく目的の英雄を識別することができ
、これはハッシュマップのクエリを使用することで、非常に高速な原則。
これは、時間のためのスペースの考え方
ステップ5:。HashSetのは、繰り返しのかどうかを決定します
HashSetのデータが繰り返されていない、同じデータがどのようにそれが重複しているかどうかを判断するために最後に一緒に保存することができないのですか?
HashSetのとHashMapの間の関係、HashSetのによると、私たちは何の自己実現はありません知っているので、しかし、HashMapのキーを繰り返すかどうかを判断するために、その本質的に、HashMapをカプセル化しています。
そして、学習によってステップ、リピートするかどうかの鍵は、2つの段階で判断さ:
としてかどうかハッシュコード
ハッシュコードが同じでない場合、つまり異なるピット、繰り返してはならない
ハッシュコードと同じ場合である、同じピット、等号も比較する必要が
同じに等しい場合、そのデータが繰り返され
ない場合は等号と同じ、データが異なっています。
以下は、提供するJava APIのハッシュコードの文字列を生成する方法です。
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
S [0]は文字を表し
nは文字列の長示し
たアルゴリズムを理解する必要はありませんこの演習のを、しかし、カスタムハッシュコードは、単純なアルゴリズムは、ハッシュコードの任意の文字列を計算する
ので、Stringクラスを書き換えることができないので、私たちは、静的メソッドで文字列のハッシュコードに戻りました
public static int hashcode(String)
文字列の長さが0の場合、0が返されます。
それ以外の場合:すべての文字を取得した後、23を掛け、一緒に加え、デジタルに変換
(s[0]+ s[1] + s[2] + s[3]+ s[n-1])*23.
値が1999を超えた場合、その後、2000年の残りの部分を取り、保証は0-1999の間に入ります。
それが負の場合、絶対値。
2-10ランダムに生成された不等長列100、印刷枚数の現在値が取得されるハッシュコード
答え:
package collection;
public class TestCollection {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
int length = (int) (Math.random()*8+2);
String str = randomString(length);
int hashcode = hashcode(str);
System.out.printf("%-11s的自定义hashcode是:%d%n",str,hashcode);
}
}
private static int hashcode(String str) {
// TODO Auto-generated method stub
if(0==str.length())
return 0;
int hashcode = 0;
char[]cs= str.toCharArray();
for (int i = 0; i < cs.length; i++) {
hashcode +=cs[i];
}
hashcode*=23;
//取绝对值
hashcode = hashcode<0?0-hashcode:hashcode;
//落在0-1999之间
hashcode %=2000;
return hashcode;
}
private static String randomString(int length) {
String pool = "";
for (short i = '0'; i <= '9'; i++) {
pool += (char) i;
}
for (short i = 'a'; i <= 'z'; i++) {
pool += (char) i;
}
for (short i = 'A'; i <= 'Z'; i++) {
pool += (char) i;
}
char cs[] = new char[length];
for (int i = 0; i < cs.length; i++) {
int index = (int) (Math.random() * pool.length());
cs[i] = pool.charAt(index);
}
String result = new String(cs);
return result;
}
}