最近は C の差分やネタばっかりになっていたので、たまには Java を書けるところをアピールしておかないといけないと思ったので。
配列のhashCode()は要素に無関係なのか - T/O で提起されている問題は以下のように hashCode() をオーバーライドできれば解決できるんだろうけど、Java では配列のクラスに関しては言語仕様および仮想マシン仕様でがっちり決められちゃってるから、残念ながら無理なんだよな。
/* * コンパイルできないよ\(^o^)/ */ class ArrayOverride { static private final int LENGTH = 8; static public void main(String[] args) { Object[] a = new Object[LENGTH] { public int hashCode() { int hashcode = 0; for (Object o : this) { hashcode = hashcode ^ o.hashCode(); } return hashcode; } }; } }
あと、ちょっと考えたのはこれ。
それに対して、ListのhashCode()は要素から取るので、要素が全く一緒なListのhashCode()は同一になる。
int hashCode = 1; Iterator<E> i = list.iterator(); while (i.hasNext()) { E obj = i.next(); hashCode = 31*hashCode + (obj==null ?0 :obj.hashCode()); }
「LinkedList の hashCode() を計算する度にクソ真面目に O(n) の処理を毎回やっているのはどうなんだ?modCount か何かを見てキャッシュしておくような実装にすればいいのに。」とか思っていたのだが、よくよく考えてみると、各要素が返す hashCode() が変わるイベントの発生を LinkedList 側では検出できないからやっぱダメだということに気付いた。
久々に Java を真面目を考えたけど、他の言語もこれくらいは考えられるように勉強しないといけないと思った。