Nikki
Nikki

Reputation: 38

Dictionary of Objects where key is an instance field in Java

I was wondering if it was possible to have a Java dictionary of objects where one of the fields of the object is defined to be the key of the dictionary.

To be more specific, here's what I would like: I have defined a class with three fields. One of these fields is an Integer and is unique to each object. I would like this field to be the key of the dictionary.

Upvotes: 0

Views: 1041

Answers (4)

Jim Garrison
Jim Garrison

Reputation: 86774

If you want to hide the details:

public interface HasOwnKey<K> {
    public K getKey();
}

public class MyMap<K, V extends HasOwnKey<K>> {
{
    private Map<K,V> map = new HashMap<>();
    public V put(V value) {
    {
        return this.map.put(value.getKey(),value);
    }
    public V get(K key) {
        return this.map.get(key)
    }
    ... etc
}

public class MyClass extends HasOwnKey<String> {
    ...
    @Override String getKey() { return this.key; }
}

MyMap<String, MyClass> myMap = new MyMap<>();
MyClass obj = new MyClass();
obj.setKey("abc");
myMap.put(obj);

Unfortunately Java 7 doesn't seem to be smart enough to infer K from a declaration like

public class MyMap<V extends HasOwnKey<K>> {

so you have to provide the Key type in two places and cannot do

MyMap<MyClass> myMap = new MyMap<>();

Upvotes: 1

Stelium
Stelium

Reputation: 1367

If you already have created a List of those objects you can use an aggregate operation in java 8 like this:

Map<Integer, List<MyClass>> theMap = list
                .stream()
                .collect( Collectors.groupingBy(MyClass::myIntegerKey) );

Upvotes: 0

OneMoreError
OneMoreError

Reputation: 7728

You can do that easily as follows :

public class CustomClass 
{
    private int primaryKey;
    private int secondaryField;
    private int tertiaryField;

    public CustomClass(int primaryKey, int secondaryField, int tertiaryField)
    {
        this.primaryKey = primaryKey;
        this.secondaryField = secondaryField;
        this.tertiaryField = tertiaryField;
    }

    public int getPrimaryKey(CustomClass object)
    {
        return object.primaryKey;
    }
}

public class Test 
{
    public static void main(String[] args) 
    {
        CustomClass object = new CustomClass(10, 20, 30);
        Map map = new HashMap<Integer,CustomClass>();
        map.put(object.getPrimaryKey(object), object);
    }
}

You may also want to consider using Enums for doing the same, if the number of such records is fairly less, as they provide more readability.

Upvotes: 0

Eran
Eran

Reputation: 393841

Yes, of course it's possible.

Example :

Map<Integer,MyClass> map = new HashMap<Integer,MyClass>();
MyClass myObject = new MyClass(...);
map.put (myObject.getIntegerKey(), myObject);

Upvotes: 2

Related Questions