Является ли создание нового объекта рекурсивно более медленным, чем создание ссылки?


Допустим, у меня есть следующий код:

    public static ArrayList<Integer> doSomething(int n) {

    ArrayList<Integer> list = new ArrayList<Integer>();
    if (n <= 0)
        return list ;
    list = ListMethods.doSomething(n - 1);
    list.add(n);

    return list;

Это медленнее, чем этот код:

    public static ArrayList<Integer> doSomething(int n) {

    ArrayList<Integer> list = null;
    if (n <= 0)
        return list = new ArrayList<Integer>();
    list = ListMethods.doSomething(n - 1);
    list.add(n);

    return list;
Я спрашиваю, потому что один из моих лекторов использует последний код в своих заметках, в то время как я видел, что другие гиды Онлайн используют первый. Это просто личные предпочтения, или есть разница в скорости? Кроме того, если есть разница в скорости, не слишком ли она мала, чтобы беспокоиться?
1 2

1 ответ:

Да, первый код работает медленнее. Для каждого значения n, большего 0, вы получаете первую часть, эквивалентную:

ArrayList<Integer> list = new ArrayList<Integer>();
list = ListMethods.doSomething(n - 1);
Нет смысла создавать новый объект ArrayList и сразу же присваивать ему другое значение.

Второй код лучше, но все еще может быть значительно улучшен с точки зрения читаемости:

public static ArrayList<Integer> doSomething(int n) {
    if (n <= 0) {
        return new ArrayList<Integer>();
    }
    ArrayList<Integer> list = doSomething(n - 1);
    list.add(n);
    return list;
}

Это только использует переменную list, если она на самом деленуждается в . Бессмысленно даже заявлять об этом для случай n <= 0, Когда вы просто собираетесь вернуть новый ArrayList<Integer>.