Javaオブジェクトの深度コピーと効率比較
23310 ワード
Javaオブジェクトの深度コピー-ツールクラス紹介 上コード 性能比較 まとめ 紹介する
ここでは,反射により深さコピーが可能なコピーオブジェクトツールクラスを独自に作成した.深度コピーの基本タイプ、Collection、Map、Array、カスタムオブジェクトをサポートします.注意事項:ソースオブジェクトとターゲットオブジェクト、フィールド名は同じでなければなりません.
深度コピー:たとえばコピーが必要なソースオブジェクトに1つのオブジェクトが含まれています.ターゲットオブジェクトとは異なりフィールドのみです.BeanUtils.copyPropertiesコピーは、私たちが望んでいる効果に達しません(データは来たようですが、オブジェクトは変わっていません.自分で試してみてください).オブジェクトを取得するときにエラーが表示されます(データ型が一致しないためです).
オブジェクト・コピーで現在よく使用されているものは次のとおりです. springのBeanUtils.copyProperties; cglibのBeanCopier;
じょうふごう
パフォーマンスの比較
cglibのBeanCopierは比較していないので、きっとすぐにできますが、浅いコピーでもあるので、自分で比較してみてください.以下は参考にしてください.
属性コピー方式
10,000回
100000回
SpringのBeanUtils.copyProperties
344~472ミリ秒
455~580ミリ秒
自分で書いた
40~100ミリ秒
168~235ミリ秒
まとめ
オブジェクトコピーは主にエンティティの変換に使用され、基本的には100000を超えることはありません.このツールクラスも基本的に十分ですが、サポートされているタイプは複雑ではありません.このバージョンはまだ完備されていないので、更新する時間があります.
ここでは,反射により深さコピーが可能なコピーオブジェクトツールクラスを独自に作成した.深度コピーの基本タイプ、Collection、Map、Array、カスタムオブジェクトをサポートします.注意事項:ソースオブジェクトとターゲットオブジェクト、フィールド名は同じでなければなりません.
深度コピー:たとえばコピーが必要なソースオブジェクトに1つのオブジェクトが含まれています.ターゲットオブジェクトとは異なりフィールドのみです.BeanUtils.copyPropertiesコピーは、私たちが望んでいる効果に達しません(データは来たようですが、オブジェクトは変わっていません.自分で試してみてください).オブジェクトを取得するときにエラーが表示されます(データ型が一致しないためです).
オブジェクト・コピーで現在よく使用されているものは次のとおりです.
じょうふごう
//
public class ObjectCopyUtil {
/**
* copy
* : , Collection, Map, Array,
* :Collection Collection
* @param source
* @param target
* @return target
* @throws Exception
*/
public static Object deepCopy(Object source,Object target) throws Exception{
if(null == source){
return null;
}
//
Class<?> sourceClassType = source.getClass();
//
Class<?> targetClassType = target.getClass();
// Map
Map<String,Object> sourceMap = new HashMap<>(sourceClassType.getDeclaredFields().length);
//
for(Field field : sourceClassType.getDeclaredFields()){
field.setAccessible(true);
Object value = field.get(source);
if(value != null){
sourceMap.put(field.getName(),value);
}
}
//
for(Field field : targetClassType.getDeclaredFields()){
field.setAccessible(true);
Object targetValue;
Object value = sourceMap.get(field.getName());
if(value == null){
continue;
}
if(value instanceof Collection<?>){
//
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
Class<?> actualTypeArgument = (Class<?>)parameterizedType.getActualTypeArguments()[0];
// Collection
Collection list = (Collection)value;
// Collection
Collection targetList = CollectionFactory.createCollection(field.getType(),list.size());
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Object targetItem;
Object item = iterator.next();
if(isBaseType(item)){
//
targetItem = item;
}else if(item instanceof Map){
//map
targetItem = item;
}else if(item.getClass().isArray()){
//
targetItem = item;
}else if(item instanceof Collection<?>){
//Collection
//throw new IllegalArgumentException("Collection cannot be nested within collection");
targetItem = null;
}else{
targetItem = deepCopy(item,actualTypeArgument.newInstance());
}
targetList.add(targetItem);
}
targetValue = targetList;
}else if(value instanceof Map){
//map
targetValue = value;
}else if(value.getClass().isArray()){
//
targetValue = value;
}else if(isBaseType(value)){
//
targetValue = value;
}else{
//
targetValue = deepCopy(value,field.getType().newInstance());
}
field.set(target,targetValue);
}
return target;
}
public static boolean isBaseType(Object object){
if(object.getClass().isPrimitive()){
return true;
}else if(object instanceof String){
return true;
}else if(object instanceof Integer){
return true;
}else if(object instanceof Double){
return true;
}else if(object instanceof Float){
return true;
}else if(object instanceof Long){
return true;
}else if(object instanceof Boolean){
return true;
}else if(object instanceof Date){
return true;
}else if(object instanceof Byte){
return true;
}else if(object instanceof Short){
return true;
}else {
return false;
}
}
}
パフォーマンスの比較
cglibのBeanCopierは比較していないので、きっとすぐにできますが、浅いコピーでもあるので、自分で比較してみてください.以下は参考にしてください.
属性コピー方式
10,000回
100000回
SpringのBeanUtils.copyProperties
344~472ミリ秒
455~580ミリ秒
自分で書いた
40~100ミリ秒
168~235ミリ秒
まとめ
オブジェクトコピーは主にエンティティの変換に使用され、基本的には100000を超えることはありません.このツールクラスも基本的に十分ですが、サポートされているタイプは複雑ではありません.このバージョンはまだ完備されていないので、更新する時間があります.