Как сделать клон arraylist java

Добавил пользователь Владимир З.
Обновлено: 10.09.2024

Метод clone () класса ArrayList используется для клонирования ArrayList в другой список ArrayList в Java, поскольку он возвращает неглубокую копию вызывающего его ArrayList.

Синтаксис:

Возвращаемое значение: эта функция возвращает копию экземпляра Object.

Программа ниже иллюстрирует метод Java.util.ArrayList.clone ():

Пример:

Пример 2:

Выход

Вниманию читателя! Не прекращайте учиться сейчас. Ознакомьтесь со всеми важными концепциями Java Foundation и коллекций с помощью курса "Основы Java и Java Collections" по доступной для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .

Как я могу клонировать коллекции , а также клонировать предметы в Java?

Например у меня:

И я ожидаю, что объекты в clonedList не совпадает с в список собаки.

Вам нужно, чтобы выполнить итерации по элементам, и клонировать их по одному, выставив клоны в массив результата, как вы идете.

Для того, чтобы работать, очевидно, вам придется сделать класс собака по реализации клонируемые интерфейс и переопределить клон()` метод.

Я, лично, хотел бы добавить конструктор для собаки:

Потом просто повторять (как показано в Varkhan'ы ответ):

Я нахожу преимущество в том, вы не'т нужно, чтобы ввернуть вокруг с разбитыми клонируемые вещи в Java. Это также соответствует тому, как вы копируете коллекциями Java.

Другой вариант мог бы написать свой собственный интерфейс ICloneable и используйте это. Таким образом, вы могли бы написать универсальный метод для клонирования.

Все стандартные коллекции имеют конструкторы копирования. Используйте их.

клон() был разработан с учетом нескольких ошибок (см. Этот вопрос), так что'ы лучше, чтобы избежать этого.

Из эффективная Java 2-е издание, Пункт 11: переопределить клон рассудительно

учитывая все проблемы, связанные с клонируемые, можно с уверенностью сказать что другие интерфейсы не должны продлить его, и что классы предназначен для наследства (пункт 17) не должен его выполнять. Из-за его многочисленные недостатки, некоторые программисты эксперт просто выбрать никогда переопределить метод clone и никогда не ссылаться на него, за исключением, пожалуй, массивы копия. Если вы проектируете класс для наследования, следует помнить, что если вы решите не предоставлять хорошо защищенный метод clone, он не будет невозможного для подклассы, чтобы реализовать клонируемые.

Эта книга также описывает многие преимущества конструкторов копирования более клонируемые/клон.

  • Они не'т полагаться на риск экстралингвистические создания объекта механизм
  • Они не'т спрос неисполнимым соблюдение тонко документально конвенций
  • Они не'т конфликте с правильным использованием конечных полей
  • Они не'т выбросить ненужное проверенные исключения
  • Они не'т требует забросы.

Рассмотрим еще одно преимущество использования конструктора копирования: Предположим, у вас есть поиска HashSet S , и вы хотите скопировать его как TreeSet . Метод clone не могу предложить эту функциональность, но это легко конструктор преобразования: `новый TreeSet(ов).

У меня есть ArrayList , копию которого я хочу вернуть. ArrayList имеет метод клонирования со следующей подписью:

Как после вызова этого метода вернуть возвращенный объект в ArrayList ?

Вы можете оставить комментарий. Думаю, мои правки объяснили, с чем у меня были проблемы.

Bill the Lizard

@Oscar, он хочет клонировать, а не вызывать команду клонирования. Это может быть не то же самое, если клон на самом деле не клонирует. Думаю, в этом суть. Это действительно непростой вопрос.

@BilltheLizard. Вы предпочитаете 30 (ish) ответ на голосование, или вы просто не пересматривали его с тех пор, как был опубликован ответ 180 (ish)?

Bill the Lizard

Ответы 14

