Implementation:Apache Paimon StringUtils
| Knowledge Sources | |
|---|---|
| Domains | Utilities, String Operations |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
StringUtils provides comprehensive string utility methods including emptiness checks, encoding, random generation, splitting, joining, replacement, quoting, case conversion, numeric detection, and truncated collection formatting.
Description
StringUtils is a widely-used utility class throughout Paimon that reduces external library dependencies while providing essential string operations. The class offers null-safe methods for common operations: isNullOrWhitespaceOnly() checks for empty or whitespace-only strings, isEmpty() and isNotEmpty() provide quick null-or-empty checks, and isNumeric() validates numeric strings including negative numbers.
For encoding and conversion, the class provides byteToHexString() for hexadecimal encoding, bytesToBinaryString() for binary representation, and getRandomString() methods for generating test data. The split() method offers optimized string splitting with special handling for single-character separators and whitespace, while join() efficiently combines iterables with separators.
The replace() method provides controlled string replacement with a maximum occurrence limit, and repeat() uses an efficient doubling algorithm for string repetition. For SQL identifier handling, quote() wraps strings in backticks. The truncatedString() method is particularly useful for logging and debugging, displaying large collections with a configurable limit (default 25 fields) and showing truncation information.
Usage
Use StringUtils for string manipulation in schema validation, configuration parsing, SQL generation, logging, and display formatting. The class is designed for high-performance scenarios with optimized implementations for common operations.
Code Reference
Source Location
- Repository: Apache_Paimon
- File: paimon-api/src/main/java/org/apache/paimon/utils/StringUtils.java
- Lines: 33-611
Signature
public class StringUtils {
public static final String EMPTY = "";
public static final int INDEX_NOT_FOUND = -1;
public static final int DEFAULT_MAX_FIELDS = 25;
// Validation
public static boolean isNullOrWhitespaceOnly(String str);
public static boolean isEmpty(CharSequence cs);
public static boolean isNotEmpty(CharSequence cs);
public static boolean isNumeric(CharSequence cs);
// Encoding
public static String byteToHexString(byte[] bytes);
public static String byteToHexString(byte[] bytes, int start, int end);
public static String bytesToBinaryString(byte[] bytes);
// Generation
public static String getRandomString(Random rnd, int minLength, int maxLength);
public static String getRandomString(Random rnd, int minLength, int maxLength,
char minValue, char maxValue);
public static String randomNumericString(int len);
// Manipulation
public static String repeat(String string, int count);
public static String replace(String text, String searchString, String replacement);
public static String[] split(String str, String separatorChars);
public static String join(Iterable<?> iterable, String separator);
// Formatting
public static String quote(String str);
public static String trim(String value);
public static String toUpperCase(String value);
public static String toLowerCase(String value);
public static String truncatedString(Collection<?> lst, String start,
String sep, String end, int maxFields);
}
Import
import org.apache.paimon.utils.StringUtils;
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| str | String | yes | String to process or validate |
| bytes | byte[] | yes | Byte array to encode |
| searchString | String | yes | Substring to find for replacement |
| replacement | String | yes | Replacement text |
| separatorChars | String | no | Separator characters for splitting |
| iterable | Iterable<?> | yes | Elements to join |
| separator | String | no | Separator for joining |
Outputs
| Name | Type | Description |
|---|---|---|
| result | boolean | Validation result (for check methods) |
| processed | String | Processed string result |
| array | String[] | Split string array |
Usage Examples
String Validation
// Check for null or whitespace
boolean isEmpty = StringUtils.isNullOrWhitespaceOnly(" "); // true
boolean hasContent = StringUtils.isNullOrWhitespaceOnly("hello"); // false
// Check for empty
boolean empty1 = StringUtils.isEmpty(null); // true
boolean empty2 = StringUtils.isEmpty(""); // true
boolean empty3 = StringUtils.isEmpty(" "); // false (has spaces)
// Check for not empty
boolean notEmpty = StringUtils.isNotEmpty("text"); // true
// Validate numeric strings
boolean isNum1 = StringUtils.isNumeric("12345"); // true
boolean isNum2 = StringUtils.isNumeric("-123"); // true
boolean isNum3 = StringUtils.isNumeric("12.34"); // false
boolean isNum4 = StringUtils.isNumeric("abc"); // false
Byte Encoding
// Convert bytes to hex string
byte[] data = {0x01, 0x0F, (byte) 0xFF, 0x00};
String hex = StringUtils.byteToHexString(data);
// Returns: "010fff00"
// Convert partial byte array
String partialHex = StringUtils.byteToHexString(data, 1, 3);
// Returns: "0fff"
// Convert to binary string
byte[] binaryData = {0x05, 0x03};
String binary = StringUtils.bytesToBinaryString(binaryData);
// Returns: "0000010100000011"
Random String Generation
Random rnd = new Random();
// Generate random string with length 5-10
String random1 = StringUtils.getRandomString(rnd, 5, 10);
// Generate with specific character range (lowercase letters)
String random2 = StringUtils.getRandomString(rnd, 8, 12, 'a', 'z');
// Generate numeric string
String numericStr = StringUtils.randomNumericString(6);
// Example: "834729"
String Splitting
// Split by delimiter
String csv = "field1,field2,field3";
String[] parts = StringUtils.split(csv, ",");
// Returns: ["field1", "field2", "field3"]
// Split by whitespace (null separator)
String text = "hello world test";
String[] words = StringUtils.split(text, null);
// Returns: ["hello", "world", "test"]
// Split with single character (optimized)
String path = "a/b/c/d";
String[] segments = StringUtils.split(path, "/");
// Returns: ["a", "b", "c", "d"]
String Joining
// Join collection with separator
List<String> fields = Arrays.asList("id", "name", "age");
String joined = StringUtils.join(fields, ", ");
// Returns: "id, name, age"
// Join with null separator (concatenation)
List<Integer> numbers = Arrays.asList(1, 2, 3);
String concatenated = StringUtils.join(numbers, null);
// Returns: "123"
// Join empty collection
String empty = StringUtils.join(Collections.emptyList(), ", ");
// Returns: ""
String Replacement
// Replace all occurrences
String text = "hello world, hello universe";
String replaced = StringUtils.replace(text, "hello", "hi");
// Returns: "hi world, hi universe"
// Replace with maximum count
String limited = StringUtils.replace(text, "hello", "hi", 1);
// Returns: "hi world, hello universe"
// Replace with empty string (removal)
String removed = StringUtils.replace("a-b-c", "-", "");
// Returns: "abc"
String Repetition
// Repeat string
String repeated = StringUtils.repeat("ab", 3);
// Returns: "ababab"
// Create separator line
String line = StringUtils.repeat("-", 50);
// Returns: "--------------------------------------------------"
// Repeat once (returns original)
String once = StringUtils.repeat("text", 1);
// Returns: "text"
// Repeat zero times (returns empty)
String zero = StringUtils.repeat("text", 0);
// Returns: ""
Case Conversion and Trimming
// Null-safe trim
String trimmed = StringUtils.trim(" text "); // "text"
String nullTrim = StringUtils.trim(null); // null
// Null-safe case conversion
String upper = StringUtils.toUpperCase("hello"); // "HELLO"
String lower = StringUtils.toLowerCase("WORLD"); // "world"
String nullUpper = StringUtils.toUpperCase(null); // null
// Conditional case conversion
String result = StringUtils.toLowerCaseIfNeed("Field", false); // "field"
String kept = StringUtils.toLowerCaseIfNeed("Field", true); // "Field"
SQL Identifier Quoting
// Quote identifier for SQL
String quoted = StringUtils.quote("column_name");
// Returns: "`column_name`"
// Use in SQL generation
String sql = "SELECT " + StringUtils.quote("user.id") +
" FROM " + StringUtils.quote("user_table");
// Returns: "SELECT `user.id` FROM `user_table`"
Truncated Collection Display
// Display large collection with default limit (25 fields)
List<String> largeList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
largeList.add("field" + i);
}
String display = StringUtils.truncatedString(largeList, "[", ", ", "]");
// Returns: "[field0, field1, ..., field23, ... 76 more fields]"
// Custom max fields
String custom = StringUtils.truncatedString(largeList, "{", "; ", "}", 5);
// Returns: "{field0; field1; field2; field3; ... 96 more fields}"
// Small collection (no truncation)
List<String> smallList = Arrays.asList("a", "b", "c");
String full = StringUtils.truncatedString(smallList, "[", ", ", "]");
// Returns: "[a, b, c]"
Bracket Detection
// Check for opening brackets
boolean isOpen1 = StringUtils.isOpenBracket('['); // true
boolean isOpen2 = StringUtils.isOpenBracket('{'); // true
boolean isOpen3 = StringUtils.isOpenBracket('('); // true
boolean isOpen4 = StringUtils.isOpenBracket('a'); // false
// Check for closing brackets
boolean isClose1 = StringUtils.isCloseBracket(']'); // true
boolean isClose2 = StringUtils.isCloseBracket('}'); // true
boolean isClose3 = StringUtils.isCloseBracket(')'); // true
boolean isClose4 = StringUtils.isCloseBracket('a'); // false
Schema Validation Example
// Validate field names in schema
public void validateFieldNames(List<String> fieldNames) {
for (String name : fieldNames) {
if (StringUtils.isNullOrWhitespaceOnly(name)) {
throw new IllegalArgumentException(
"Field name must contain at least one non-whitespace character"
);
}
}
}
// Generate field list display
public String getFieldListDisplay(List<DataField> fields) {
List<String> fieldNames = fields.stream()
.map(DataField::name)
.collect(Collectors.toList());
return StringUtils.truncatedString(
fieldNames,
"Fields: [",
", ",
"]",
StringUtils.DEFAULT_MAX_FIELDS
);
}