android/guava/src/com/google/common/hash/BloomFilter.java
public static <T> BloomFilter<T> readFrom(InputStream in, Funnel<? super T> funnel)
      throws IOException {
    checkNotNull(in, "InputStream");
    checkNotNull(funnel, "Funnel");
    int strategyOrdinal = -1;
    int numHashFunctions = -1;
    int dataLength = -1;
    try {
      DataInputStream din = new DataInputStream(in);
      // currently this assumes there is no negative ordinal; will have to be updated if we
      // add non-stateless strategies (for which we've reserved negative ordinals; see
      // Strategy.ordinal()).
      strategyOrdinal = din.readByte();
      numHashFunctions = UnsignedBytes.toInt(din.readByte());
      dataLength = din.readInt();

      Strategy strategy = BloomFilterStrategies.values()[strategyOrdinal];
      long[] data = new long[dataLength];
      for (int i = 0; i < data.length; i++) {
        data[i] = din.readLong();
      }
      return new BloomFilter<T>(new LockFreeBitArray(data), numHashFunctions, funnel, strategy);
    } catch (RuntimeException e) {
      String message =
          "Unable to deserialize BloomFilter from InputStream."
              + " strategyOrdinal: "
              + strategyOrdinal
              + " numHashFunctions: "
              + numHashFunctions
              + " dataLength: "
              + dataLength;
      throw new IOException(message, e);
    }
  }
public static <T> BloomFilter<T> readFrom(InputStream in, Funnel<? super T> funnel)
      throws IOException {
    checkNotNull(in, "InputStream");
    checkNotNull(funnel, "Funnel");
    int strategyOrdinal = -1;
    int numHashFunctions = -1;
    int dataLength = -1;
    try {
      DataInputStream din = new DataInputStream(in);
      // currently this assumes there is no negative ordinal; will have to be updated if we
      // add non-stateless strategies (for which we've reserved negative ordinals; see
      // Strategy.ordinal()).
      strategyOrdinal = din.readByte();
      numHashFunctions = UnsignedBytes.toInt(din.readByte());
      dataLength = din.readInt();

      Strategy strategy = BloomFilterStrategies.values()[strategyOrdinal];
      long[] data = new long[dataLength];
      for (int i = 0; i < data.length; i++) {
        data[i] = din.readLong();
      }
      return new BloomFilter<T>(new LockFreeBitArray(data), numHashFunctions, funnel, strategy);
    } catch (RuntimeException e) {
      String message =
          "Unable to deserialize BloomFilter from InputStream."
              + " strategyOrdinal: "
              + strategyOrdinal
              + " numHashFunctions: "
              + numHashFunctions
              + " dataLength: "
              + dataLength;
      throw new IOException(message, e);
    }
  }
Reads a byte stream, which was written by {@linkplain #writeTo(OutputStream)}, into a {@code
BloomFilter}.

<p>The {@code Funnel} to be used is not encoded in the stream, so it must be provided here.
<b>Warning:</b> the funnel provided <b>must</b> behave identically to the one used to populate
the original Bloom filter!

@throws IOException if the InputStream throws an {@code IOException}, or if its data does not
appear to be a BloomFilter serialized using the {@linkplain #writeTo(OutputStream)} method.