Java中hutool?List集合對(duì)象拷貝案例代碼
需求
三個(gè)對(duì)象,一個(gè)對(duì)象Point,一個(gè)對(duì)象CustomData。第三個(gè)對(duì)象IotDataCache用來(lái)屏蔽二者差異
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
完美實(shí)現(xiàn)
拓展
問(wèn)了AI 很多東西牛頭不對(duì)馬尾的,方法名對(duì)不上,參數(shù)有問(wèn)題啊什么的。看來(lái)還需要進(jìn)步。還是得自己看源碼
copyToList方法
/** * 復(fù)制集合中的Bean屬性<br> * 此方法遍歷集合中每個(gè)Bean,復(fù)制其屬性后加入一個(gè)新的{@link List}中。 * * @param collection 原Bean集合 * @param targetType 目標(biāo)Bean類型 * @param copyOptions 拷貝選項(xiàng) * @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配置
/** * 屬性拷貝選項(xiàng)<br> * 包括:<br> * 1、限制的類或接口,必須為目標(biāo)對(duì)象的實(shí)現(xiàn)接口或父類,用于限制拷貝的屬性,例如一個(gè)類我只想復(fù)制其父類的一些屬性,就可以將editable設(shè)置為父類<br> * 2、是否忽略空值,當(dāng)源對(duì)象的值為null時(shí),true: 忽略而不注入此值,false: 注入null<br> * 3、忽略的屬性列表,設(shè)置一個(gè)屬性列表,不拷貝這些屬性值<br> * * @author Looly */ public class CopyOptions implements Serializable { private static final long serialVersionUID = 1L; /** * 限制的類或接口,必須為目標(biāo)對(duì)象的實(shí)現(xiàn)接口或父類,用于限制拷貝的屬性,例如一個(gè)類我只想復(fù)制其父類的一些屬性,就可以將editable設(shè)置為父類<br> * 如果目標(biāo)對(duì)象是Map,源對(duì)象是Bean,則作用于源對(duì)象上 */ protected Class<?> editable; /** * 是否忽略空值,當(dāng)源對(duì)象的值為null時(shí),true: 忽略而不注入此值,false: 注入null */ protected boolean ignoreNullValue; /** * 屬性過(guò)濾器,斷言通過(guò)的屬性才會(huì)被復(fù)制<br> * 斷言參數(shù)中Field為源對(duì)象的字段對(duì)象,如果源對(duì)象為Map,使用目標(biāo)對(duì)象,Object為源對(duì)象的對(duì)應(yīng)值 */ private BiPredicate<Field, Object> propertiesFilter; /** * 是否忽略字段注入錯(cuò)誤 */ protected boolean ignoreError; /** * 是否忽略字段大小寫(xiě) */ protected boolean ignoreCase; /** * 字段屬性編輯器,用于自定義屬性轉(zhuǎn)換規(guī)則,例如駝峰轉(zhuǎn)下劃線等<br> * 規(guī)則為,{@link Editor#edit(Object)}屬性為源對(duì)象的字段名稱或key,返回值為目標(biāo)對(duì)象的字段名稱或key */ private Editor<String> fieldNameEditor; /** * 字段屬性值編輯器,用于自定義屬性值轉(zhuǎn)換規(guī)則,例如null轉(zhuǎn)""等 */ protected BiFunction<String, Object, Object> fieldValueEditor; /** * 是否支持transient關(guān)鍵字修飾和@Transient注解,如果支持,被修飾的字段或方法對(duì)應(yīng)的字段將被忽略。 */ protected boolean transientSupport = true; /** * 是否覆蓋目標(biāo)值,如果不覆蓋,會(huì)先讀取目標(biāo)對(duì)象的值,非{@code null}則寫(xiě),否則忽略。如果覆蓋,則不判斷直接寫(xiě) */ protected boolean override = true; /** * 自定義類型轉(zhuǎn)換器,默認(rèn)使用全局萬(wàn)能轉(zhuǎn)換器轉(zhuǎn)換 */ protected TypeConverter converter = (type, value) -> Convert.convertWithCheck(type, value, null, ignoreError); //region create /** * 創(chuàng)建拷貝選項(xiàng) * * @return 拷貝選項(xiàng) */ public static CopyOptions create() { return new CopyOptions(); } /** * 創(chuàng)建拷貝選項(xiàng) * * @param editable 限制的類或接口,必須為目標(biāo)對(duì)象的實(shí)現(xiàn)接口或父類,用于限制拷貝的屬性 * @param ignoreNullValue 是否忽略空值,當(dāng)源對(duì)象的值為null時(shí),true: 忽略而不注入此值,false: 注入null * @param ignoreProperties 忽略的屬性列表,設(shè)置一個(gè)屬性列表,不拷貝這些屬性值 * @return 拷貝選項(xiàng) */ public static CopyOptions create(Class<?> editable, boolean ignoreNullValue, String... ignoreProperties) { return new CopyOptions(editable, ignoreNullValue, ignoreProperties); } //endregion /** * 構(gòu)造拷貝選項(xiàng) */ public CopyOptions() { } /** * 構(gòu)造拷貝選項(xiàng) * * @param editable 限制的類或接口,必須為目標(biāo)對(duì)象的實(shí)現(xiàn)接口或父類,用于限制拷貝的屬性 * @param ignoreNullValue 是否忽略空值,當(dāng)源對(duì)象的值為null時(shí),true: 忽略而不注入此值,false: 注入null * @param ignoreProperties 忽略的目標(biāo)對(duì)象中屬性列表,設(shè)置一個(gè)屬性列表,不拷貝這些屬性值 */ public CopyOptions(Class<?> editable, boolean ignoreNullValue, String... ignoreProperties) { this.propertiesFilter = (f, v) -> true; this.editable = editable; this.ignoreNullValue = ignoreNullValue; this.setIgnoreProperties(ignoreProperties); } /** * 設(shè)置限制的類或接口,必須為目標(biāo)對(duì)象的實(shí)現(xiàn)接口或父類,用于限制拷貝的屬性 * * @param editable 限制的類或接口 * @return CopyOptions */ public CopyOptions setEditable(Class<?> editable) { this.editable = editable; return this; } /** * 設(shè)置是否忽略空值,當(dāng)源對(duì)象的值為null時(shí),true: 忽略而不注入此值,false: 注入null * * @param ignoreNullVall 是否忽略空值,當(dāng)源對(duì)象的值為null時(shí),true: 忽略而不注入此值,false: 注入null * @return CopyOptions */ public CopyOptions setIgnoreNullValue(boolean ignoreNullVall) { this.ignoreNullValue = ignoreNullVall; return this; } /** * 設(shè)置忽略空值,當(dāng)源對(duì)象的值為null時(shí),忽略而不注入此值 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreNullValue() { return setIgnoreNullValue(true); } /** * 屬性過(guò)濾器,斷言通過(guò)的屬性才會(huì)被復(fù)制<br> * {@link BiPredicate#test(Object, Object)}返回{@code true}則屬性通過(guò),{@code false}不通過(guò),拋棄之 * * @param propertiesFilter 屬性過(guò)濾器 * @return CopyOptions */ public CopyOptions setPropertiesFilter(BiPredicate<Field, Object> propertiesFilter) { this.propertiesFilter = propertiesFilter; return this; } /** * 設(shè)置忽略的目標(biāo)對(duì)象中屬性列表,設(shè)置一個(gè)屬性列表,不拷貝這些屬性值 * * @param ignoreProperties 忽略的目標(biāo)對(duì)象中屬性列表,設(shè)置一個(gè)屬性列表,不拷貝這些屬性值 * @return CopyOptions */ public CopyOptions setIgnoreProperties(String... ignoreProperties) { return setPropertiesFilter((field, o) -> false == ArrayUtil.contains(ignoreProperties, field.getName())); } /** * 設(shè)置忽略的目標(biāo)對(duì)象中屬性列表,設(shè)置一個(gè)屬性列表,不拷貝這些屬性值,Lambda方式 * * @param <P> 參數(shù)類型 * @param <R> 返回值類型 * @param funcs 忽略的目標(biāo)對(duì)象中屬性列表,設(shè)置一個(gè)屬性列表,不拷貝這些屬性值 * @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è)置是否忽略字段的注入錯(cuò)誤 * * @param ignoreError 是否忽略注入錯(cuò)誤 * @return CopyOptions */ public CopyOptions setIgnoreError(boolean ignoreError) { this.ignoreError = ignoreError; return this; } /** * 設(shè)置忽略字段的注入錯(cuò)誤 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreError() { return setIgnoreError(true); } /** * 設(shè)置是否忽略字段的大小寫(xiě) * * @param ignoreCase 是否忽略大小寫(xiě) * @return CopyOptions */ public CopyOptions setIgnoreCase(boolean ignoreCase) { this.ignoreCase = ignoreCase; return this; } /** * 設(shè)置忽略字段的大小寫(xiě) * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreCase() { return setIgnoreCase(true); } /** * 設(shè)置拷貝屬性的字段映射,用于不同的屬性之前拷貝做對(duì)應(yīng)表用 * * @param fieldMapping 拷貝屬性的字段映射,用于不同的屬性之前拷貝做對(duì)應(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)換器只針對(duì)源端的字段做轉(zhuǎn)換,請(qǐng)確認(rèn)轉(zhuǎn)換后與目標(biāo)端字段一致<br> * 當(dāng)轉(zhuǎn)換后的字段名為null時(shí)忽略這個(gè)字段 * * @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注解,如果支持,被修飾的字段或方法對(duì)應(yīng)的字段將被忽略。 * * @param transientSupport 是否支持 * @return this * @since 5.4.2 */ public CopyOptions setTransientSupport(boolean transientSupport) { this.transientSupport = transientSupport; return this; } /** * 設(shè)置是否覆蓋目標(biāo)值,如果不覆蓋,會(huì)先讀取目標(biāo)對(duì)象的值,非{@code null}則寫(xiě),否則忽略。如果覆蓋,則不判斷直接寫(xiě) * * @param override 是否覆蓋目標(biāo)值 * @return this * @since 5.7.17 */ public CopyOptions setOverride(boolean override) { this.override = override; return this; } /** * 設(shè)置自定義類型轉(zhuǎn)換器,默認(rèn)使用全局萬(wà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 目標(biāo)類型 * @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; } /** * 測(cè)試是否保留字段,{@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忽略情況,大小寫(xiě)情況、忽略字段、屬性字段映射(其實(shí)就是fieldNameEditor)。各位成功!
總結(jié)
到此這篇關(guān)于Java中hutool List集合對(duì)象拷貝的文章就介紹到這了,更多相關(guān)Java hutool List集合對(duì)象拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java集合List快速實(shí)現(xiàn)重復(fù)判斷的方法小結(jié)
- Java?hutool?List集合對(duì)象拷貝示例代碼
- java的list集合排序自定義元素方式
- Java將不同的List集合復(fù)制到另一個(gè)集合常見(jiàn)的方法
- Java?List集合取交集的五種常見(jiàn)方式總結(jié)
- Java?List集合取交集的8種不同實(shí)現(xiàn)方式總結(jié)
- java取出list中某幾個(gè)屬性組成一個(gè)新集合的幾種方式
- Java實(shí)現(xiàn)List集合手動(dòng)分頁(yè)的方法
- java如何獲取兩個(gè)List集合之間的交集、差集、并集
- Java中Set集合轉(zhuǎn)為L(zhǎng)ist集合常見(jiàn)的兩種方式
- Java集合中的List超詳細(xì)講解
相關(guān)文章
java實(shí)現(xiàn)計(jì)算器加法小程序(圖形化界面)
這篇文章主要介紹了Java實(shí)現(xiàn)圖形化界面的計(jì)算器加法小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05Springboot中@Value注解的場(chǎng)景用法及可能遇到的問(wèn)題詳解
這篇文章主要給大家介紹了關(guān)于Springboot中@Value注解的場(chǎng)景用法及可能遇到問(wèn)題的相關(guān)資料, @Value通常用于注入外部化屬性,即外部配置屬性的注入,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11Spring中的InitializingBean接口源碼解析
這篇文章主要介紹了Spring中的InitializingBean接口源碼解析,InitializingBean接口為Bean初始化提供了一種方式,實(shí)現(xiàn)InitializingBean接口的Bean,在BeanFactory設(shè)置其所有屬性后會(huì)調(diào)用其afterPropertiesSet()方法,需要的朋友可以參考下2024-02-02SpringBoot如何監(jiān)聽(tīng)redis?Key變化事件案例詳解
項(xiàng)目中需要監(jiān)聽(tīng)redis的一些事件比如鍵刪除,修改,過(guò)期等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot如何監(jiān)聽(tīng)redis?Key變化事件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08IntellIJ?IDEA顯示內(nèi)存不足的完美解決方法
IntelliJ?IDEA是一款廣泛使用的Java集成開(kāi)發(fā)環(huán)境,以其強(qiáng)大的功能和高效的編碼體驗(yàn)深受開(kāi)發(fā)者喜愛(ài),然而?在我們導(dǎo)入大項(xiàng)目時(shí),?IntellIJ?Idea?向我們拋出了一個(gè)?OutOfMemoryError?內(nèi)存不足,?所以本文給大家介紹了IntellIJ?Idea顯示內(nèi)存不足的完美解決方法2025-03-03Java ArrayList的基本概念和作用及動(dòng)態(tài)數(shù)組的機(jī)制與性能
在Java中,ArrayList是一個(gè)實(shí)現(xiàn)了List接口的動(dòng)態(tài)數(shù)組,它可以根據(jù)需要自動(dòng)增加大小,因此可以存儲(chǔ)任意數(shù)量的元素,這篇文章主要介紹了探秘Java ArrayList的基本概念和作用及動(dòng)態(tài)數(shù)組的機(jī)制與性能,需要的朋友可以參考下2023-12-12Spring事務(wù)失效的場(chǎng)景梳理總結(jié)
實(shí)際項(xiàng)目開(kāi)發(fā)中,如果涉及到多張表操作時(shí),為了保證業(yè)務(wù)數(shù)據(jù)的一致性,大家一般都會(huì)采用事務(wù)機(jī)制,好多小伙伴可能只是簡(jiǎn)單了解一下,遇到事務(wù)失效的情況,便會(huì)無(wú)從下手,下面這篇文章主要給大家介紹了關(guān)于Spring事務(wù)失效場(chǎng)景的相關(guān)資料,需要的朋友可以參考下2023-02-02