strings) {
int size = strings == null ? 0 : strings.size();
return switch (size) {
case 0 -> "";
case 1 -> strings.get(0);
default -> String.join(regularSeparator, strings.subList(0, --size)) + finalSeparator + strings.get(size);
};
}
/**
* Create a {@link String} that repeats the base character n times.
* @param base the base character.
* @param n the number of repetition.
* @return a {@link String} that repeats the base character n times.
*/
public static String repeat(char base, int n) {
char[] chars = new char[n];
Arrays.fill(chars, base);
return String.valueOf(chars);
}
private static final Pattern endingNumber = Pattern.compile("(\\d+)$");
/**
* Generate a name based on the original name, but that does not conflit with anouther one, according to the
* provided predicate.
* It can be used to to add an entry in a map when the key already exists, and it is ok to modify the added key to
* not erase the previous data.
* This situation can be compared to when a file is added to a directory but another file with the same name exists,
* so the new file have a suffix number to make the file name different.
*
* Be aware that this method may run an infinite loop if the predicate continuously returns true.
* @param originalName the original conflicting name.
* @param conflictTester a predicate that test if a generated name stills conflict with a set of name
* @return the original name, with a suffix number (ex: {@code "original1"}).
*/
public static String fixConflictName(String originalName, Predicate conflictTester) {
int suffix = 1;
Matcher endingMatcher = endingNumber.matcher(originalName);
if (endingMatcher.find()) {
suffix = Integer.parseInt(endingMatcher.group(1)) + 1;
originalName = originalName.substring(0, endingMatcher.start());
}
for (;; suffix++) {
String newStr = originalName + suffix;
if (!conflictTester.test(newStr))
return newStr;
}
}
/**
* Wraps the provided {@link UnaryOperator} of integer into an {@link UnaryOperator} of String parsing the input
* string to int and converting back the return value to String.
* @param operator the {@link UnaryOperator} to warp.
* @return an {@link UnaryOperator} of String.
*/
public static UnaryOperator wrapParsingInt(UnaryOperator operator) {
return s -> Integer.toString(operator.apply(Integer.parseInt(s)));
}
/**
* Wraps the provided {@link UnaryOperator} of long into an {@link UnaryOperator} of String parsing the input
* string to long and converting back the return value to String.
* @param operator the {@link UnaryOperator} to warp.
* @return an {@link UnaryOperator} of String.
*/
public static UnaryOperator wrapParsingLong(UnaryOperator operator) {
return s -> Long.toString(operator.apply(Long.parseLong(s)));
}
}