I found that stringtohashbucketop and stringtokeyedhashbucketop only deal with value override without hash collision handling. Why?
//tensorflow/tensorflow/core/kernels/string_to_hash_bucket_fast_op.h
    typedef decltype(input_flat.size()) Index;
    for (Index i = 0; i < input_flat.size(); ++i) {
      const uint64 input_hash = hash(input_flat(i));
      const uint64 bucket_id = input_hash % num_buckets_;
      // value override without hash collision handling
      output_flat(i) = static_cast<int64>(bucket_id);
    }

//tensorflow/tensorflow/core/kernels/string_to_hash_bucket_op.h
    typedef decltype(input_flat.size()) Index;
    for (Index i = 0; i < input_flat.size(); ++i) {
      const uint64 input_hash = hash(input_flat(i));
      const uint64 bucket_id = input_hash % num_buckets_;
      // value override without hash collision handling
      output_flat(i) = static_cast<int64>(bucket_id);
    }