优雅实现List数据拷贝

在Java开发中,数据拷贝是一项非常常见的任务。Apache Commons BeanUtils库提供了一种方便的方式来实现JavaBean之间的属性拷贝。然而,当涉及到拷贝List类型的属性时,BeanUtils的默认实现会遇到一些限制。本文将介绍如何通过改造BeanUtils来优雅地实现List数据拷贝。

1. BeanUtils的默认实现

首先,让我们来看一下BeanUtils的默认实现。假设我们有两个JavaBean,分别为SourceBean和TargetBean:

public class SourceBean {
    private List<String> items;

    public List<String> getItems() {
        return items;
    }

    public void setItems(List<String> items) {
        this.items = items;
    }
}

public class TargetBean {
    private List<String> items;

    public List<String> getItems() {
        return items;
    }

    public void setItems(List<String> items) {
        this.items = items;
    }
}

我们可以使用BeanUtils.copyProperties()方法将SourceBean的属性拷贝到TargetBean中:

SourceBean source = new SourceBean();
source.setItems(Arrays.asList("item1", "item2", "item3"));

TargetBean target = new TargetBean();
BeanUtils.copyProperties(target, source);

System.out.println(target.getItems()); // [item1, item2, item3]

这段代码可以正常工作,但是如果我们尝试修改TargetBean的items属性,会发现它会影响到SourceBean的items属性:

target.getItems().add("item4");
System.out.println(source.getItems()); // [item1, item2, item3, item4]

这是因为BeanUtils默认情况下只是简单地将List对象的引用复制到目标对象中,而不是创建一个新的List对象。因此,当我们修改目标对象中的List时,源对象中的List也会被修改。

2. 改造BeanUtils

为了解决这个问题,我们需要改造BeanUtils。具体来说,我们需要扩展BeanUtils.copyProperty()方法,以便在拷贝List类型属性时创建一个新的List对象。

首先,我们需要创建一个新的类ListConverter,它实现了org.apache.commons.beanutils.Converter接口:

public class ListConverter implements Converter {

    @SuppressWarnings("rawtypes")
    @Override
    public Object convert(Class type, Object value) {
        if (value == null) {
            return null;
        } else if (value instanceof List) {
            List<?> list = (List<?>) value;
            List<Object> copy = new ArrayList<>(list.size());
            for (Object item : list) {
                copy.add(item);
            }
            return copy;
        } else {
            throw new ConversionException("Cannot convert " + value.getClass().getName() + " to List");
        }
    }
}

这个类的作用是在拷贝List类型属性时创建一个新的List对象。如果属性值为null,则返回null;如果属性值为List类型,则遍历原始List并将其元素添加到新的List中;否则抛出ConversionException异常。

接下来,我们需要注册这个Converter。可以通过以下方式进行注册:

ConvertUtils.register(new ListConverter(), List.class);

这样就完成了Converter的注册。现在我们可以使用改造后的BeanUtils来拷贝List类型属性了:

SourceBean source = new SourceBean();
source.setItems(Arrays.asList("item1", "item2", "item3"));

TargetBean target = new TargetBean();
BeanUtils.copyProperties(target, source);

System.out.println(target.getItems()); // [item1, item2, item3]

target.getItems().add("item4");
System.out.println(source.getItems()); // [item1, item2, item3]

现在修改目标对象中的List不会影响源对象中的List了。

3. 总结

在Java开发中,数据拷贝是一项非常常见的任务。Apache Commons BeanUtils库提供了一种方便的方式来实现JavaBean之间的属性拷贝。然而,当涉及到拷贝List类型的属性时,BeanUtils的默认实现会遇到一些限制。通过改造BeanUtils并注册一个新的Converter,我们可以优雅地实现List数据拷贝。

猜你喜欢

转载自blog.csdn.net/zhengren964/article/details/131600521