Подтвердить что ты не робот

Guava ImmutableList copyOf vs Builder

Мне было интересно, что более эффективно и почему?

1)

List<Blah> foo;
...
return ImmutableList.copyOf(foo);

или

2)

List<Blah> foo;
...
return new ImmutableList.Builder<Blah>().addAll(foo).build();
4b9b3361

Ответ 1

Я не вижу причин, по которым вы должны использовать строитель здесь:

  • ImmutableList.copyOf гораздо читабельнее, чем создание Builder в этом случае
  • Builder не выводит общий тип, и вам нужно указать тип самостоятельно, когда используется как однострочный,
  • (from docs) ImmutableList.copyOf делает хорошую магию при вызове с другой неизменной коллекцией (попытки избежать фактического копирования данных, когда это безопасно)
  • (из исходного кода) Builder#addAll вызывает addAll ранее созданного ArrayList, а copyOf избегает создания любого списка для коллекций с нулевым и одноэлементным доступом (возвращает пустой неизменный список и неизменный список singleton соответственно),
  • (из источника) copyOf(Collection) экземпляр не создает временные ArrayList (copyOf(Iterable) и copyOf(Iterator) делает это),
  • (из источника), кроме того, Builder#build вызывает copyOf на ранее внутренне заселенном ArrayList, что подводит вас к вашему вопросу - зачем использовать Builder здесь, когда у вас есть copyOf?

P.S. Лично я использую ImmutableList.builder() static factory вместо конструктора new ImmutableList.Builder<Blah>() - при назначении переменной Builder<Blah> первый вводит общий тип, а последний - нет.

Ответ 2

Строитель позволяет добавлять вещи. Т.е. если вам нужно добавить другой объект, это может быть проще сделать с помощью шаблона Builder:

ImmutableList<SomeModel> newModelObjects = new ImmutableList.Builder<SomeModel>()
    .addAll(getModelObjects()).add(newModelObject).build();

В отличие от:

ArrayList<SomeModel> list = new ArrayList<>(getModelObjects());
list.add(newModelObject);
ImmutableList<SomeModel> newModelObjects = ImmutableList.copyOf(list);