2015-12-07 8 views
0

Скажем, у меня есть следующий класс А, который реализует интерфейс M:Как реализовать эффективный хэш-код для объекта-оболочки в Java?

class A implements M { 
    int i; 

    int hashCode() { return i; } 
} 

И обертку для А, например

class AWrapper implements M { 

    A a; 

    public Wrapper(A a) { 
     this.a = a; 
    } 

    int hashCode() { ??? } 
} 

Эта иерархия является своего рода Composite Pattern. Мой вопрос в том, что такое хороший хэш-код для класса AWrapper? Я могу использовать a.hashCode(), но тогда все A и AWrapper's будут иметь тот же хэш-код. Каков наилучший способ реализации такого хеш-кода?

Как некоторые люди спрашивают, в чем причина этого дизайна, позвольте мне сделать его более конкретным. Я пишу тип данных для регулярных выражений. Таким образом, A является символом, и существуют регулярные операторы, такие как *, +,? которые по существу являются обертками символов, например, Star (A). Я также хочу, чтобы убедиться, что есть только один экземпляр объекта, поэтому мне нужно делиться, так что если кто-то пишет:

r1 = a*a 
r2 = a*c 

представлены Seq(Star('a'), 'a') и Seq(Star('a'), 'c'), я хочу два экземпляра Star('a') совместно, конечно с помощью заводского вызова.

+0

Есть ли причина, по которой оболочка не должна иметь одинаковый хэш-код? – pvg

+0

Они будут помещены в ту же HashMap, поэтому я хочу избежать столкновений. – Wickoo

+0

Из любопытства, каков сценарий, в котором вам нужно различать 'A' и' AWrapper'? Если у них есть один и тот же хеш-код, я не вижу причин для предоставления класса-оболочки –

ответ

1

Ввод A s и AWrapper s как ключи на одной карте не звучат правильно. Но если это то, что вы хотите, вы можете использовать Objects.hash(a).

Когда предоставляется одна ссылка на объект, возвращаемое значение не равно хеш-коду этой ссылки на объект.


Как примечание стороны, если AWrapper неизменен и метод hashCode называется часто и A :: хэш-код не является тривиальной и объем памяти не является проблемой, вы можете заранее рассчитать хэш-код (стоит если это стоит в вашем сценарии):

class AWrapper implements M { 

    private final A a; 
    private final int hash; 

    public Wrapper(A a) { 
     this.a = a; 
     hash = Objects.hash(a); 
    } 

    int hashCode() { return hash; } 
}