2009-08-19 86 views
23

Xem lớp sauTrình trợ giúp để sao chép các thuộc tính không rỗng từ đối tượng này sang đối tượng khác? (Java)

public class Parent { 

    private String name; 
    private int age; 
    private Date birthDate; 

    // getters and setters 

} 

Giả sử tôi đã tạo ra một đối tượng cha mẹ như sau

Parent parent = new Parent(); 

parent.setName("A meaningful name"); 
parent.setAge(20); 

Thông báo theo mã trên tài sản sinh là null. Bây giờ tôi muốn sao chép các thuộc tính không rỗng từ đối tượng cha mẹ sang đối tượng khác. Một cái gì đó như

SomeHelper.copyNonNullProperties(parent, anotherParent); 

tôi cần nó, vì tôi muốn cập nhật đối tượng anotherParent không có ghi đè rỗng không của nó với các giá trị null.

Bạn có biết một số trợ giúp như thế này không?

Tôi chấp nhận mã tối thiểu là câu trả lời cho dù không helper trong tâm trí

regards,

+0

Removed tag mùa xuân từ này, vì nó không có gì để làm với mùa xuân. – Trenton

+0

Xóa thẻ ngủ đông từ này, vì nó không có bất cứ điều gì để làm với hibernate hoặc. – stian

Trả lời

68

Tôi cho rằng bạn đã có giải pháp, vì đã có rất nhiều thời gian xảy ra kể từ khi bạn hỏi. Tuy nhiên, nó không được đánh dấu là đã được giải quyết, và có lẽ tôi có thể giúp những người dùng khác.

Bạn đã thử xác định một lớp con của BeanUtilsBean của gói org.commons.beanutils? Trên thực tế, BeanUtils sử dụng lớp này, vì vậy đây là một cải tiến của giải pháp được đề xuất bởi dfa.

Kiểm tra tại source code của lớp học đó, tôi nghĩ bạn có thể ghi đè phương pháp copyProperty, bằng cách kiểm tra giá trị null và không làm gì nếu giá trị rỗng.

Something như thế này:

package foo.bar.copy; 
import java.lang.reflect.InvocationTargetException; 
import org.apache.commons.beanutils.BeanUtilsBean; 

public class NullAwareBeanUtilsBean extends BeanUtilsBean{ 

    @Override 
    public void copyProperty(Object dest, String name, Object value) 
      throws IllegalAccessException, InvocationTargetException { 
     if(value==null)return; 
     super.copyProperty(dest, name, value); 
    } 

} 

Sau đó, bạn chỉ có thể nhanh chóng một NullAwareBeanUtilsBean và sử dụng nó để sao chép đậu của bạn, ví dụ:

BeanUtilsBean notNull=new NullAwareBeanUtilsBean(); 
notNull.copyProperties(dest, orig); 
+0

một câu trả lời lý tưởng sẽ sử dụng ví dụ lớp cha được cung cấp trong câu hỏi – kiedysktos

+0

Tôi đang cố gắng thực hiện ý tưởng của bạn nhưng không thành công cho đến nay. Tôi đã tạo một chuỗi cho http://stackoverflow.com/questions/41125384/copy-non-null-properties-from-one-object-to-another-using-beanutilsbean – kiedysktos

+1

copyProperty() là phương thức tĩnh http: // commons.apache.org/proper/commons-beanutils/javadocs/v1.9.3/apidocs/index.html – Sadanand

0

bạn có thể sử dụng Apache Common BeanUtils, cụ thể the copyProperties helper in BeanUtils class hơn:

BeanUtils.copyProperties(parent, anotherParent); 
Tuy nhiên,

tuy nhiên tại sao bạn chỉ muốn sao chép các thuộc tính không trống? nếu một tài sản trong parent là null, chỉ cần sao chép nó, bạn có null cũng trong anotherParent phải không?

Chỉ cần đoán ... bạn muốn cập nhật một bean với một bean khác?

+1

Có, tôi muốn cập nhật một bean khác mà không ghi đè các giá trị không null của nó. –

+1

+1 cho một gợi ý lành mạnh để sử dụng thư viện ... đôi khi tôi cảm thấy như chúng tôi là những tiếng nói duy nhất trong vùng hoang dã trên số – skaffman

+2

Xin chào, xin lỗi nhưng nó không hoạt động. Nếu tôi có một nonParent.getBirthDate() và tôi gọi BeanUtils.copyProperties (parent, anotherParent) anotherParent.getBirthDate() sẽ trả về null –

1

Đơn giản chỉ cần sử dụng phương pháp bản sao của riêng bạn:

void copy(Object dest, Object source) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, 
     InvocationTargetException { 
    BeanInfo beanInfo = Introspector.getBeanInfo(source.getClass()); 
    PropertyDescriptor[] pdList = beanInfo.getPropertyDescriptors(); 
    for (PropertyDescriptor pd : pdList) { 
     Method writeMethod = null; 
     Method readMethod = null; 
     try { 
      writeMethod = pd.getWriteMethod(); 
      readMethod = pd.getReadMethod(); 
     } catch (Exception e) { 
     } 

     if (readMethod == null || writeMethod == null) { 
      continue; 
     } 

     Object val = readMethod.invoke(source); 
     writeMethod.invoke(dest, val); 
    } 
} 
0

