Java中hutool?List集合對(duì)象拷貝案例代碼
需求
三個(gè)對(duì)象,一個(gè)對(duì)象Point,一個(gè)對(duì)象CustomData。第三個(gè)對(duì)象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

完美實(shí)現(xiàn)
拓展
問了AI 很多東西牛頭不對(duì)馬尾的,方法名對(duì)不上,參數(shù)有問題啊什么的。看來還需要進(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;
/**
* 屬性過濾器,斷言通過的屬性才會(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;
/**
* 是否忽略字段大小寫
*/
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}則寫,否則忽略。如果覆蓋,則不判斷直接寫
*/
protected boolean override = true;
/**
* 自定義類型轉(zhuǎn)換器,默認(rè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);
}
/**
* 屬性過濾器,斷言通過的屬性才會(huì)被復(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è)置忽略的目標(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è)置是否忽略字段的大小寫
*
* @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è)置拷貝屬性的字段映射,用于不同的屬性之前拷貝做對(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}則寫,否則忽略。如果覆蓋,則不判斷直接寫
*
* @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)使用全局萬能轉(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忽略情況,大小寫情況、忽略字段、屬性字段映射(其實(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è)集合常見的方法
- Java?List集合取交集的五種常見方式總結(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集合常見的兩種方式
- Java集合中的List超詳細(xì)講解
相關(guān)文章
java實(shí)現(xiàn)計(jì)算器加法小程序(圖形化界面)
這篇文章主要介紹了Java實(shí)現(xiàn)圖形化界面的計(jì)算器加法小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
Springboot中@Value注解的場(chǎng)景用法及可能遇到的問題詳解
這篇文章主要給大家介紹了關(guān)于Springboot中@Value注解的場(chǎng)景用法及可能遇到問題的相關(guān)資料, @Value通常用于注入外部化屬性,即外部配置屬性的注入,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11
Spring中的InitializingBean接口源碼解析
這篇文章主要介紹了Spring中的InitializingBean接口源碼解析,InitializingBean接口為Bean初始化提供了一種方式,實(shí)現(xiàn)InitializingBean接口的Bean,在BeanFactory設(shè)置其所有屬性后會(huì)調(diào)用其afterPropertiesSet()方法,需要的朋友可以參考下2024-02-02
SpringBoot如何監(jiān)聽redis?Key變化事件案例詳解
項(xiàng)目中需要監(jiān)聽redis的一些事件比如鍵刪除,修改,過期等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot如何監(jiān)聽redis?Key變化事件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
IntellIJ?IDEA顯示內(nèi)存不足的完美解決方法
IntelliJ?IDEA是一款廣泛使用的Java集成開發(fā)環(huán)境,以其強(qiáng)大的功能和高效的編碼體驗(yàn)深受開發(fā)者喜愛,然而?在我們導(dǎo)入大項(xiàng)目時(shí),?IntellIJ?Idea?向我們拋出了一個(gè)?OutOfMemoryError?內(nèi)存不足,?所以本文給大家介紹了IntellIJ?Idea顯示內(nèi)存不足的完美解決方法2025-03-03
Java 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-12
Spring事務(wù)失效的場(chǎng)景梳理總結(jié)
實(shí)際項(xiàng)目開發(fā)中,如果涉及到多張表操作時(shí),為了保證業(yè)務(wù)數(shù)據(jù)的一致性,大家一般都會(huì)采用事務(wù)機(jī)制,好多小伙伴可能只是簡(jiǎn)單了解一下,遇到事務(wù)失效的情況,便會(huì)無從下手,下面這篇文章主要給大家介紹了關(guān)于Spring事務(wù)失效場(chǎng)景的相關(guān)資料,需要的朋友可以參考下2023-02-02

