I am working with the Apache Commons CSV library specifically, but this is a more general question.
Is it possible to skip an argument based on a condition when calling a varargs method?
Consider the following example:
class Test {
public static void main(String[] args) {
String str1 = "One";
String str2 = "Two";
String str3 = "Three";
String str4 = "Four";
String str5 = "Five";
boolean excludeOne = false;
boolean excludeTwo = false;
boolean excludeThree = true;
boolean excludeFour = false;
boolean excludeFive = false;
print(
str1,
str2,
str3, // Can I skip this argument if excludeThree = true?
str4,
str5
);
}
private static void print(Object... items) {
for (Object item : items) {
System.out.println(item);
}
}
}
My Use Case: I am working to export a TableView
to CSV, but depending on certain factors, one of more columns may or may not need to be included in that output. So I need a way to determine, at runtime, if that column should be included when calling the CSVPrinter.printRecord(Object... values)
method.
I know I could build a list of valid items first and pass that to the method:
List<String> filteredList = new ArrayList<>();
if (!excludeOne) filteredList.add(str1);
if (!excludeTwo) filteredList.add(str2);
if (!excludeThree) filteredList.add(str3);
if (!excludeFour) filteredList.add(str4);
if (!excludeFive) filteredList.add(str5);
print(filteredList.toArray());
Just wondering if there is a shorter, in-line way of determining the arguments.
No, there is no syntax to change the length of a varargs array based on a runtime condition. If the length of the array is only determined at runtime, it must be passed as a single array argument (like your filteredList.toArray()
example).
Reference: Java Language Specification 15.12.4.2 says:
If
m
is being invoked with k ≠ n actual argument expressions [...], then the argument list (e1, ..., en-1, en, ..., ek) is evaluated as if it were written as (e1, ..., en-1,new |T[]|
{ en, ..., ek }), where|T[]|
denotes the erasure (§4.6) ofT[]
.The argument expressions (possibly rewritten as described above) are now evaluated to yield argument values. Each argument value corresponds to exactly one of the method's n formal parameters.
In your case, this means that if you have five actual argument expressions in your function call, the function will always receive an Object[]
array with exactly five elements. You can't have any more or any less: the number of elements in the array is determined at compile time.