【问题标题】:Generate unique random zip codes with Java Faker使用 Java Faker 生成唯一的随机邮政编码
【发布时间】:2021-02-26 15:08:15
【问题描述】:

我正在使用Java Faker 并希望生成一系列唯一的随机邮政编码。 Python 和 Ruby 支持 unique 关键字。但我不知道如何在 Java 中完成这项工作。是否支持此功能?

这是 Java 代码:

// Not guaranteed to be unique
String zipCode = faker.address().zipCode()

Python example:

import faker
fake = faker.Faker()
number = fake.unique.random_int()

Ruby example:

# This will return a unique name every time it is called
Faker::Name.unique.name

【问题讨论】:

    标签: java faker


    【解决方案1】:

    使用Stream.generate() 是产生价值的好方法。要使用它,请定义一个将提供源值的Supplier lambda。在这种情况下,邮政编码。

    var zipCodesStream = Stream.generate(() -> faker.address().zipCode());
    

    使用distinct() 使值唯一。

    var zipCodesStream = Stream.generate(() -> faker.address().zipCode())
            .distinct();
    

    可以使用limit 抓取任意数量的值。

    var zipCodes = zipCodesStream
        .limit(10_000)
        .collect(Collectors.toList());
    

    请务必使用limit,否则它永远不会停止收集。另请注意,如果源没有足够的不同值,则进程将挂起!

    如需更强大的实现,请参阅Kotlin's Sequences


    完整(jdk11)示例:

    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");
      }
    
    }
    
    

    输出:

    Generated 10000 distinct zip codes in 387ms
    

    【讨论】:

    • 非常优雅的解决方案!我更喜欢使用内置库而不是自定义方法。我正在开发的功能已经完成,但是当我有时间时,我会重新审视并配备此解决方案。如果一切顺利,我会改变答案。谢谢!
    【解决方案2】:

    查看源代码(您链接到的),看起来 Java 实现不支持 unique,因此您需要自己维护它。 java.util.Set<String> 很容易:

    Set<String> zipCodes = new Set<>();
    ...
    String zipCode;
    do {
        zipCode = faker.address().zipCode();
    } while (zipCodes.contains(zipCode));
    zipCodes.add(zipCode);
    ...
    

    这可能比原生实现慢 - 或者不会 - 但它会给你你所需要的。

    【讨论】:

    • 感谢您的快速回答!只要唯一邮政编码列表很快(或根本没有)收敛,此解决方案就可以工作,否则我还需要实现UniquenessException(python)或RetryLimitExceeded(ruby)的等效项,这不应该太难了。
    • @Absolutely。我不知道您需要多少个唯一的邮政编码。如果集合足够大,您可能会想到完全不同的实现。
    • 好点,我从未指定。我需要 1k-10k 范围内的东西,所以这应该不是问题,因为生成的一些邮政编码使用 ZIP+4 格式,导致池更大,因此碰撞更少。
    猜你喜欢
    • 1970-01-01
    • 2016-03-19
    • 2014-09-17
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    相关资源
    最近更新 更多