0

I am developing a plugin that will store clans (Clan class objects) in a hashmap to be used during operation. The hasmap will be stored in a file (serializing the hashmap as a whole would be ideal but I'm not sure if that is possible) for later and be reloaded.

How should I go about saving the objects? Can I serialize the entire hashmap? Thanks in advance; I'm new to hashmaps :P

TheNickmaster21
  • 275
  • 3
  • 13
  • 1
    Why exactly do you want to store clans in a hashmap? Is there a reason a list/array would not suffice? or a HashSet? – Porkbutts Apr 01 '13 at 22:10
  • Arrays use integers as a key and I want to be able to use the Clan's name as a key. If you could do this with a list that would work just fine. – TheNickmaster21 Apr 01 '13 at 22:12

4 Answers4

2

A HashMap itself implements Serializable so you could serialize the entire HashMap if both keys and values are serializable. First you have to decide what key to use. The key can be any object, but must implement both equals(..) and hashCode() methods so that the key can be identified in the HashMap.

In, your case, you could probably use a Clan name as the key represented as a String object. Also, the Clan should be implement Serializable (or Externalizable).

public class Clan 
    implements Serializable 
{
    ...
}

Creating the HashMap as follows (using Java 1.5 or greater):

Map<String, Clan> clans = new HashMap<String, Clan>();

Serialize it to file like this:

FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(clans);

oos.close();

Deserialize it with ObjectInputStream. The Java serialization process is pretty slow so if speed is an issue, you should check out alternative serialization techniques. Kryo is a pretty simple and fast serialization library (https://code.google.com/p/kryo/).

Sten Roger Sandvik
  • 2,526
  • 2
  • 19
  • 16
  • Speed shouldn't be an issue because the serialization and deserialization occur when the plugin first starts up and is closed down. Thanks for another good explanation :) – TheNickmaster21 Apr 01 '13 at 22:24
  • Alright, but if you want a slightly better speed you could also implement Externalizable for your value object. When doing this, you have complete control over how to serialize/deserialize your value objects. – Sten Roger Sandvik Apr 01 '13 at 22:36
1

Yes, you can serialize HashMap objects since the class already implements the Serializable interface. From the HashMap documentation:

public class HashMap extends AbstractMap implements Map, Cloneable, Serializable

Note that your Clan class must implement the Serializable interface in order to be serialized as well. If you're going to use the Clan class as key in your map, it must override the hashCode and equals methods.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • "override the hashCode and equals methods" Why? Also, I am assuming the objects themselves are stored in the hashmap and not just a reference to them; is that correct? – TheNickmaster21 Apr 01 '13 at 22:11
  • 1
    @TheNickmaster21 sorry, I typed to fast. I've updated my answer. – Luiggi Mendoza Apr 01 '13 at 22:13
  • 1
    If you are using a `string` for the key, you won't have to override hashCode, since string already has its own hashcode implementation. – Porkbutts Apr 01 '13 at 22:14
  • Ah, okay. I am using a string as the key (The clans name). – TheNickmaster21 Apr 01 '13 at 22:15
  • @TheNickmaster21 The reference will be stored in the hashmap. Since you are working in java, you will always have a reference to the object. Not sure why this would impact your decision though. – Porkbutts Apr 01 '13 at 22:16
  • @Porkbutts primitives don't go in `Map`s so in this case no exceptions. – Boris the Spider Apr 01 '13 at 22:17
  • @bmorris591 You're right. I forgot about Java's need for wrapper classes, since I have been working with C# for a while now. – Porkbutts Apr 01 '13 at 22:19
  • @Porkbutts How would I go about retrieving the objects then? I need to save them and the Hashmap. If only a reference is saved what is the use of storing them in a Hashmap? – TheNickmaster21 Apr 01 '13 at 22:27
  • 2
    @TheNickmaster21 when serializing you don't serialize the references, you serialize **the data**. So, you move the file to another JVM and deserialize it, and it will deserialize the data with new references. AFAIK no language will store the memory references of the objects (because it will be a very bad design). – Luiggi Mendoza Apr 01 '13 at 22:30
  • @Luiggi Mendoza How would I do that? Is the data automatically serialized with the hashmap? – TheNickmaster21 Apr 01 '13 at 22:34
  • 1
    @TheNickmaster21 yes it is. You should not worry about it. – Luiggi Mendoza Apr 01 '13 at 22:34
1

Sure you can, because HashMap is serializable. Do not forgot make Clan serializable also

Write to file:

FileOutputStream fos = new FileOutputStream("clans");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(clans);
oos.close();

Read from file:

FileInputStream fis = new FileInputStream("clans");
ObjectInputStream ois = new ObjectInputStream(fis);
HashMap<String, Clan> clans = (HashMap) ois.readObject();
ois.close();
mishadoff
  • 10,719
  • 2
  • 33
  • 55
1

You can easily use Java's built in serialization as long as all the items in the map implement Serializable, here's a quick example:

public static void main(String[] args) throws IOException, ClassNotFoundException {
    final Map<Serializable, Serializable> myMap = new HashMap<>();
    final File myFile = new File("/path/to/file");
    try (final ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(myFile))) {
        oos.writeObject(myMap);
    }
    final Map<Serializable, Serializable> myReadMap;
    try (final ObjectInputStream ois = new ObjectInputStream(new FileInputStream(myFile))) {
        myReadMap = (Map<Serializable, Serializable>) ois.readObject();
    }
}

The Map myMap, which contains Serializable keys and values, is saved to a file and then read from the file as myReadMap.

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166