Java中hutool?List集合對象拷貝案例代碼
需求
三個對象,一個對象Point,一個對象CustomData。第三個對象IotDataCache用來屏蔽二者差異
public class Point extends Model<Point> { @TableId private Integer pointId; private String iotCode; }
主鍵ID為整型
public class CustomData extends Model<CustomData> { @Schema(description = "主鍵") @TableId(type = IdType.ASSIGN_UUID) private String id; private String iotCode; }
主鍵id為字符串
把Point的pointId 和 CustomData的id 都拷貝到IotDataCache中
iotCode字段不變
案例
public static void main(String[] args) { List<Point> list1 = new ArrayList<>(1); Point point = new Point(); point.setPointId(1); point.setIotCode("root.test"); point.setName("123"); list1.add(point); Point point2 = new Point(); point2.setPointId(2); point2.setIotCode("root.test2"); point2.setName("123"); list1.add(point2); Map<String,String> fieldMapping = new HashMap<>(1); fieldMapping.put("pointId","id"); CopyOptions copyOptions = CopyOptions.create() .setIgnoreNullValue(false) .setFieldMapping(fieldMapping); List<IotDataCache> temp = BeanUtil.copyToList(list1, IotDataCache.class, copyOptions); System.out.println(temp); List<CustomData> list2 = new ArrayList<>(2); CustomData bean1 = new CustomData(); bean1.setId("customdata_h34fdjfsdouf9"); bean1.setIotCode("root.custom"); list2.add(bean1); CustomData bean2 = new CustomData(); bean2.setId("customdata_h34fdjfsdouf8"); bean2.setIotCode("root.custom2"); list2.add(bean2); List<IotDataCache> temp2 = BeanUtil.copyToList(list2, IotDataCache.class, null); System.out.println(temp2); }
Test
完美實現(xiàn)
拓展
問了AI 很多東西牛頭不對馬尾的,方法名對不上,參數(shù)有問題啊什么的??磥磉€需要進步。還是得自己看源碼
copyToList方法
/** * 復(fù)制集合中的Bean屬性<br> * 此方法遍歷集合中每個Bean,復(fù)制其屬性后加入一個新的{@link List}中。 * * @param collection 原Bean集合 * @param targetType 目標Bean類型 * @param copyOptions 拷貝選項 * @param <T> Bean類型 * @return 復(fù)制后的List * @since 5.6.4 */ public static <T> List<T> copyToList(Collection<?> collection, Class<T> targetType, CopyOptions copyOptions) { if (null == collection) { return null; } if (collection.isEmpty()) { return new ArrayList<>(0); } return collection.stream().map((source) -> { final T target = ReflectUtil.newInstanceIfPossible(targetType); copyProperties(source, target, copyOptions); return target; }).collect(Collectors.toList()); }
CopyOptions配置
/** * 屬性拷貝選項<br> * 包括:<br> * 1、限制的類或接口,必須為目標對象的實現(xiàn)接口或父類,用于限制拷貝的屬性,例如一個類我只想復(fù)制其父類的一些屬性,就可以將editable設(shè)置為父類<br> * 2、是否忽略空值,當(dāng)源對象的值為null時,true: 忽略而不注入此值,false: 注入null<br> * 3、忽略的屬性列表,設(shè)置一個屬性列表,不拷貝這些屬性值<br> * * @author Looly */ public class CopyOptions implements Serializable { private static final long serialVersionUID = 1L; /** * 限制的類或接口,必須為目標對象的實現(xiàn)接口或父類,用于限制拷貝的屬性,例如一個類我只想復(fù)制其父類的一些屬性,就可以將editable設(shè)置為父類<br> * 如果目標對象是Map,源對象是Bean,則作用于源對象上 */ protected Class<?> editable; /** * 是否忽略空值,當(dāng)源對象的值為null時,true: 忽略而不注入此值,false: 注入null */ protected boolean ignoreNullValue; /** * 屬性過濾器,斷言通過的屬性才會被復(fù)制<br> * 斷言參數(shù)中Field為源對象的字段對象,如果源對象為Map,使用目標對象,Object為源對象的對應(yīng)值 */ private BiPredicate<Field, Object> propertiesFilter; /** * 是否忽略字段注入錯誤 */ protected boolean ignoreError; /** * 是否忽略字段大小寫 */ protected boolean ignoreCase; /** * 字段屬性編輯器,用于自定義屬性轉(zhuǎn)換規(guī)則,例如駝峰轉(zhuǎn)下劃線等<br> * 規(guī)則為,{@link Editor#edit(Object)}屬性為源對象的字段名稱或key,返回值為目標對象的字段名稱或key */ private Editor<String> fieldNameEditor; /** * 字段屬性值編輯器,用于自定義屬性值轉(zhuǎn)換規(guī)則,例如null轉(zhuǎn)""等 */ protected BiFunction<String, Object, Object> fieldValueEditor; /** * 是否支持transient關(guān)鍵字修飾和@Transient注解,如果支持,被修飾的字段或方法對應(yīng)的字段將被忽略。 */ protected boolean transientSupport = true; /** * 是否覆蓋目標值,如果不覆蓋,會先讀取目標對象的值,非{@code null}則寫,否則忽略。如果覆蓋,則不判斷直接寫 */ protected boolean override = true; /** * 自定義類型轉(zhuǎn)換器,默認使用全局萬能轉(zhuǎn)換器轉(zhuǎn)換 */ protected TypeConverter converter = (type, value) -> Convert.convertWithCheck(type, value, null, ignoreError); //region create /** * 創(chuàng)建拷貝選項 * * @return 拷貝選項 */ public static CopyOptions create() { return new CopyOptions(); } /** * 創(chuàng)建拷貝選項 * * @param editable 限制的類或接口,必須為目標對象的實現(xiàn)接口或父類,用于限制拷貝的屬性 * @param ignoreNullValue 是否忽略空值,當(dāng)源對象的值為null時,true: 忽略而不注入此值,false: 注入null * @param ignoreProperties 忽略的屬性列表,設(shè)置一個屬性列表,不拷貝這些屬性值 * @return 拷貝選項 */ public static CopyOptions create(Class<?> editable, boolean ignoreNullValue, String... ignoreProperties) { return new CopyOptions(editable, ignoreNullValue, ignoreProperties); } //endregion /** * 構(gòu)造拷貝選項 */ public CopyOptions() { } /** * 構(gòu)造拷貝選項 * * @param editable 限制的類或接口,必須為目標對象的實現(xiàn)接口或父類,用于限制拷貝的屬性 * @param ignoreNullValue 是否忽略空值,當(dāng)源對象的值為null時,true: 忽略而不注入此值,false: 注入null * @param ignoreProperties 忽略的目標對象中屬性列表,設(shè)置一個屬性列表,不拷貝這些屬性值 */ public CopyOptions(Class<?> editable, boolean ignoreNullValue, String... ignoreProperties) { this.propertiesFilter = (f, v) -> true; this.editable = editable; this.ignoreNullValue = ignoreNullValue; this.setIgnoreProperties(ignoreProperties); } /** * 設(shè)置限制的類或接口,必須為目標對象的實現(xiàn)接口或父類,用于限制拷貝的屬性 * * @param editable 限制的類或接口 * @return CopyOptions */ public CopyOptions setEditable(Class<?> editable) { this.editable = editable; return this; } /** * 設(shè)置是否忽略空值,當(dāng)源對象的值為null時,true: 忽略而不注入此值,false: 注入null * * @param ignoreNullVall 是否忽略空值,當(dāng)源對象的值為null時,true: 忽略而不注入此值,false: 注入null * @return CopyOptions */ public CopyOptions setIgnoreNullValue(boolean ignoreNullVall) { this.ignoreNullValue = ignoreNullVall; return this; } /** * 設(shè)置忽略空值,當(dāng)源對象的值為null時,忽略而不注入此值 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreNullValue() { return setIgnoreNullValue(true); } /** * 屬性過濾器,斷言通過的屬性才會被復(fù)制<br> * {@link BiPredicate#test(Object, Object)}返回{@code true}則屬性通過,{@code false}不通過,拋棄之 * * @param propertiesFilter 屬性過濾器 * @return CopyOptions */ public CopyOptions setPropertiesFilter(BiPredicate<Field, Object> propertiesFilter) { this.propertiesFilter = propertiesFilter; return this; } /** * 設(shè)置忽略的目標對象中屬性列表,設(shè)置一個屬性列表,不拷貝這些屬性值 * * @param ignoreProperties 忽略的目標對象中屬性列表,設(shè)置一個屬性列表,不拷貝這些屬性值 * @return CopyOptions */ public CopyOptions setIgnoreProperties(String... ignoreProperties) { return setPropertiesFilter((field, o) -> false == ArrayUtil.contains(ignoreProperties, field.getName())); } /** * 設(shè)置忽略的目標對象中屬性列表,設(shè)置一個屬性列表,不拷貝這些屬性值,Lambda方式 * * @param <P> 參數(shù)類型 * @param <R> 返回值類型 * @param funcs 忽略的目標對象中屬性列表,設(shè)置一個屬性列表,不拷貝這些屬性值 * @return CopyOptions * @since 5.8.0 */ @SuppressWarnings("unchecked") public <P, R> CopyOptions setIgnoreProperties(Func1<P, R>... funcs) { final Set<String> ignoreProperties = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName); return setPropertiesFilter((field, o) -> false == ignoreProperties.contains(field.getName())); } /** * 設(shè)置是否忽略字段的注入錯誤 * * @param ignoreError 是否忽略注入錯誤 * @return CopyOptions */ public CopyOptions setIgnoreError(boolean ignoreError) { this.ignoreError = ignoreError; return this; } /** * 設(shè)置忽略字段的注入錯誤 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreError() { return setIgnoreError(true); } /** * 設(shè)置是否忽略字段的大小寫 * * @param ignoreCase 是否忽略大小寫 * @return CopyOptions */ public CopyOptions setIgnoreCase(boolean ignoreCase) { this.ignoreCase = ignoreCase; return this; } /** * 設(shè)置忽略字段的大小寫 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreCase() { return setIgnoreCase(true); } /** * 設(shè)置拷貝屬性的字段映射,用于不同的屬性之前拷貝做對應(yīng)表用 * * @param fieldMapping 拷貝屬性的字段映射,用于不同的屬性之前拷貝做對應(yīng)表用 * @return CopyOptions */ public CopyOptions setFieldMapping(Map<String, String> fieldMapping) { return setFieldNameEditor((key -> fieldMapping.getOrDefault(key, key))); } /** * 設(shè)置字段屬性編輯器,用于自定義屬性轉(zhuǎn)換規(guī)則,例如駝峰轉(zhuǎn)下劃線等<br> * 此轉(zhuǎn)換器只針對源端的字段做轉(zhuǎn)換,請確認轉(zhuǎn)換后與目標端字段一致<br> * 當(dāng)轉(zhuǎn)換后的字段名為null時忽略這個字段 * * @param fieldNameEditor 字段屬性編輯器,用于自定義屬性轉(zhuǎn)換規(guī)則,例如駝峰轉(zhuǎn)下劃線等 * @return CopyOptions * @since 5.4.2 */ public CopyOptions setFieldNameEditor(Editor<String> fieldNameEditor) { this.fieldNameEditor = fieldNameEditor; return this; } /** * 設(shè)置字段屬性值編輯器,用于自定義屬性值轉(zhuǎn)換規(guī)則,例如null轉(zhuǎn)""等<br> * * @param fieldValueEditor 字段屬性值編輯器,用于自定義屬性值轉(zhuǎn)換規(guī)則,例如null轉(zhuǎn)""等 * @return CopyOptions * @since 5.7.15 */ public CopyOptions setFieldValueEditor(BiFunction<String, Object, Object> fieldValueEditor) { this.fieldValueEditor = fieldValueEditor; return this; } /** * 編輯字段值 * * @param fieldName 字段名 * @param fieldValue 字段值 * @return 編輯后的字段值 * @since 5.7.15 */ protected Object editFieldValue(String fieldName, Object fieldValue) { return (null != this.fieldValueEditor) ? this.fieldValueEditor.apply(fieldName, fieldValue) : fieldValue; } /** * 設(shè)置是否支持transient關(guān)鍵字修飾和@Transient注解,如果支持,被修飾的字段或方法對應(yīng)的字段將被忽略。 * * @param transientSupport 是否支持 * @return this * @since 5.4.2 */ public CopyOptions setTransientSupport(boolean transientSupport) { this.transientSupport = transientSupport; return this; } /** * 設(shè)置是否覆蓋目標值,如果不覆蓋,會先讀取目標對象的值,非{@code null}則寫,否則忽略。如果覆蓋,則不判斷直接寫 * * @param override 是否覆蓋目標值 * @return this * @since 5.7.17 */ public CopyOptions setOverride(boolean override) { this.override = override; return this; } /** * 設(shè)置自定義類型轉(zhuǎn)換器,默認使用全局萬能轉(zhuǎn)換器轉(zhuǎn)換。 * * @param converter 轉(zhuǎn)換器 * @return this * @since 5.8.0 */ public CopyOptions setConverter(TypeConverter converter) { this.converter = converter; return this; } /** * 使用自定義轉(zhuǎn)換器轉(zhuǎn)換字段值<br> * 如果自定義轉(zhuǎn)換器為{@code null},則返回原值。 * * @param targetType 目標類型 * @param fieldValue 字段值 * @return 編輯后的字段值 * @since 5.8.0 */ protected Object convertField(Type targetType, Object fieldValue) { return (null != this.converter) ? this.converter.convert(targetType, fieldValue) : fieldValue; } /** * 轉(zhuǎn)換字段名為編輯后的字段名 * * @param fieldName 字段名 * @return 編輯后的字段名 * @since 5.4.2 */ protected String editFieldName(String fieldName) { return (null != this.fieldNameEditor) ? this.fieldNameEditor.edit(fieldName) : fieldName; } /** * 測試是否保留字段,{@code true}保留,{@code false}不保留 * * @param field 字段 * @param value 值 * @return 是否保留 */ protected boolean testPropertyFilter(Field field, Object value) { return null == this.propertiesFilter || this.propertiesFilter.test(field, value); } }
常用的可能就是Null忽略情況,大小寫情況、忽略字段、屬性字段映射(其實就是fieldNameEditor)。各位成功!
總結(jié)
到此這篇關(guān)于Java中hutool List集合對象拷貝的文章就介紹到這了,更多相關(guān)Java hutool List集合對象拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java集合List快速實現(xiàn)重復(fù)判斷的方法小結(jié)
- Java?hutool?List集合對象拷貝示例代碼
- java的list集合排序自定義元素方式
- Java將不同的List集合復(fù)制到另一個集合常見的方法
- Java?List集合取交集的五種常見方式總結(jié)
- Java?List集合取交集的8種不同實現(xiàn)方式總結(jié)
- java取出list中某幾個屬性組成一個新集合的幾種方式
- Java實現(xiàn)List集合手動分頁的方法
- java如何獲取兩個List集合之間的交集、差集、并集
- Java中Set集合轉(zhuǎn)為List集合常見的兩種方式
- Java集合中的List超詳細講解
相關(guān)文章
Springboot中@Value注解的場景用法及可能遇到的問題詳解
這篇文章主要給大家介紹了關(guān)于Springboot中@Value注解的場景用法及可能遇到問題的相關(guān)資料, @Value通常用于注入外部化屬性,即外部配置屬性的注入,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-11-11Spring中的InitializingBean接口源碼解析
這篇文章主要介紹了Spring中的InitializingBean接口源碼解析,InitializingBean接口為Bean初始化提供了一種方式,實現(xiàn)InitializingBean接口的Bean,在BeanFactory設(shè)置其所有屬性后會調(diào)用其afterPropertiesSet()方法,需要的朋友可以參考下2024-02-02SpringBoot如何監(jiān)聽redis?Key變化事件案例詳解
項目中需要監(jiān)聽redis的一些事件比如鍵刪除,修改,過期等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot如何監(jiān)聽redis?Key變化事件的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-08-08IntellIJ?IDEA顯示內(nèi)存不足的完美解決方法
IntelliJ?IDEA是一款廣泛使用的Java集成開發(fā)環(huán)境,以其強大的功能和高效的編碼體驗深受開發(fā)者喜愛,然而?在我們導(dǎo)入大項目時,?IntellIJ?Idea?向我們拋出了一個?OutOfMemoryError?內(nèi)存不足,?所以本文給大家介紹了IntellIJ?Idea顯示內(nèi)存不足的完美解決方法2025-03-03Java ArrayList的基本概念和作用及動態(tài)數(shù)組的機制與性能
在Java中,ArrayList是一個實現(xiàn)了List接口的動態(tài)數(shù)組,它可以根據(jù)需要自動增加大小,因此可以存儲任意數(shù)量的元素,這篇文章主要介紹了探秘Java ArrayList的基本概念和作用及動態(tài)數(shù)組的機制與性能,需要的朋友可以參考下2023-12-12