Serialization and Deserialization of Collections in Java – Complete Guide with Examples

Illustration for Serialization and Deserialization of Collections in Java – Complete Guide with Examples
By Last updated:

Serialization is the process of converting an object into a byte stream, while deserialization is the reconstruction of that byte stream into a live object. Java's Serializable interface enables this transformation, and it's especially useful for persisting or transferring data.

In enterprise applications, developers often need to serialize and deserialize complex collections like List, Set, Map, and even nested structures. Understanding how Java handles collection serialization is essential for building reliable, portable, and secure applications.

This tutorial will teach you how to serialize and deserialize Java collections — the right way — with best practices, performance tips, and working examples.


What Is Serialization in Java?

  • Java provides built-in support for object serialization via the java.io.Serializable marker interface.
  • When a class implements Serializable, its objects can be written to or read from a stream.

Key Interfaces and Classes

  • Serializable
  • ObjectOutputStream
  • ObjectInputStream

When and Why to Serialize Collections?

  • Store data between program runs
  • Transmit data over the network
  • Implement caching mechanisms
  • Deep copy collections
  • Log snapshots of application state

Code Example: Serialize and Deserialize a List

Step 1: Make Your Model Class Serializable

import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Step 2: Serialize the List

List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));

try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("people.ser"))) {
    oos.writeObject(people);
} catch (IOException e) {
    e.printStackTrace();
}

Step 3: Deserialize the List

try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("people.ser"))) {
    List<Person> deserialized = (List<Person>) ois.readObject();
    deserialized.forEach(p -> System.out.println(p.name + ", " + p.age));
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

Supported Collections

Collection Type Serializable by Default Notes
ArrayList ✅ Yes Most common list
HashMap ✅ Yes Hash-based maps
HashSet ✅ Yes Backed by HashMap
TreeMap ✅ Yes Sorted
LinkedList ✅ Yes Doubly-linked
Stack ✅ Yes Legacy
Queue ⛔ Depends on impl Use LinkedList or ArrayDeque
ConcurrentHashMap ✅ Yes Thread-safe

Internal Mechanics

  • Every non-transient field must also be Serializable, or you'll get NotSerializableException
  • Transient fields are skipped during serialization
  • Static fields are not serialized

Performance Benchmarks

Metric Value
Speed Moderate (disk I/O involved)
Format Binary
Size Larger than JSON
Portability Java-specific

For cross-platform serialization, consider JSON or Protocol Buffers.


Serialization in Java 8+

Java 8 introduced improvements such as:

  • Better lambdas and functional serialization (though lambdas aren’t serializable by default)
  • Easier data manipulation before/after serialization using Streams
List<Person> filtered = people.stream()
    .filter(p -> p.age > 20)
    .collect(Collectors.toList());

Java Version Tracker

📌 What's New in Java?

  • Java 8
    • Stream APIs for collection filtering before/after serialization
  • Java 9
    • Immutable collections: List.of(), Map.of() — but not serializable
  • Java 10+
    • var for inferred typing simplifies serialization code
  • Java 21
    • Improved performance, record support, GC optimizations help serialization-heavy apps

Best Practices

  • Always declare serialVersionUID explicitly
  • Avoid serializing large or deep object graphs
  • Use transient for fields like logs, threads, connections
  • Use try-with-resources to handle streams properly
  • Validate object state after deserialization if needed

Anti-Patterns

  • Making non-serializable fields like Thread or Socket serializable
  • Relying on default serialization for sensitive data
  • Not handling class versioning with serialVersionUID
  • Serializing lambdas or anonymous classes

Refactoring Legacy Code

  • Add implements Serializable to model classes if needed
  • Migrate from manual file handling to try-with-resources
  • Replace non-serializable collections with standard ones (ArrayList, HashMap)

Real-World Use Cases

  • Java RMI and EJBs – Transmit objects across networked Java apps
  • Android apps – Save app state or preferences
  • Distributed caches – Like Ehcache, Hazelcast
  • Persistent queues – Save and reload task queues between sessions

Conclusion and Key Takeaways

  • Serialization enables storing and transmitting Java objects — including collections
  • Not all collections or elements are serializable — check every object in the chain
  • Prefer serialization for Java-to-Java persistence; use JSON for broader compatibility
  • Understand internal memory layout and compatibility when designing serializable models

FAQ – Serialization and Deserialization of Collections

  1. Is List.of() serializable?
    No. It throws UnsupportedOperationException on deserialization.

  2. Do I need to close ObjectOutputStream?
    Yes — use try-with-resources for safety.

  3. Can I serialize nested objects?
    Yes — all nested objects must also be serializable.

  4. What happens if I change the class after serializing?
    Deserialization fails unless serialVersionUID is consistent.

  5. Is serialization fast?
    No. It's slower than in-memory processing or JSON for large data.

  6. Can I serialize a HashMap with custom key/value types?
    Yes, if both key and value are serializable.

  7. How do I prevent a field from being serialized?
    Mark it as transient.

  8. Can I use serialization across JVM versions?
    It works, but not guaranteed — avoid for long-term storage.

  9. What if a collection has null elements?
    Serialization supports them.

  10. Should I encrypt serialized objects?
    Yes — if security is a concern, wrap streams in CipherOutputStream.