我专门使用Apache Commons CSV库,但这是一个更笼统的问题。
在调用varargs方法时是否可以基于条件跳过参数?
考虑以下示例:
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);
}
}
}
我的用例:我正在努力将TableView
导出为CSV,但是根据某些因素,该输出中可能包含也可能不需要包含更多列之一。因此,我需要一种在运行时确定在调用CSVPrinter.printRecord(Object... values)
方法时是否应包括该列的方法。
我知道我可以先建立一个有效项目列表,然后将其传递给方法:
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());
只是想知道是否有一种较短的,直接确定参数的在线方法。
答案 0 :(得分:2)
否,没有语法可以根据运行时条件来更改varargs数组的长度。如果仅在运行时确定数组的长度,则必须将其作为单个数组参数传递(例如您的filteredList.toArray()
示例)。
参考:Java Language Specification 15.12.4.2说:
如果正在使用 k≠n 实际参数表达式[...]调用
m
,则参数列表(e 1 ,... ,e n-1 ,e n ,...,e k )的计算方式就像写为(e 1 ,...,e n-1 ,new |T[]|
{e n ,...,e k }),其中|T[]|
表示T[]
的擦除(第4.6节)。现在对参数表达式(可能如上所述进行了重写)求值以产生参数值。每个参数值恰好对应于该方法的 n 形式参数之一。
在您的情况下,这意味着如果函数调用中有五个实际参数表达式,则该函数将始终接收一个正好包含五个元素的Object[]
数组。您不能有更多或更少:数组中的元素数是在编译时确定的。
答案 1 :(得分:2)
我认为您可以创建某种类型的辅助方法来返回需要传递的实际内容。
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(helperMethod(excludeOne ? "" : str1,
excludeTwo ? "" : str2,
excludeThree ? "" : str3, // Can I skip this argument if excludeThree = true?
excludeFour ? "" : str4,
excludeFive ? "" : str5)
);
}
public static Object[] helperMethod(Object... items)
{
List<String> returnItems = new ArrayList();
for (int i = 0; i < items.length; i++) {
if (!items[i].toString().isEmpty()) {
returnItems.add(items[i].toString());
}
}
return returnItems.toArray();
}
private static void print(Object... items)
{
for (Object item : items) {
if (!item.toString().isEmpty()) {
System.out.println(item);
}
}
}
这里是接受对象的版本。
public static void main(String[] args)
{
String str1 = "One";
String str2 = "Two";
String str3 = "Three";
String str4 = "Four";
String str5 = "Five";
TestObject testObject1 = new TestObject("One");
TestObject testObject2 = new TestObject("Two");
TestObject testObject3 = new TestObject("Three");
TestObject testObject4 = new TestObject("Four");
TestObject testObject5 = new TestObject("Five");
boolean excludeOne = false;
boolean excludeTwo = false;
boolean excludeThree = true;
boolean excludeFour = false;
boolean excludeFive = false;
//If this was an Object I would set something like object
print(helperMethod2(excludeOne ? null : testObject1,
excludeTwo ? null : testObject2,
excludeThree ? null : testObject3, // Can I skip this argument if excludeThree = true?
excludeFour ? null : testObject4,
excludeFive ? null : testObject5)
);
}
public static Object[] helperMethod2(Object... items)
{
List<Object> returnItems = new ArrayList();
for (int i = 0; i < items.length; i++) {
if (items[i] != null) {
returnItems.add(items[i]);
}
}
return returnItems.toArray();
}
private static void print(Object... items)
{
for (Object item : items) {
System.out.println(((TestObject) item).getVar());
}
}
public static class TestObject
{
private String var;
public TestObject(String var)
{
this.var = var;
}
public String getVar()
{
return var;
}
public void setVar(String var)
{
this.var = var;
}
}