Философия Java


Перегрузка hashCode( ) - часть 2


//: c09:StringHashCode.java

public class StringHashCode { public static void main(String[] args) { System.out.println("Hello".hashCode()); System.out.println("Hello".hashCode()); } } ///:~

Чтобы это работало, hashCode( ) для String должен базироваться на содержимом String.

Для эффективного hashCode( ) необходим быстрый и осмысленный механизм: то есть, он должен генерировать значение, основываясь на содержимом объекта. Помните, что это значение не обязательно должно быть уникальным — вы должны больше внимания уделить скорости, а не уникальности — но с помощью hashCode( ) и equals( ) идентичность должна быть полностью установлена.

Поскольку hashCode( ) вызывается до того, как будет произведен индекс ковша, диапазон значений не важен; просто должно генерироваться число типа int.

Есть еще один фактор: хороший hashCode( ) должен возвращать хорошо распределенные значения. Если значения группируются, то HashMap или HashSet будут тяжелее загружаться в некоторых областях и не будут так же быстры, как это могло быть с функцией с хорошим распределением.

Вот пример, который следует этим руководящим принципам:

//: c09:CountedString.java

// Создание хорошего hashCode().

import java.util.*;

public class CountedString { private String s; private int id = 0; private static ArrayList created = new ArrayList(); public CountedString(String str) { s = str; created.add(s); Iterator it = created.iterator(); // Id - это полное число экземпляров

// строки, используемой CountedString:

while(it.hasNext()) if(it.next().equals(s)) id++; } public String toString() { return "String: " + s + " id: " + id + " hashCode(): " + hashCode() + "\n"; } public int hashCode() { return s.hashCode() * id; } public boolean equals(Object o) { return (o instanceof CountedString) && s.equals(((CountedString)o).s) && id == ((CountedString)o).id; } public static void main(String[] args) { HashMap m = new HashMap(); CountedString[] cs = new CountedString[10]; for(int i = 0; i < cs.length; i++) { cs[i] = new CountedString("hi"); m.put(cs[i], new Integer(i)); } System.out.println(m); for(int i = 0; i < cs.length; i++) { System.out.print("Looking up " + cs[i]); System.out.println(m.get(cs[i])); } } } ///:~




Начало  Назад  Вперед