Это будет нормально работать для строк (это то, о чем задается вопрос), но стоит отметить, что ArrayList.clone будет выполнять неглубокую копию, поэтому, если в списке были изменяемые объекты, они не будут клонированы (и изменение одного в одном списке изменит и тот, что в другом списке.

Вам следует избегать использования необработанных типов в чем-либо, кроме устаревшего кода. Вам лучше использовать ArrayList newArrayList = (ArrayList ) oldArrayList.clone(); .

Не связано, но пока есть: используйте List вместо ArrayList с левой стороны. Именно так следует использовать коллекции большую часть времени.

Я не мог использовать этот метод для дублирования ArrayList. Метод clone () не распознан.

@Jack, ошибка в вашем случае заключается в том, что вы пытаетесь вызвать метод clone () через интерфейс List, а не через класс ArrayList.

Я считаю, что использование addAll отлично работает.

используются круглые скобки, а не общий синтаксис

Это будет работать для строк, но не для изменяемых объектов. Вы также захотите клонировать их.

Да, его вопрос касается струн. И у него есть проблема с дженериками, которым в данном случае не нравится кастинг.

Кроме того, ArrayList.clone будет выполнять только поверхностное клонирование, поэтому изменяемые объекты в списке также не будут клонированы с использованием этого метода.

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

Почему бы просто не использовать new ArrayList (original) ?

Глядя на исходный код OpenJDK 8, использование List copy = new ArrayList<>(original); имеет дополнительное преимущество в виде меньших накладных расходов и может быть немного быстрее по сравнению с List list = new ArrayList<>(original); list.addAll(orig); (не тестировалось, хотя использование аргументов конструктора вместо addAll(Collection) только для повышения производительности углубляется в преждевременную оптимизацию. территория, просто использую потому что короче тбх)

Это также должно работать:

Я думаю, что это должно помочь с использованием API коллекций:

Примечание: метод копирования выполняется за линейное время.

Почему бы просто не использовать новый ArrayList (oldList)?

Я считаю, что это не сработает, из документа * Список адресатов должен быть не меньше длины исходного списка. Если он длиннее, остальные элементы в списке назначения не затронуты.

@GregDomjan не то чтобы я согласен с тем, что это лучший способ, но это способ сделать это. Чтобы обойти вашу проблему, это очень просто: List newList = new ArrayList <> (oldList.size ());

Не уверен, что это связано с Java 8, но даже при указании размера по-прежнему возникает исключение IndexOutOfBoundsException: destination.size () List copyList = new ArrayList<>(mMySerializableObjects.size()); . Похоже, использование copyList.addAll(original); является хорошей альтернативой.

@GeneBo Это не указывает размер. Это совсем другое дело - указать емкость. Радость тайны аргументов int . Понятия не имею, почему вы хотите использовать этот непонятный статический метод вместо старого доброго addAll .

Tom Hawtin - tackline

Зачем вам клонировать? Создание нового списка обычно имеет больше смысла.

Вы можете не знать, что это за список. Это может быть LinkedList, MyOwnCustomList или подкласс ArrayList, и в этом случае создание ArrayList будет неправильным типом.

Будет ли мне интересно, какая реализация используется в исходном списке? Меня, наверное, волнует, какая реализация используется в новом списке.

Tom Hawtin - tackline

@ Стив Куо: Подпись ArrayList(Collection c) означает, что не имеет значения, какой список вы используете в качестве аргумента.

cdmckay, проблема в поведении нового списка. Какими должны быть характеристики производительности для ArrayList vs LinkedList. Я говорю, что это должно быть то, что требует код копирования. Стив Куо, похоже, считает, что это должно быть то же самое, что и исходный список.

Tom Hawtin - tackline

Согласно документации связь, похоже, не копировать элемент списка, а использовать те же ссылки, я прав?

Я имею в виду, что это не глубокая копия, не так ли?

@YekhezkelYovel Нет, не будет.

Tom Hawtin - tackline

Но клон - это глубокая копия. Итак, конструктор копирования и клон - разные вещи?

@Vlad Нет. Если вы клонируете say ArrayList , то любые изменения дат в одном списке будут отражены в другом.

Tom Hawtin - tackline

Хотя это не глубокая копия

@Inchara И ArrayList.clone тоже.

Tom Hawtin - tackline

Не думаю, что это глубокая копия. strs.list все еще упоминается.

@PasupathiRajamanickam Нет, это все еще не глубокая копия. Как исходный вопрос, это эквивалент клонирования списка.

Tom Hawtin - tackline

Было бы хорошо, если бы этот ответ объяснял преимущества создания нового списка перед клонированием списка.

Tom Hawtin - tackline

Имейте в виду, что у Object.clone () есть некоторые серьезные проблемы, и его использование в большинстве случаев не рекомендуется. Полный ответ см. В пункте 11 из "Эффективная Java" Джошуа Блоха. Я считаю, что вы можете безопасно использовать Object.clone () для массивов примитивных типов, но помимо этого вам нужно быть осторожным в правильном использовании и переопределении клона. Вероятно, вам лучше определить конструктор копирования или статический фабричный метод, который явно клонирует объект в соответствии с вашей семантикой.

Будьте очень осторожны при клонировании ArrayLists. Клонирование в java мелкое. Это означает, что он будет клонировать только самого Arraylist, а не его членов. Итак, если у вас есть ArrayList X1 и вы клонируете его в X2, любое изменение в X2 также проявится в X1 и наоборот. При клонировании вы создадите только новый список ArrayList с указателями на те же элементы в оригинале.

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

  • Если вы переопределите метод clone в нефинальном классе, вы должны вернуть объект, полученный с помощью вызова super.clone()
    • Методы super.clone() автоматически копируют примитивные значения

    Примеры реализации метода clone()

    Альтернативы использования clone():


    • Получить ссылку
    • Facebook
    • Twitter
    • Pinterest
    • Электронная почта
    • Другие приложения

    Комментарии

    Методы класса Object в Java

    Изображение

    Класс Object является корнем иерархии классов. У каждого класса есть Object как суперкласс. Все объекты, включая массивы, реализуют методы этого класса. Методы класса Object Метод getClass() public final Class getClass() Возвращает класс времени исполнения (runtime class) этого Object. Возвращенный объект Class - это объект, который заблокирован статическими синхронизированными методами представленного класса. Фактический тип результата - Class где |X| заменяется статическим типом выражения, для которого вызывается getClass. Например, в этом фрагменте кода не требуется приведение: Number n = 0; Class c = n.getClass(); Метод getClass() возвращает: Объект Class, представляющий класс времени исполнения (runtime class) этого объекта. Метод hashCode public int hashCode() Возвращает значение хэш-кода для объекта. Этот метод поддерживается для использования хэш-таблиц, таких как те, что предоставляются HashMap. Основной контракт метода hashCo

    Spring Boot стартеры

    Изображение

    Стартеры - это набор удобных дескрипторов зависимостей, которые вы можете включить в свое приложение. Вы получаете универсальный набор для всех необходимых вам Spring и связанных с ними технологий без необходимости искать примеры кода и копировать и вставлять множество дескрипторов зависимостей. Например, если вы хотите начать использовать Spring и JPA для доступа к базе данных, включите в ваш проект зависимость spring-boot-starter-data-jpa. Стартеры содержат множество зависимостей, которые необходимы вам для быстрого запуска и запуска проекта с согласованным, поддерживаемым набором управляемых переходных зависимостей. Что указывается в имени стартера Все официальные стартеры следуют аналогичной схеме именования; spring-boot-starter-*, где * это конкретный тип приложения. Эта структура наименования предназначена, чтобы помочь, когда вам нужно найти стартер. Интеграция Maven во многие IDE позволяет вам искать зависимости по имени. Например, если установлен соответствующий плагин Ecl

    Читайте также: