code: public long approximateElementCount() {
      long bitSize = bits.bitSize();
      long bitCount = bits.bitCount();
  
      /**
       * Each insertion is expected to reduce the # of clear bits by a factor of
       * `numHashFunctions/bitSize`. So, after n insertions, expected bitCount is `bitSize * (1 - (1 -
       * numHashFunctions/bitSize)^n)`. Solving that for n, and approximating `ln x` as `x - 1` when x
       * is close to 1 (why?), gives the following formula.
       */
      double fractionOfBitsSet = (double) bitCount / bitSize;
      return DoubleMath.roundToLong(
          -Math.log1p(-fractionOfBitsSet) * bitSize / numHashFunctions, RoundingMode.HALF_UP);
    }
docs: Returns an estimate for the total number of distinct elements that have been added to this
  Bloom filter. This approximation is reasonably accurate if it does not exceed the value of
  {@code expectedInsertions} that was used when constructing the filter.
  
  @since 22.0