ObjectのhashCodeの生成規則について

このQ&Aのポイント
  • ObjectのhashCodeはどのような規則で生成されているのかについて調べました。
  • マルチスレッドでオブジェクトの生成順番を変えてもhashCodeは同じになることを確認しました。
  • オブジェクトの生成順番とhashCodeの関係について説明しています。
回答を見る
  • ベストアンサー

hashCode

ObjectのhashCodeはどういう規則で生成されているのでしょうか? あるオブジェクトにおいて、オブジェクトの生成順番が実行毎に同じならばhashCodeは同一になるかと思っていたのですが、どうも違うようなので気になりました。 例えば、マルチスレッドでObjectの生成順序を毎回違うよう生成しても、ob配列ojbs1,objs2中の要素のhashCode()は同じになります。 public class HashCodeMultiThreadTest {  public static void main(String[] args) {   final Object[] objs1 = new Object[20];   final Object[] objs2 = new Object[20];   int one_or_two = (int) (Math.random()*2+1);   final long sleep_time1 = 100 * one_or_two;   final long sleep_time2 = 100 * (3-one_or_two);      Thread t1 = new Thread() {    public void run() { try{     for (int i=0; i<objs1.length; i++) {      objs1[i] = new Object();      Thread.sleep(sleep_time1);     }    }catch(Exception e){}}   };   Thread t2 = new Thread() {    public void run() { try {     for (int i=0; i<objs2.length; i++) {      objs2[i] = new Object();      Thread.sleep(sleep_time2);     }    }catch(Exception e){}}   };   try {    t1.start();    t2.start();    t1.join();    t2.join();   }catch(Exception e){}   for (Object o : objs2)    System.out.println(o.hashCode());  } }

  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • PED02744
  • ベストアンサー率40% (157/390)
回答No.1

JDKのJAVADOCを見ればすぐにわかるとおもいますが、 「通常、これはオブジェクトの内部アドレスを整数値に変換する形で実装されます」 とあります。 だから、同じJVMを使って同じだけのメモリ容量でヒープなどパラメータも変更しない状態なら、オブジェクトが生成されるメモリアドレスは変わらないでしょうから、(たまたま)毎回同じになるということでしょう。 また、JAVADOCには続けて「そのような実装テクニックは JavaTM プログラミング言語では不要です」と書かれています。 hashCodeを意識するようなプログラミングは避けるべきでしょう。 http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/Object.html#hashCode()

hekkusyoi
質問者

お礼

ご回答ありがとうございます。 googleでばかり探していて、肝心のjavadocに目を通していませんでした。 > hashCodeを意識するようなプログラミングは避けるべきでしょう。 なるほど、承知いたしました。

