private void readObject(java.io.ObjectInputStream s)
      throws java.io.IOException, ClassNotFoundException {
    /*
     * To improve performance in typical cases, we create nodes while reading, then place in table
     * once size is known. However, we must also validate uniqueness and deal with overpopulated
     * bins while doing so, which requires specialized versions of putVal mechanics.
     */
    sizeCtl = -1; // force exclusion for table construction
    s.defaultReadObject();
    long size = 0L;
    Node<V> p = null;
    for (;;) {
      @SuppressWarnings("unchecked")
      V k = (V) s.readObject();
      if (k != null) {
        p = new Node<>(spread(k.hashCode()), k, p);
        ++size;
      } else {
        break;
      }
    }
    if (size == 0L) {
      sizeCtl = 0;
    } else {
      int n;
      if (size >= (long) (MAXIMUM_CAPACITY >>> 1)) {
        n = MAXIMUM_CAPACITY;
      } else {
        int sz = (int) size;
        n = tableSizeFor(sz + (sz >>> 1) + 1);
      }
      @SuppressWarnings("unchecked")
      Node<V>[] tab = (Node<V>[]) new Node<?>[n];
      int mask = n - 1;
      long added = 0L;
      while (p != null) {
        boolean insertAtFront;
        Node<V> next = p.next, first;
        int h = p.hash, j = h & mask;
        if ((first = tabAt(tab, j)) == null) {
          insertAtFront = true;
        } else {
          V k = p.key;
          if (first.hash < 0) {
            TreeBin<V> t = (TreeBin<V>) first;
            if (t.putTreeVal(h, k) == null) {
              ++added;
            }
            insertAtFront = false;
          } else {
            int binCount = 0;
            insertAtFront = true;
            Node<V> q;
            V qk;
            for (q = first; q != null; q = q.next) {
              if (q.hash == h && ((qk = q.key) == k || (qk != null && k.equals(qk)))) {
                insertAtFront = false;
                break;
              }
              ++binCount;
            }
            if (insertAtFront && binCount >= TREEIFY_THRESHOLD) {
              insertAtFront = false;
              ++added;
              p.next = first;
              TreeNode<V> hd = null, tl = null;
              for (q = p; q != null; q = q.next) {
                TreeNode<V> t = new TreeNode<>(q.hash, q.key, null, null);
                if ((t.prev = tl) == null) {
                  hd = t;
                } else {
                  tl.next = t;
                }
                tl = t;
              }
              setTabAt(tab, j, new TreeBin<>(hd));
            }
          }
        }
        if (insertAtFront) {
          ++added;
          p.next = first;
          setTabAt(tab, j, p);
        }
        p = next;
      }
      table = tab;
      sizeCtl = n - (n >>> 2);
      baseCount = added;
    }
  }
Reconstitutes the instance from a stream (that is, deserializes it).

@param s the stream
geode-core/src/main/java/org/apache/geode/internal/concurrent/CompactConcurrentHashSet2.java