2016-01-23 11 views
3

Я хочу клонировать любой LinkedList, независимо от того, содержит ли он вещи, которые могут быть примитивными оболочками. Я понимаю, что это может быть глубокий рекурсивный вызов, чтобы получить настоящий глубокий клон, но я хочу только один уровень клонирования. Я не могу скомпилировать следующий код:Общий клон LinkedList в Java

<T> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input){ 
     if(input != null){ 
      LinkedList<T> clone = new LinkedList<>(); 
      for (T t: input){ 
       clone.add(t.clone()); //error : clone() has protected access 
      } 
      return clone; 
     } 
     return null; 
    } 
+2

Вы не можете. Не все объекты являются клонируемыми. Чего вы пытаетесь достичь на более высоком уровне? –

+0

Небольшой комментарий к вашему коду: цикл 'for' может быть упрощен для вызова' collect() 'с использованием Java 8. – bcsb1001

+0

Даже если я добавлю чек (если t instanceof Cloneable); он не работает. Почему это ? Есть ли обходной путь? – SlowAndSteady

ответ

2

Как уже упоминалось в комментариях, Cloneable Java не является очень дружественным способом клонировать объект. Таким образом, Вы, возможно, потребуется определить свой интерфейс Cloneable, и убедитесь, что

interface MyClone<T>{ 
    T clone(); 
} 

И использовать это в вашем коде

<T extends MyClone<? super T>> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input){ 
    if(input != null){ 
     LinkedList<T> clone = new LinkedList<>(); 
     for (T t: input){ 
      clone.add(t.clone()); 
     } 
     return clone; 
    } 
    return null; 
} 

И реализации MyClone знать, если неполную копию достаточно или глубокая копия требуется

Но что, если тип не реализуется MyClone? Хороший вопрос. Мы можем добавить перегрузку, которая занимает clone «завод».

<T> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input, Function<T,T> factory){ 
    if(input != null){ 
     LinkedList<T> clone = new LinkedList<>(); 
     for (T t: input){ 
      clone.add(factory.apply(t)); 
     } 
     return clone; 
    } 
    return null; 
} 

Если ваша платформа не имеет Function, то вы можете легко написать свой собственный, или использовать один из гуавы в.

+1

При таком подходе я, возможно, не смогу обрабатывать типы Integer и String, не так ли? – SlowAndSteady

+1

Принимая этот ответ, хотя я не могу использовать его полностью, поскольку функция недоступна в Android/Java7 – SlowAndSteady

+0

@SlowAndSteady вы можете легко определить свои собственные, нет? –

1

Поскольку clone() метод является большой беспорядок в Java мире, одно решение может быть использование Apache Commons SerializationUtils. Он использует сериализацию для копирования объектов и, как следствие, медленный. Что еще хуже, у вас будут проблемы, если ваш класс содержит поля, которые не поддерживают сериализацию. Вот пример:

<T extends Serializable> LinkedList<T> deepCloneOneLevel (final LinkedList<T> input) { 
    if (input != null) { 
     LinkedList<T> clone = new LinkedList<>(); 
     for (T t : input){ 
      clone.add(SerializationUtils.clone(t)); 
     } 
     return clone; 
    } 
    return null; 
} 
Смежные вопросы