関連するQ&A

  • javaの同期について

    javaの同期について package rwlock; public class App1 extends Thread { static private final int REFER = 0; static private final int UPDATE = 1; static private final int[] conf1 = { REFER, REFER, REFER, UPDATE }; static private final int[] conf2 = { REFER, UPDATE, REFER, REFER }; static private MyObj0 mo = new MyObj0(); // App1 + MyObj0 int id; private int[] conf; public App1(int id, int[] conf) { this.id = id; this.conf = conf; } public void run() { long tStart = Time.current(); for (int i = 0; i < conf.length; i++) { switch(conf[i]) { case REFER: mo.refer(); break; case UPDATE: mo.update(); break; default: assert false : "internal error"; } } if (id == 1) { Time.printElapsed(tStart); } } public static void main(String[] args) { App1 th1 = new App1(1, conf1); App1 th2 = new App1(2, conf2); th1.start(); th2.start(); } } public class MyObj0 { private Object countLock = new Object(); private int count; private void enter() { synchronized(countLock) { count++; } } private void leave() { synchronized(countLock) { count--; } } public MyObj0() { count = 0; } public void refer() { enter(); Time.sleep(300); leave(); } public void update() { enter(); synchronized(countLock) { assert count == 1; } Time.sleep(500); leave(); } において、updateの実行中は、他のスレッドでもupdateもreferも実行されないが、二つのスレッドで同時にreferは実行されうるという条件を満たすにはどうしたらよいでしょうか?updateにsynchronizedをつけてみましたが、referが同時に実行されてしまいました

    • ベストアンサー
    • Java
  • ローカル変数にアクセスする複数のスレッドの振る舞いについて

    早速ではございますが、質問をさせていただきます。 以下のコード中のMonitorクラスを複数のスレッドが 共有して自由に入り込んでいるにも関わらす、 排他制御をしていないのにBROKENと表示されません。 final class Main { private final static int NUM = 10; public static void main(String[] args) { Monitor m = new Monitor(); UserThread[] ut = new UserThread[NUM]; Thread[] t = new Thread[NUM]; for(int i=0;i<NUM;i++) { ut[i] = new UserThread(m); t[i] = new Thread(ut[i]); t[i].start(); } } } final class UserThread implements Runnable { private final Monitor m; public UserThread(Monitor m) { this.m = m; } public void run() { System.out.println (Thread.currentThread().getName()+" BEGIN"); while(true) { this.m.func(); } } } final class Monitor { public void func() { int i1 = 0; int i2 = 0; i1++; i2++; if(i1 != i2) { System.out.println ("***** BROKEN ***** " +i1+"と"+i2); } } } 動作確認を2日間くらい行っているのですが、それでも BROKENと表示してくれません。javaの処理系によって 振る舞いがことなるかもしれませんので一概には言えませ んが、いったいなぜBROKENと表示しないのでしょうか? どうかご教授のほどよろしくお願いします。

    • ベストアンサー
    • Java
  • Javaを説明するには

    4枚の絵をパラパラアニメにするソースなのですが。これをわけ合って説明しなくてはならなくなってしまいました。 薄らぼんやりとはわかるのですが。どう説明したらいいのかさっぱり分かりません、どう説明すれば、分かりやすく正しく伝えられるでしょうか?>< import java.applet.Applet; import java.awt.Graphics; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class DNA extends Applet implements Runnable, ActionListener { Image image[] = new Image[4]; int[] timing = { 400,350,230,350}; Thread t; int index1 = 0; int no = 0; private static final long serialVersionUID = 1L; public void init(){ for(int i = 0; i<4; i++){ image[i] = getImage(getDocumentBase(),"img"+(i)+".gif"); } } public void paint(Graphics g){ g.drawImage(image[index1],0,0,this); } public void update(Graphics g) { paint(g); if(++no==4)no=0; } public void start(){ t = new Thread(this); t.start(); } public void run() { while(true){ index1++; if(index1 == 4){ index1 = 0; } repaint(); try{ Thread.sleep(timing[no]); }catch(InterruptedException e){} }} public void actionPerformed(ActionEvent arg0) { } }

  • java 選択肢に制限時間を設ける

    こんにちは. 現在javaでプログラムを組んでいるのですが,その中で選択肢を表示させる部分があります. この選択肢の選択に制限時間を設けたいのですが,うまくいきません. このプログラムの実現のためにどんな方法があるでしょうか? どなたかご教授お願いします. なお, public class time extends Thread { public void run() { for (int i = 3; i >= 0 ; i--) { try { sleep(1000); } catch (InterruptedException e) {} System.out.println(i); } } public static void main(String[] args) { time t = new time(); t.start(); try { System.out.println("スレッド t の終了を待機します。"); t.join(); // カウントダウンが終了するのを待つ System.out.println("スレッド t が終了しました。"); } catch (InterruptedException e) {} } } こちらのソースを参考にプログラムを書いてみましたがだめでした.

    • ベストアンサー
    • Java
  • 交互にスレッド実行 (どうしてちゃんと動いてる?)

    http://oshiete1.goo.ne.jp/qa2968378.html で質問した者です。 2つのスレッドで1と2を交互に実行する以下のプログラム。 final Object obj1 = new Object(); //スレッド間通信用のobject final Object obj2 = new Object(); //スレッド間通信用のobject2 Thread t1 = new Thread() {  public void run() {   try {    while(true) {     System.out.print("1");     synchronized (obj1) {      synchronized (obj2) {       obj2.notify();//相手をnotifyして      }      obj1.wait();//自分はwait     }    }   } catech (Exception e){} }; Thread t2 = new Thread() {  public void run() {   try {    while(true) {     System.out.print("2");     synchronized (obj2) {      synchronized (obj1) {       obj1.notify();      }      obj2.wait();     }    }   } catch (Exception e){}  } }; Thread t1 = new Test1(); Thread t2 = new Test2(); t1.start(); while(t1.getState() != Thread.State.WAITING); t2.start(); が思ったように動いてはいるものの、なぜ正常に動いているかがわかりません。 t1が wait() したときはobj1のロックをもっていて、t2の synchronized (obj1){obj1.notify()} ブロックに入れず待機するはずだと思うのですが。 なぜちゃんと動いているのでしょう?

    • ベストアンサー
    • Java
  • ServletContextLisntener#contextDest

    ServletContextLisntener#contextDestroyedついて 下記の様なコードがあったとします。 Tomcat上で動くServletContextListenerImpl#contextDestroyed内の処理にて ポイント1とポイント2を確実に通過するには どのような設定orコーディングが必要ですか? ※宿題ではありません。月曜に製造完です。(..); class ThreadManager {   private static final ThreadManager manager = new ThreadManager();   private final Thread t;   private boolean isStop;   pulbic ThreadManger () {     isStop = false;     final Thread t = new Thread () {       public void run () {         for ( ; ! this.isStop ; ) {           Thread.sleep(300000);         }       }       //ポイント1     }     t.start();     this.t = t;   }   public static ThreadManager getInstance () {     return manager;   }   public void stop () {     this.isStop = true;   }   public void isAlive () {     return this.isAlive();   } } public class ServletContextListenerImpl implements ServletContextListener {   public void contextInitialzed () {}   public void contextDestroyed () {     final ThreadManager manager = ThreadManager.getInstance();     manager.stop();     while (manager.isAlive()) {       //Thread.sleep(2000)する     }     //ポイント2   } }

    • ベストアンサー
    • Java
  • ThreadとRunnableのlogへの表示差異

    マルチスレッドでsleep()の時間を指定して動かすのを前提で、 Threadを継承した時は、時間通りに(リアルタイムで) eclipseのコンソールへ表示されるのですが、 Runnableをインプリメントしての動作では、 eclipseのコンソールに一瞬で表示されるのは何故でしょうか? public class MultiThread3 implements Runnable{ int time; MultiThread3(int time) { this.time = time; } public void run() { for(int i=0; i<5; i++) System.out.println("No."+i+":"+Thread.currentThread().getName()); try{ Thread.sleep(time); }catch (InterruptedException e) {} } } class MultiThreadTest3{ public static void main(String[] args) { MultiThread3 a = new MultiThread3(500); MultiThread3 b = new MultiThread3(700); MultiThread3 c = new MultiThread3(1100); Thread ta = new Thread(a); Thread tb = new Thread(b); Thread tc = new Thread(c); ta.setName("A"); tb.setName("\tB"); tc.setName("\t\tC"); ta.start(); tb.start(); tc.start(); } }

    • ベストアンサー
    • Java
  • javaの割込みのcatchに関する質問

    下記のコードはgenInterruptにて、割込みを10回発生させ、rcvInterruptでその 割込みをcatchするものです。 割込みの発生周期が1msの場合は、割込みのcatchは略10回受取ることが出来ますが、 割込みの発生周期が短い場合は、最初の2、3個受取るのみです。 Q1)割込みの発生周期が1msの場合には、全ての割込みをcatchすることが出来ますか? //========================== //Project: Interrupt(受信側セット)の確認 class T_thread extends Thread{ static int TIMES=20; public static void main(String args[]){ rcvInterrupt obj=new rcvInterrupt(); obj.start(); for (int i = 0 ; i <TIMES ; i++){ try{ Thread.sleep(1); //System.out.println("main: "+TIMES+"20回の1msタイマー待ち"); }catch(InterruptedException e){ } } } } class genInterrupt extends T_thread{ private Thread target; genInterrupt(Thread targetx){ this.target=targetx; } public void run(){ System.out.println("genInterupt start"); for (int i=0; i<10; i++){ try{ Thread.sleep(0); //割込みが殆ど捕らえられない //Thread.sleep(1); //割込みが全て捕らえられない事がたまにある target.interrupt(); } catch(InterruptedException e){ } } } } class rcvInterrupt extends T_thread{ int cnt=0; public void run(){ genInterrupt obj=new genInterrupt(Thread.currentThread()); obj.setPriority(Thread.MAX_PRIORITY); obj.start(); System.out.println("receiveInterupt start"); for (int i=0 ; i<20 ; i++){ try{ Thread.sleep(2); }catch(InterruptedException e){ System.out.println("get interrupt cnt="+cnt++); } } } } //========================== 以上、宜しくお願いします。

    • ベストアンサー
    • Java
  • Threadに関するの質問

    このプログラムに synchronized , wait(), notify()を加えることで、 stackBody[]配列をオーバーやアンダーフローしないようにできるのでしょうか。お助け下さい! public class test { public static void main(String args[]) { Stack stack = new Stack(5); Pusher pusher = new Pusher(stack); Popper popper = new Popper(stack); pusher.start(); popper.start(); } } class Stack { private int stackSize; private int stackPointer; private int stackBody[]; public Stack(){ this(10); } public Stack(int size){ stackSize = size; stackBody = new int[size]; stackPointer = 0; } public void push(int value){ if(stackSize == stackPointer){ // } stackBody[stackPointer++] = value; } public int pop(){ if(stackPointer == 0){ // } return stackBody[--stackPointer]; } } class Pusher extends Thread { Stack s; public Pusher(Stack s) { this.s = s; } public void run() { int n, interval; for(int i = 0; i < 10; i ++) { n = (int)(100.0 * Math.random()); interval = (int)(100.0 * Math.random()); s.push(n); System.out.println("Pusher:" + n); try{ Thread.sleep(interval); }catch(InterruptedException e) {} } System.out.println("Push 終了"); } } class Popper extends Thread { Stack s; public Popper(Stack s) { this.s = s; } public void run(){ int n, interval; for(int i = 0; i < 10; i++){ interval = (int)(100.0 * Math.random()); n = s.pop(); System.out.println("Popper:" + n); try{ Thread.sleep(interval); }catch(InterruptedException e) {} } System.out.println("Popper 終了"); } }

    • ベストアンサー
    • Java
  • Javaのスレッドに関して質問です

    Assistantクラスを使い待機状態と再開を確認できるプログラムの作成 loafとrestartメソッドを設ける workメソッドが呼ばれる度loafを呼び出す Managerクラスを定義 checkメソッドを設け、Assistantをcheckし続ける loaf状態ならrestartさせる (Managerクラスはデーモンスレッド) ということなんですが、いまいちうまくいきません さぼっても復帰してくれません public class Assistant implements Runnable { private String name; private Chore c; public Assistant(String name, Chore c) { this.name = name; this.c = c; } public void run() { work(); } public void work() { while (true) { synchronized (c) { if (c.doEnd()) break; System.out.println(name + " : " + c.digest()); loaf(); } } } public synchronized void loaf() { try { c.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void restart() { c.notify(); } } public class Chore { private String name; private int step; private int id; public Chore(String name) { this.name = name; this.step = this.name.length(); this.id = 0; } public synchronized String digest() { String message = "" + id + name.charAt(id); try { Thread.sleep(500); } catch (InterruptedException ie) { } id++; return message; } public synchronized boolean doEnd() { return id >= step; } } public class Manager extends Thread { private String name; private Assistant a; public Manager(String name) { this.name = name; } public void run() { check(); } public void check() { a.restart(); } } public class Test { public static void main(String[] args) { Chore[] ch = { new Chore("掃除"), new Chore("プリント印刷"), new Chore("出欠データ入力") }; Assistant[] a = { new Assistant("あ", ch[0]), new Assistant("\tい", ch[1]), new Assistant("\t\tう", ch[2] }; Thread[] t = new Thread[a.length]; for (int i = 0; i < t.length; i++) { t[i] = new Thread(a[i]); } for (int i = 0; i < t.length; i++) { t[i].start(); } Manager m = new Manager("監査"); m.setDaemon(true); m.start(); for (int i = 0; i < t.length; i++) { try { t[i].join(); } catch( InterruptedException ie ) { } } }

    • ベストアンサー
    • Java

専門家に質問してみよう