Java: параметры переменной длины как список для рекурсии - PullRequest
2 голосов
/ 07 июля 2011

Я бы хотел что-то вроде следующего рекурсивного метода:

private Node getElementRec(Node currentNode, String ... names) {
    if (null == names || names.length == 0)
        return currentNode;
    else {
        Node child = currentNode.getChildWithName(names[0]);
        return getElementRec(child, namesAux.subList(1, names[1,]));
    }
}

Поскольку параметры Java переменной длины (здесь names) являются массивами, я не могу создать что-то вроде names.sublist(1, names.size()) Хотя это было бы довольно неэффективно, я попытался преобразовать массив в список, а затем передать его методу , но не принимает список

Итак, вопрос : возможно ли в Java выполнить рекурсию по параметру переменной длины (Type ... parameter)? Что-то, как я показал, возможно?

Спасибо

Ответы [ 6 ]

5 голосов
/ 07 июля 2011

Вы можете использовать функцию copyOfRange из класса Arrays для передачи в функцию

Arrays.copyOfRange(names, 1, names.length)

Еще один способ избежать копирования - изменить вашу функцию так, чтобы она принимала начальный и конечный индексы:

private Node getElementRec(Node currentNode, int start, int end, String ... names) {
    if (null == names || start >= end || start < 0 || end > names.length)
        return currentNode;
    else {
        Node child = currentNode.getChildWithName(names[start]);
        return getElementRec(child, start+1, end, names);
    }
}
2 голосов
/ 07 июля 2011

Вместо names.size() вы можете использовать names.lengthВараги ... в Java - это массивы, а не векторы, как вы предлагаете.

1 голос
/ 07 июля 2011

пройти указатель

private Node getElementRec(Node currentNode, int i, String ... names) {
    if (null == names || names.length == i)
        return currentNode;
    else {
        Node child = currentNode.getChildWithName(names[i]);
        return getElementRec(child, i+1, names);
    }
}
1 голос
/ 07 июля 2011

String ... names - сокращение от String[] names. Так что вы можете попробовать:

else {
     Node child = currentNode.getChildWithName(names[0]);
     String[] remainingNames = new String[names.length -1];
     System.arrayCopy(names, 1, remainingNames, 0, names.length - 1);
     return getElementRec(child, remainingNames));
 }
0 голосов
/ 07 июля 2011

Прежде всего: переменные параметры арности реализуются с использованием массивов, а не как векторов (вектор обычно означает java.util.Vector в Java, что будет реализацией List, которая будет иметь метод subList()).

Как вы поняли, коллекции (в частности, List объекты) допускают гораздо более богатые взаимодействия, чем простые массивы. К счастью, есть простой способ преобразовать массив в List, используя Arrays.asList().

Я бы реализовал рекурсивный метод, используя List<String> вместо String... и , предоставляя удобный метод, который принимает переменный параметр arity:

private Node getElementRec(Node currentNode, String... names) {
    return getElementRec(currentNode, Arrays.asList(names));
}

private Node getElementRec(Node currentNode, List<String> names) {
    if (null == names || names.isEmpty())
        return currentNode;
    else {
        Node child = currentNode.getChildWithName(names.get(0));
        return getElementRec(child, names.subList(1, names.length()-1));
    }
}
0 голосов
/ 07 июля 2011

Вы можете передать массив вместо vararg:

private Node getElementRec(Node currentNode, String ... names) {
     String slice[] = ..... // Get sub array from names
     ....
     getElementRec(node, slice);
     ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...