Using Stream.generate() is a great way to generate values. To use it, define a Supplier lambda that will provide the source values. In this case, zip codes.
var zipCodesStream = Stream.generate(() -> faker.address().zipCode());
Use distinct() to make the values unique.
var zipCodesStream = Stream.generate(() -> faker.address().zipCode())
.distinct();
Any number of values can be grabbed using limit.
var zipCodes = zipCodesStream
.limit(10_000)
.collect(Collectors.toList());
Make sure to use limit, or it will never stop collecting. Also be aware that if the source doesn't have enough distinct values then the process will hang!
For an even more powerful implementation, see Kotlin's Sequences.
Full (jdk11) example:
import com.github.javafaker.Faker;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class scratch {
public static void main(String[] args) {
// use a Thread local random, just in case we're multi-threading
var random = ThreadLocalRandom.current();
// use the random in the Faker, for consistency
var faker = Faker.instance(random);
// generate a Stream - the source values are from Faker
var zipCodesStream =
Stream.generate(() -> faker.address().zipCode())
// make the generated values are distinct
.distinct();
var startMillis = System.currentTimeMillis();
// grab 10k values, put them into a list
var zipCodes = zipCodesStream
.limit(10_000)
.collect(Collectors.toList());
var elapsedMillis = System.currentTimeMillis() - startMillis;
// verify the generated values are distinct
assert zipCodes.size() == Set.copyOf(zipCodes).size()
: "Expect zipCodes has no duplicates";
System.out.println("Generated " + zipCodes.size() + " distinct zip codes in "
+ elapsedMillis + "ms");
}
}
Output:
Generated 10000 distinct zip codes in 387ms