Datafaker 簡介
一、概述
在本教程中,我們將學習如何解決為不同目的生成模擬數據的問題。我們將學習如何使用Datafaker並查看幾個示例。
2. 歷史
Datafaker 是Javafaker的現代分支。它被轉移到 Java 8 並進行了改進,提高了庫的性能。但是,當前的 API 或多或少保持不變。因此,以前使用的 Javafaker 遷移到 Datafaker 不會有任何問題。 Java Faker 文章中提供的所有示例都適用於1.6.0
版本的 Datafaker。
The
Datafaker API 與 Javafaker 兼容。因此,本文將只關注差異和改進。
首先,讓我們在項目中添加[datafaker](https://search.maven.org/search?q=g:net.datafaker%20AND%20a:datafaker%20AND%20v:1.6.0)
Maven 依賴項:
<dependency>
<groupId>net.datafaker</groupId>
<artifactId>datafaker</artifactId>
<version>1.6.0</version>
</dependency>
3. 提供者
Datafaker 最重要的部分之一是提供者。這是一組使數據生成更加方便的特殊類。重要的是要注意這些類由具有正確數據的yml
文件備份。 Faker
方法和表達式直接或間接使用這些文件來生成數據。在接下來的部分中,我們將更加熟悉這些方法和指令的工作。
4. 數據生成的其他模式
Datafaker 和 Javafaker 支持基於提供的模式生成值。 Datafaker 引入了帶有templatify, exemplify, options, date, csv, and json
指令的附加功能.
4.1。模板化
templatify
指令有幾個參數。第一個是基礎 S tring
。第二個是將在給定字符串中替換的字符。其餘是隨機選擇的替換選項:
public class Templatify {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("Expression: " + getExpression());
System.out.println("Expression with a placeholder: " + getExpressionWithPlaceholder());
}
static String getExpression() {
return faker.expression("#{templatify 'test','t','j','r'}");
}
static String getExpressionWithPlaceholder() {
return faker.expression("#{templatify '#ight', '#', 'f', 'l', 'm', 'n'}");
}
}
儘管我們可以使用不帶佔位符的基本字符串,但它可能會產生不良結果,因為它將替換給定字符串中的所有出現。我們可以引入一個佔位符,一個只出現在基本字符串特定位置的字符。在上述情況下,結果是:
Expression: resj
Expression with a placeholder: night
如果有多個位置可以放置隨機字符,則每次都會隨機。可以使用字符串進行替換,但文檔沒有明確提及這一點。因此最好謹慎使用。
4.2.舉例
該指令根據提供的示例生成一個隨機值。它將用尊重的值替換小寫或大寫字符。數字也是如此。特殊字符未被觸及,這有助於創建格式化字符串:
public class Examplify {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("Expression: " + getExpression());
System.out.println("Number expression: " + getNumberExpression());
}
static String getExpression() {
return faker.expression("#{examplify 'Cat in the Hat'}");
}
static String getNumberExpression() {
return faker.expression("#{examplify '123-123-123'}");
}
}
輸出示例:
Expression: Lvo lw ero Qkd
Number expression: 707-657-434
4.3.正則表達式
這是一種更靈活的創建格式化 S tring
值的方法。我們可以使用regexify
指令作為表達式,或者直接在Faker
對像上調用regexify
方法:
public class Regexify {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("Expression: " + getExpression());
System.out.println("Regexify with a method: " + getMethodExpression());
}
static String getExpression() {
return faker.expression("#{regexify '(hello|bye|hey)'}");
}
static String getMethodExpression() {
return faker.regexify("[AD]{4,10}");
}
}
可能的輸出:
Expression: bye
Regexify with a method: DCCC
4.4.選項
options.option
指令允許從提供的列表中隨機選擇一個選項。此功能可以通過regexify
實現,但通常情況下,單獨的指令是有意義的:
public class Option {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("First expression: " + getFirstExpression());
System.out.println("Second expression: " + getSecondExpression());
System.out.println("Third expression: " + getThirdExpression());
}
static String getFirstExpression() {
return faker.expression("#{options.option 'Hi','Hello','Hey'}");
}
static String getSecondExpression() {
return faker.expression("#{options.option '1','2','3','4','*'}");
}
static String getThirdExpression() {
return faker.expression("#{regexify '(Hi|Hello|Hey)'}");
}
}
上面代碼的輸出:
First expression: Hey
Second expression: 4
Third expression: Hello
如果選項的數量太大,為隨機值創建自定義提供程序是有意義的。
4.5. CSV
該指令根據其名稱創建 CSV 格式的數據。但是,使用此指令可能會造成混淆。因為,在底層,兩個具有完全不同簽名的重載方法處理這個指令:
public class Csv {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("First expression:\n" + getFirstExpression());
System.out.println("Second expression:\n" + getSecondExpression());
}
static String getFirstExpression() {
String firstExpressionString
= "#{csv '4','name_column','#{Name.first_name}','last_name_column','#{Name.last_name}'}";
return faker.expression(firstExpressionString);
}
static String getSecondExpression() {
String secondExpressionString
= "#{csv ',','\"','true','4','name_column','#{Name.first_name}','last_name_column','#{Name.last_name}'}";
return faker.expression(secondExpressionString);
}
}
上面的指令使用表達式#{Name.first_name}
和#{Name.last_name}
。下一節將解釋這些表達式的用法。
表達式中csv
指令之後的值映射到上述方法的參數。這些方法的文檔提供了附加信息。但是,有時解析這些指令可能會出現問題,在這種情況下,最好直接使用這些方法。上面的代碼將產生以下輸出:
First expression:
"name_column","last_name_column"
"Riley","Spinka"
"Lindsay","O'Conner"
"Sid","Rogahn"
"Prince","Wiegand"
Second expression:
"name_column","last_name_column"
"Jen","Schinner"
"Valeria","Walter"
"Mikki","Effertz"
"Deon","Bergnaum"
這是一種以編程方式生成模擬數據以供在應用程序外部使用的好方法。
4.6. JSON
另一種流行且經常使用的格式是 JSON。 Datafaker 允許使用表達式生成 JSON 格式的數據:
public class Json {
private static final Faker faker = new Faker();
public static void main(String[] args) {
System.out.println(getExpression());
}
static String getExpression() {
return faker.expression(
"#{json 'person'," + "'#{json ''first_name'',''#{Name.first_name}'',''last_name'',''#{Name.last_name}''}'," +
"'address'," + "'#{json ''country'',''#{Address.country}'',''city'',''#{Address.city}''}'}");
}
}
上面的代碼產生以下輸出:
{"person": {"first_name": "Dorian", "last_name": "Simonis"}, "address": {"country": "Cameroon", "city": "South Ernestine"}}
4.7.方法調用
**事實上,所有的表達式都只是方法調用,方法名稱和參數作為String.
**因此,上面的所有指令都反映了具有相同名稱的方法。但是,有時使用純文本創建模擬數據更方便:
public class MethodInvocation {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("Name from a method: " + getNameFromMethod());
System.out.println("Name from an expression: " + getNameFromExpression());
}
static String getNameFromMethod() {
return faker.name().firstName();
}
static String getNameFromExpression() {
return faker.expression("#{Name.first_Name}");
}
}
現在很明顯,帶有csv
和json
指令的表達式在內部使用了方法調用。這樣,我們就可以調用任何方法在Faker
對像上生成數據。雖然方法名稱不區分大小寫並且允許格式變化,但最好參考所用版本的文檔來驗證它。
此外,可以將參數傳遞給帶有表達式的方法。我們在regexify
和templatify
指令的格式中部分地看到了這一點。儘管在某些情況下它可能有點麻煩且容易出錯,但有時這是與Faker:
public class MethodInvocationWithParams {
public static int MIN = 1;
public static int MAX = 10;
public static String UNIT = "SECONDS";
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("Duration from the method :" + getDurationFromMethod());
System.out.println("Duration from the expression: " + getDurationFromExpression());
}
static Duration getDurationFromMethod() {
return faker.date().duration(MIN, MAX, UNIT);
}
static String getDurationFromExpression() {
return faker.expression("#{date.duration '1', '10', 'SECONDS'}");
}
}
表達式的缺點之一是它們返回一個String
對象。結果,這減少了我們可以對返回的對象進行的操作數量。上面的代碼產生這個輸出:
Duration from the method: PT6S
Duration from the expression: PT4S
5. 收藏
集合允許使用模擬數據創建列表。在這種情況下,元素可以是不同的類型。集合由最具體的類型參數化:集合中所有類的父類。讓我們稍微了解一下並生成“星球大戰”和“開始迷航”中的角色列表:
public class Collection {
public static int MIN = 1;
public static int MAX = 100;
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println(getFictionalCharacters());
}
static List<String> getFictionalCharacters() {
return faker.collection(
() -> faker.starWars().character(),
() -> faker.starTrek().character())
.len(MIN, MAX)
.generate();
}
}
結果,我們得到了以下列表:
[Luke Skywalker, Wesley Crusher, Jean-Luc Picard, Greedo, Hikaru Sulu, William T. Riker]
**因為我們集合中的兩個供應商都返回 String 類型的值,所以結果列表將由String.
**讓我們檢查一下我們混合不同類型數據的情況:
public class MixedCollection {
public static int MIN = 1;
public static int MAX = 20;
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println(getMixedCollection());
}
static List<? extends Serializable> getMixedCollection() {
return faker.collection(
() -> faker.date().birthday(),
() -> faker.name().fullName())
.len(MIN, MAX)
.generate();
}
}
**在這種情況下,最具體的String
和Timestamp
類是Serializable.
**輸出將如下:
[1964-11-09 15:16:43.0, Devora Stamm DVM, 1980-01-11 15:18:00.0, 1989-04-28 05:13:54.0,
2004-09-06 17:11:49.0, Irving Turcotte, Sherita Durgan I, 2004-03-08 00:45:57.0, 1979-08-25 22:48:50.0,
Manda Hane, Latanya Hegmann, 1991-05-29 12:07:23.0, 1989-06-26 12:40:44.0, Kevin Quigley]
六,結論
Datafaker 是 Javafaker 的一個新的改進版本。本文介紹了 Datafaker 1.6.0,
它提供了生成數據的新方法。不過,關於這個庫還有更多需要了解,最好參考官方文檔和GitHub 存儲庫,以獲取有關 Datafaker 功能和特性的更多信息。
與往常一樣,本文中提供的代碼可在 GitHub 上獲得。