使用varargs方法,是否可以确定是否应在线传递对象



我专门使用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());

只是想知道是否有一个较短的在线方式来确定参数。

否,没有语法可以根据运行时条件更改varargs数组的长度。如果数组的长度仅在运行时确定,则必须作为单个数组参数将其传递(例如您的filteredList.toArray()示例(。

参考:Java语言规范15.12.4.2说:

如果m k≠n 实际参数表达式调用[...]> n-1 ,e n ,...,e k (被评估为(e 1 ,...,e n-1 new |T[]| {e n ,...,e k }(,其中 |T[]|表示 T[]的擦除(§4.6(。

现在评估参数表达式(可能如上所述(以产生参数值。每个参数值完全对应于该方法的 n 形式参数之一。

在您的情况下,这意味着,如果您在函数调用中有五个实际参数表达式,则该函数将始终接收一个恰好有五个元素的Object[]数组。您不能再有更多或更少的:数组中的元素数量是在编译时确定的。

我认为您可以创建某种类型的辅助方法来返回需要传递的实际内容。

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;
    }
}

最新更新