Tôi biết thực tế là câu hỏi này là khá cũ, nhưng tôi nghĩ rằng belo w câu trả lời có thể hữu ích cho ai đó.

Nếu bạn sử dụng Spring, bạn có thể thử tùy chọn bên dưới.

import java.beans.PropertyDescriptor; 
import java.util.HashSet; 
import java.util.Set; 

import org.springframework.beans.BeanWrapper; 
import org.springframework.beans.BeanWrapperImpl; 

/** 
* Helper class to extract property names from an object. 
* 
* @Threadsafe 
* 
* @author arun.bc 
* 
*/ 
public class PropertyUtil { 

    /** 
    * Gets the properties which have null values from the given object. 
    * 
    * @param - source object 
    * 
    * @return - String array of property names. 
    */ 
    public static String[] getNullPropertiesString(Object source) { 
     Set<String> emptyNames = getNullProperties(source); 
     String[] result = new String[emptyNames.size()]; 

     return emptyNames.toArray(result); 
    } 


    /** 
    * Gets the properties which have null values from the given object. 
    * 
    * @param - source object 
    * 
    * @return - Set<String> of property names. 
    */ 
    public static Set<String> getNullProperties(Object source) { 
     final BeanWrapper src = new BeanWrapperImpl(source); 
     PropertyDescriptor[] pds = src.getPropertyDescriptors(); 

     Set<String> emptyNames = new HashSet<String>(); 
     for (PropertyDescriptor pd : pds) { 
      Object srcValue = src.getPropertyValue(pd.getName()); 
      if (srcValue == null) 
       emptyNames.add(pd.getName()); 
     } 
     return emptyNames; 
    } 

    /** 
    * Gets the properties which are not null from the given object. 
    * 
    * @param - source object 
    * 
    * @return - Set<String> array of property names. 
    */ 
    public static Set<String> getNotNullProperties(Object source) { 
     final BeanWrapper src = new BeanWrapperImpl(source); 
     PropertyDescriptor[] pds = src.getPropertyDescriptors(); 

     Set<String> names = new HashSet<String>(); 
     for (PropertyDescriptor pd : pds) { 
      Object srcValue = src.getPropertyValue(pd.getName()); 
      if (srcValue != null) 
       names.add(pd.getName()); 
     } 

     return names; 
    } 
} 

Một lần nữa bạn có thể sử dụng PropertyDescriptor và Set từ các phương pháp trên để sửa đổi đối tượng.

2

Nếu loại trả về của bạn không bị vô hiệu, BeanUtils của Apache sẽ không hoạt động, mùa xuân có thể. Vì vậy, kết hợp cả hai.

package cn.corpro.bdrest.util; 

import org.apache.commons.beanutils.BeanUtilsBean; 
import org.apache.commons.beanutils.ConvertUtilsBean; 
import org.apache.commons.beanutils.PropertyUtilsBean; 
import org.springframework.beans.BeanUtils; 

import java.beans.PropertyDescriptor; 
import java.lang.reflect.InvocationTargetException; 

/** 
* Author: [email protected] 
* DateTime: 2016/10/20 10:17 
*/ 
public class MyBeanUtils { 

    public static void copyPropertiesNotNull(Object dest, Object orig) throws InvocationTargetException, IllegalAccessException { 
     NullAwareBeanUtilsBean.getInstance().copyProperties(dest, orig); 
    } 

    private static class NullAwareBeanUtilsBean extends BeanUtilsBean { 

     private static NullAwareBeanUtilsBean nullAwareBeanUtilsBean; 

     NullAwareBeanUtilsBean() { 
      super(new ConvertUtilsBean(), new PropertyUtilsBean() { 
       @Override 
       public PropertyDescriptor[] getPropertyDescriptors(Class<?> beanClass) { 
        return BeanUtils.getPropertyDescriptors(beanClass); 
       } 

       @Override 
       public PropertyDescriptor getPropertyDescriptor(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { 
        return BeanUtils.getPropertyDescriptor(bean.getClass(), name); 
       } 
      }); 
     } 

     public static NullAwareBeanUtilsBean getInstance() { 
      if (nullAwareBeanUtilsBean == null) { 
       nullAwareBeanUtilsBean = new NullAwareBeanUtilsBean(); 
      } 
      return nullAwareBeanUtilsBean; 
     } 

     @Override 
     public void copyProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException { 
      if (value == null) return; 
      super.copyProperty(bean, name, value); 
     } 
    } 
} 
2

Sử dụng PropertyUtils (commons-beanutils)

for (Map.Entry<String, Object> e : PropertyUtils.describe(parent).entrySet()) { 
     if (e.getValue() != null && !e.getKey().equals("class")) { 
       PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue()); 
     } 
} 

trong Java8:

PropertyUtils.describe(parent).entrySet().stream() 
     .filter(e -> e.getValue() != null) 
     .filter(e -> ! e.getKey().equals("class")) 
     .forEach(e -> { 
     try { 
      PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue()); 
     } catch (Exception e) { 
      // Error setting property ...; 
     } 
    }); 
Các vấn đề liên quan