Коллекция Java с 2 ключами - PullRequest
       10

Коллекция Java с 2 ключами

5 голосов
/ 14 февраля 2011

Я хочу реализовать HashMap с ключом из 2 компонентов. Ex.

Pseudocode:

Key = <Component1, Component2>
CollName<Key, Val> coll = new CollName<Key, Val>;

Как я могу реализовать это в Java, учитывая скорость и размер Коллекции. Спасибо: D

Ответы [ 5 ]

7 голосов
/ 14 февраля 2011

Вам нужен вспомогательный класс (составной ключ), который содержит ваши два ключа

public class CompositeKey<... , ...> {
   ... component1;
   ... component2;

   // getter , setter, ...

   // equals

  // hashcode()
}

, а затем вы можете использовать его в качестве ключа:

CompositeKey cKey = new CompositeKey(1,2);
Map x.put(cKey,val);

Здесь очень важноРеализуйте equals() и hashCode() хорошим способом.Большинство IDE могут помочь вам здесь.Для hashCode важно, чтобы он возвращал «уникальное» значение, чтобы предотвратить коллизию хеш-ключей (т. Е. Возвращение постоянного значения является наихудшим случаем, поскольку все значения окажутся в одном и том же сегменте).Многие реализации хэш-кода делают что-то по

hashcode = component1.hashCode() + 37* component2.hashCode();

Если вы хотите больше подробностей, найдите любую книгу по CS, в которой говорится об алгоритмах хеширования.

Если вы хотите использовать это для сохранения, такжеПосмотрите на это сообщение в блоге .

2 голосов
/ 14 февраля 2011

Вы не можете напрямую создать Карту с двумя ключами, однако вы можете объединить их.

Самый простой способ - сериализовать их в строку и объединить.

String key = obj1.toString() + "-" + obj2.toString();
myMap.put( key, myValue );

предполагая, что объекты могут быть легко сериализованы в строку, которая будет уникальной.

Если это не так, то создание объекта-оболочки - ваш лучший вариант.Вам необходимо определить объект, который переопределяет метод equals () и hashCode ().

В качестве грубого примера

class CombinedKey{
    private MyClass object1; 
    private MyClass object2;

    public CombinedKey( MyClass object1, MyClass object2 ){
        this.object1 = object1;
        this.object2 = object2;
    }
    public int hashCode(){ 
        return object1.hashCode() + object2.hashCode();
    }

    @Override
    public Boolean equals( Object otherObject ){
        if( otherObject == null || otherObject.getObject1() == null ) return false;
        return object1.equals( otherObject.getObject1() ) && object2.equals( otherObject.getObject2();
    }

    public MyClass getObject1() { return object1; }
    public MyClass getObject2() { return object2; }

}

(Вы также можете рассмотреть возможность использования Generics для определения этогокласс, поэтому его можно использовать в других сценариях)

Использование:

Map<CombinedKey, Object> myMap = new HashMap<CombinedKey, Object>();
myMap.put( new CombinedKey(obj1, obj2), value );
1 голос
/ 14 февраля 2011

Еще не видел ответа Google Guava , поэтому подумал, что укажу на него: я бы использовал Таблица .

0 голосов
/ 14 февраля 2011

Хорошей альтернативой использованию CompositKey / Pair / Tuple является использование List. List реализации уже имеют правильно определенные equals() и hashCode() и их легко создать с помощью Arrays.asList()

0 голосов
/ 14 февраля 2011

Обычно используется HashMap, суть в том, что вы должны определить (переопределить) равно () и hashCode () в классе Key.

...