feiyu02
2025-09-30 94fee0b511279679b43e210878d3d36e5a14384b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.flightfeather.uav.common.utils
 
import kotlin.reflect.KProperty1
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.jvm.isAccessible
 
/**
 * 对象转换为键对值map结构
 * @date 2025/8/28 10:19
 * @author feiyu
 */
object ObjToMapUtil {
 
    /**
     * 将对象转换为Map结构(支持嵌套对象递归转换)
     * @param obj 待转换的对象(非空)
     * @return 包含对象属性名和值的Map,嵌套对象会转换为Map,集合/数组会递归处理元素
     */
    fun <T : Any> objectToMap(obj: T): Map<String, Any> {
        return obj::class.declaredMemberProperties.associate { property ->
            property.isAccessible = true
            val value = try {
                (property as KProperty1<T, *>).get(obj) } catch (e: Exception) { null }
            property.name to processValue(value)
        }
    }
 
    /**
     * 递归处理属性值,将嵌套对象转换为Map,集合/数组递归处理元素
     */
    private fun processValue(value: Any?): Any {
        return when {
            value == null -> ""
            // 处理集合类型(List/Set)
            value is Collection<*> -> value.map { processValue(it) }
            // 处理Map类型(转换值)
            value is Map<*, *> -> value.mapValues { processValue(it.value) }
            // 处理数组类型
            value.javaClass.isArray -> (value as Array<*>).map { processValue(it) }
            // 处理自定义对象(递归转换)
            isCustomObject(value) -> objectToMap(value)
            // 基础类型(Int/String/Boolean等)直接返回
            else -> value
        }
    }
 
    /**
     * 判断是否为需要递归转换的自定义对象
     */
    private fun isCustomObject(value: Any): Boolean {
        val clazz = value::class.java
        return !clazz.isPrimitive &&
                !clazz.isEnum &&
                value !is String &&
                value !is Number &&
                value !is Boolean &&
                value !is Char &&
                value !is Collection<*> &&
                value !is Map<*, *> &&
                !clazz.isArray
    }
}