Java 使用varargs方法,是否可以确定是否应该内联传递对象?
我专门与图书馆合作,但这是一个更一般的问题 调用varargs方法时是否可以跳过基于条件的参数 考虑以下示例:Java 使用varargs方法,是否可以确定是否应该内联传递对象?,java,Java,我专门与图书馆合作,但这是一个更一般的问题 调用varargs方法时是否可以跳过基于条件的参数 考虑以下示例: class Test { public static void main(String[] args) { String str1 = "One"; String str2 = "Two"; String str3 = "Three"; String str4 = "Four"; String s
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.printRecordObject时是否应该包括该列。。。值方法
我知道我可以先建立一个有效项列表,然后将其传递给方法:
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());
只是想知道是否有一种更短、更直接的方法来确定参数。不,没有语法可以根据运行时条件更改varargs数组的长度。如果数组的长度仅在运行时确定,则必须像filteredList.toArray示例一样将其作为单个数组参数传递 参考:上面写着: 如果用k调用m≠ n实际参数表达式[…],然后参数列表e1,…,en-1,en,…,ek被计算为好像它被写为e1,…,en-1,new | T[]{en,…,ek},其中| T[]|表示T[]的删除§4.6 现在对可能如上所述重写的参数表达式求值,以生成参数值。每个参数值恰好对应于方法的n个形式参数中的一个
在您的例子中,这意味着如果在函数调用中有五个实际参数表达式,则函数将始终接收正好包含五个元素的Object[]数组。数组中的元素数在编译时确定。我认为您可以创建某种类型的helper方法来返回需要传递的实际内容
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);
}
}
}
这是一个接受对象的版本
我会做的就是建立一个阵列。或者,我可能根本不使用varargs,而是使用生成器模式。@DanielPryden-我正在使用的库使用varargs作为其方法。您可以执行printexcludeOne吗?:str1等?然后对于对象项:items{if!item.isEmpty{System.out.printlnitem;}}}@Sedrick-这将不太有效,因为它仍然是一个值,尽管是一个空值。所以在我的例子中,它仍然会打印一个空行。更糟糕的是,在我的实际应用程序中,我需要传递null,而这也不是我想要的。@Sedrick-我不能,因为该方法来自第三方库:这个方法非常特定于字符串数据,但我的问题实际上更一般。也许我应该在我的示例中使用更复杂的数据模型。这不适用于我需要确定是否包含特定属性的复杂对象。不过,我确实认为我需要重新考虑我的整个方法,因为我的最终目标只是能够将TableView输出到CSV,而我还没有找到任何通用的、可重用的方法。True@Zephyr。我更多的是想提出一些想法。我会更新答案。
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;
}
}