Создание объектов на итерации — лучший подход

#java #object #construct

#java #объект #построить

Вопрос:

Когда я что-то разрабатывал, я задавался вопросом, какой может быть лучший / более быстрый подход для создания группы объектов при повторении чего-либо.

Допустим, у нас есть этот класс-оболочка:

 public class Photo{
    private String url;
    private String creator;

    public Photo(String url, String creator){
        this.url = url;
        this.creator = creator;
    }
    // Getter methods down here...
}
  

И у нас есть JSONArray фотографии, из которых нам нужны только url — и creator -строки:

 JSONArray photos = json.getJSONArray("photos");
Photo[] photo_arr = new Photo[photos.length()];
// Iterate:
for (int i = 0; i < photos.length(); i  ){
    // Create the objects here.
}
  

Теперь я вижу три возможных решения:

Создание временных переменных

Создание некоторых временных переменных, которые получают желаемые значения из текущего объекта, а затем создают новый Photo объект:

 // Iterate:
String url = "";
String creator = "";
for (int i = 0; i < photos.length(); i  ){
    url = photos[i].getString("url");
    creator = photos[i].getString("creator");
    photo_arr[i] = new Photo(url, creator);
}
  

Используйте возвращаемые значения непосредственно в конструкторе

Не создавайте временные переменные, а используйте возвращаемые значения из getString() -method в вызове конструктора:

 // Iterate:
for (int i = 0; i < photos.length(); i  ){
    photo_arr[i] = new Photo(
        photos[i].getString("url"),
        photos[i].getString("creator")
    );
}
  

Использование методов установки

Добавление конструктора без параметров и методов установки для url и creator в класс-оболочку и использование их для заполнения объекта:

 // Iterate:
for (int i = 0; i < photos.length(); i  ){
    photo_arr[i] = new Photo();
    photo_arr[i].setUrl( photos[i].getString("url") );
    photo_arr[i].setCreator( photos[i].getString("creator") );
}
  

Какой из них здесь лучше / быстрее / чище?

Ответ №1:

Два первых метода похожи. Вводите переменные, если считаете, что это более читабельно и доступно для обслуживания. Последний делает Photo класс изменяемым, тогда как он был неизменяемым в первых двух методах (хотя и не в самом строгом смысле, используемом в параллелизме).

Вы всегда должны отдавать предпочтение неизменности, когда это возможно, главным образом потому, что это делает программы более надежными: a Photo всегда находится в пригодном для использования, полностью сконструированном состоянии в первых двух случаях. Не в третьем.

Обратите внимание, что производительность здесь не имеет значения: три способа, безусловно, приведут к сопоставимому времени, и это не тот код, который замедлит работу программы. Не оптимизируйте преждевременно. Это корень всего зла.

Комментарии:

1. 1 для неизменности и не заботясь о промежуточных переменных, которые в любом случае будут оптимизированы. /* Кстати, можно создавать неизменяемые объекты с помощью цепных вызовов, каждый раз возвращающих новый объект, но обычно это имеет смысл только тогда, когда такой вызов серьезно изменяет объект. См., Например blog.zilverline.com/2011/02/05 /… */

Ответ №2:

Разница в скорости незначительна между решениями, которые вы предоставили для кода, который вы смотрите здесь. Удобочитаемость на самом деле важнее, чем можно подумать. Для вас важнее, чтобы ваши конечные пользователи получили увеличение скорости на 1%? Или что вы сможете поддерживать этот код в будущих версиях? Ответ обычно последний.

По этой причине я бы выбрал создание временных переменных. Использование методов установки (на мой взгляд) менее читабельно, но потенциально медленнее, поскольку вам придется вводить каждый из этих методов установки и выделять эти ресурсы. Использование [ing] возвращаемых значений непосредственно в конструкторе (опять же, на мой взгляд) менее читаемо, и поэтому его следует избегать в подобных случаях; но если возвращаемый объект был чем-то большего размера, то выделение ресурсов для его хранения во временном значении на самом деле может быть не-незначительно.

Комментарии:

1. Мне тоже нравятся ваши мысли ( 1).

2. Временная переменная никогда не будет большой в Java. Все переменные являются либо примитивами, либо ссылками.