วิธีการแปลงวัตถุ Java (bean) เป็นคู่คีย์ - ค่า (และในทางกลับกัน)?


93

สมมติว่าฉันมีวัตถุ java ที่เรียบง่ายซึ่งมีคุณสมบัติ getXXX และ setXXX บางอย่างเท่านั้น อ็อบเจ็กต์นี้ใช้เพื่อจัดการกับค่าเท่านั้นโดยทั่วไปคือเรกคอร์ดหรือแผนที่ชนิดปลอดภัย (และตัวแสดง) ฉันมักจะต้องแอบแฝงวัตถุนี้เป็นคู่ค่าคีย์ (สตริงหรือประเภทปลอดภัย) หรือแปลงจากคู่ค่าคีย์เป็นวัตถุนี้

นอกเหนือจากการสะท้อนกลับหรือเขียนโค้ดด้วยตนเองเพื่อทำการแปลงนี้วิธีใดที่ดีที่สุดในการบรรลุเป้าหมายนี้

ตัวอย่างอาจส่งวัตถุนี้ผ่าน jms โดยไม่ใช้ประเภท ObjectMessage (หรือแปลงข้อความขาเข้าเป็นชนิดของวัตถุที่ถูกต้อง)


java.beans.Introspector.getBeanInfo(). มันถูกสร้างขึ้นใน JDK
Marquis of Lorne

คำตอบ:


53

มักจะมีถั่วลิสง apache คอมมอนส์อยู่เสมอแต่แน่นอนว่ามันใช้การสะท้อนใต้ฝากระโปรง


8
นอกจากนี้ไม่มีอะไรผิดเกี่ยวกับการใช้การสะท้อนแสงภายใต้ฝากระโปรง โดยเฉพาะอย่างยิ่งถ้าผลลัพธ์ถูกแคชไว้ (สำหรับการใช้งานในอนาคต) การเข้าถึงโดยอิงจากการสะท้อนมักจะเร็วพอสำหรับกรณีการใช้งานส่วนใหญ่
StaxMan

22
เพื่อความแม่นยำ BeanMap (ถั่ว) เป็นส่วนเฉพาะของ beanutils ทั่วไปที่ทำเคล็ดลับ
vdr

3
ไม่คำนึงถึงการพิจารณาประสิทธิภาพฉันพบว่าการใช้ BeanMap () ร่วมกับ ObjectMapper ของ Jackson จากคำตอบด้านล่างทำให้ฉันได้ผลลัพธ์ที่ดีที่สุด BeanMap ประสบความสำเร็จในการสร้างแผนที่ที่สมบูรณ์ยิ่งขึ้นของวัตถุของฉันจากนั้นแจ็คสันก็แปลงเป็นโครงสร้าง LinkedHashMap ธรรมดาซึ่งอนุญาตให้มีการปรับเปลี่ยนไปตามท่อ objectAsMap = objectMapper.convertValue (BeanMap ใหม่ (myObject), Map.class);
michaelr524

จะไม่ทำงานบน Android เนื่องจากใช้การjava.beansอ้างอิงที่ จำกัด อย่างรุนแรงบนแพลตฟอร์ม ดูคำถามที่เกี่ยวข้องสำหรับรายละเอียด
SqueezyMo

โซลูชันที่กล่าวถึง Apache Commons มักเป็นทางออกที่ดีที่สุด
рüффп

179

วิธีแก้ปัญหาที่เป็นไปได้มากมาย แต่ขอเพิ่มอีกหนึ่งข้อ ใช้Jackson (JSON processing lib) เพื่อทำการแปลง "json-less" เช่น:

ObjectMapper m = new ObjectMapper();
Map<String,Object> props = m.convertValue(myBean, Map.class);
MyBean anotherBean = m.convertValue(props, MyBean.class);

( รายการบล็อกนี้มีตัวอย่างเพิ่มเติม)

โดยทั่วไปคุณสามารถแปลงประเภทที่เข้ากันได้: หมายความว่าเข้ากันได้ว่าถ้าคุณแปลงจากประเภทเป็น JSON และจาก JSON นั้นเป็นประเภทผลลัพธ์รายการจะตรงกัน (หากกำหนดค่าอย่างถูกต้องสามารถละเว้นประเภทที่ไม่รู้จักได้)

ใช้งานได้ดีกับกรณีที่คาดหวังรวมถึง Maps, Lists, อาร์เรย์, แบบดั้งเดิม, POJO แบบถั่ว


2
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ BeanUtilsเป็นสิ่งที่ดี แต่ไม่สามารถจัดการอาร์เรย์และ enums ได้
Manish Patel

8

การสร้างรหัสจะเป็นวิธีเดียวที่ฉันคิดได้ โดยส่วนตัวแล้วฉันได้รับโซลูชันการสะท้อนกลับที่ใช้ซ้ำได้โดยทั่วไป (เว้นแต่ส่วนนั้นของโค้ดจะมีความสำคัญต่อประสิทธิภาพอย่างยิ่ง) การใช้ JMS ดูเหมือน overkill (การพึ่งพาเพิ่มเติมและนั่นไม่ใช่สิ่งที่หมายถึง) นอกจากนี้อาจใช้การสะท้อนเช่นกันภายใต้ฝากระโปรง


ประสิทธิภาพเป็นสิ่งสำคัญดังนั้นฉันคิดว่าการสะท้อนออกมา ฉันหวังว่าอาจมีเครื่องมือบางอย่างที่ใช้ asm หรือ cglib ฉันได้เริ่มดูบัฟเฟอร์โปรโตคอลของ Google อีกครั้ง ฉันไม่ได้รับความคิดเห็นของคุณเกี่ยวกับ JMS ฉันใช้มันเพื่อสื่อสารข้อมูลข้ามเครื่อง
Shahbaz

ฉันเข้าใจผิดว่า ในด้านประสิทธิภาพมีความแตกต่างระหว่างประสิทธิภาพที่สำคัญและส่วนที่เฉพาะเจาะจงนั้นสำคัญต่อประสิทธิภาพ ฉันจะทำการเปรียบเทียบเพื่อดูว่ามันสำคัญแค่ไหนเมื่อเทียบกับสิ่งอื่นที่แอปพลิเคชันกำลังทำอยู่
Michael Borgwardt

นั่นก็เป็นความคิดของฉันเช่นกัน ไม่ว่าคุณจะใช้การสะท้อน (โดยตรงหรือโดยอ้อม) หรือคุณต้องสร้างโค้ด (หรือเขียนโค้ดเสริมด้วยตัวเองแน่นอน).
ภายนอก

8

นี่เป็นวิธีการแปลงวัตถุ Java เป็นแผนที่

public static Map<String, Object> ConvertObjectToMap(Object obj) throws 
    IllegalAccessException, 
    IllegalArgumentException, 
    InvocationTargetException {
        Class<?> pomclass = obj.getClass();
        pomclass = obj.getClass();
        Method[] methods = obj.getClass().getMethods();


        Map<String, Object> map = new HashMap<String, Object>();
        for (Method m : methods) {
           if (m.getName().startsWith("get") && !m.getName().startsWith("getClass")) {
              Object value = (Object) m.invoke(obj);
              map.put(m.getName().substring(3), (Object) value);
           }
        }
    return map;
}

นี่คือวิธีการเรียกมัน

   Test test = new Test()
   Map<String, Object> map = ConvertObjectToMap(test);

1
ฉันไม่คิดว่าคำตอบที่ต้องการจะวนซ้ำวิธีการที่กำหนดไว้ในแต่ละวัตถุฟังดูเหมือนการสะท้อน
Robert Karl

2
ฉันไม่รู้ว่าจุดประสงค์ของคุณคือวิธีการของคุณ แต่ฉันคิดว่านี่เป็นตัวอย่างที่ยอดเยี่ยมมากเมื่อคุณต้องการเขียนโปรแกรมด้วยวัตถุประเภททั่วไป
DeXoN

6

อาจจะสายไปงานปาร์ตี้ คุณสามารถใช้ Jackson และแปลงเป็นวัตถุ Properties ได้ สิ่งนี้เหมาะสำหรับคลาสที่ซ้อนกันและหากคุณต้องการคีย์ใน for abc = value

JavaPropsMapper mapper = new JavaPropsMapper();
Properties properties = mapper.writeValueAsProperties(sct);
Map<Object, Object> map = properties;

ถ้าคุณต้องการคำต่อท้ายก็ทำ

SerializationConfig config = mapper.getSerializationConfig()
                .withRootName("suffix");
mapper.setConfig(config);

จำเป็นต้องเพิ่มการอ้างอิงนี้

<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-properties</artifactId>
</dependency>

4

ด้วย Java 8 คุณสามารถลองสิ่งนี้:

public Map<String, Object> toKeyValuePairs(Object instance) {
    return Arrays.stream(Bean.class.getDeclaredMethods())
            .collect(Collectors.toMap(
                    Method::getName,
                    m -> {
                        try {
                            Object result = m.invoke(instance);
                            return result != null ? result : "";
                        } catch (Exception e) {
                            return "";
                        }
                    }));
}

3

JSONเช่นการใช้ XStream + Jettison เป็นรูปแบบข้อความธรรมดาที่มีคู่คีย์ค่า ได้รับการสนับสนุนโดยนายหน้าข้อความ Apache ActiveMQ JMS สำหรับการแลกเปลี่ยนวัตถุ Java กับแพลตฟอร์ม / ภาษาอื่น ๆ


3

เพียงแค่ใช้การสะท้อนและ Groovy:

def Map toMap(object) {             
return object?.properties.findAll{ (it.key != 'class') }.collectEntries {
            it.value == null || it.value instanceof Serializable ? [it.key, it.value] : [it.key,   toMap(it.value)]
    }   
}

def toObject(map, obj) {        
    map.each {
        def field = obj.class.getDeclaredField(it.key)
        if (it.value != null) {
            if (field.getType().equals(it.value.class)){
                obj."$it.key" = it.value
            }else if (it.value instanceof Map){
                def objectFieldValue = obj."$it.key"
                def fieldValue = (objectFieldValue == null) ? field.getType().newInstance() : objectFieldValue
                obj."$it.key" = toObject(it.value,fieldValue) 
            }
        }
    }
    return obj;
}

เจ๋ง แต่มีแนวโน้มที่จะ StackOverflowError
Teo Choong Ping

3

ใช้juffrou-reflect reflect มันมีประสิทธิภาพมาก

นี่คือวิธีที่คุณสามารถเปลี่ยนถั่วเป็นแผนที่:

public static Map<String, Object> getBeanMap(Object bean) {
    Map<String, Object> beanMap = new HashMap<String, Object>();
    BeanWrapper beanWrapper = new BeanWrapper(BeanWrapperContext.create(bean.getClass()));
    for(String propertyName : beanWrapper.getPropertyNames())
        beanMap.put(propertyName, beanWrapper.getValue(propertyName));
    return beanMap;
}

ฉันพัฒนา Juffrou ด้วยตัวเอง เป็นโอเพนซอร์สดังนั้นคุณจึงมีอิสระที่จะใช้และแก้ไข และหากคุณมีคำถามใด ๆ เกี่ยวกับเรื่องนี้เรายินดีเป็นอย่างยิ่งที่จะตอบกลับ

ไชโย

คาร์ลอส


ฉันคิดเกี่ยวกับเรื่องนี้และตระหนักว่าวิธีแก้ปัญหาก่อนหน้านี้ของฉันพังถ้าคุณมีการอ้างอิงแบบวงกลมในกราฟถั่ว ดังนั้นฉันจึงพัฒนาวิธีการที่จะทำอย่างโปร่งใสและจัดการการอ้างอิงแบบวงกลมได้อย่างสวยงาม ตอนนี้คุณสามารถแปลงถั่วเป็นแผนที่และในทางกลับกันด้วย juffrou-reflect Enjoy :)
Martins

3

เมื่อใช้ Spring เราสามารถใช้ Spring Integration object-to-map-transformer อาจไม่คุ้มค่าที่จะเพิ่ม Spring เป็นการพึ่งพาเพียงแค่นี้

สำหรับเอกสารให้ค้นหา "Object-to-Map Transformer" ในhttp://docs.spring.io/spring-integration/docs/4.0.4.RELEASE/reference/html/messaging-transformation-chapter.html

โดยพื้นฐานแล้วมันจะข้ามกราฟวัตถุทั้งหมดที่สามารถเข้าถึงได้จากวัตถุที่กำหนดให้เป็นอินพุตและสร้างแผนที่จากฟิลด์ประเภท / สตริงดั้งเดิมทั้งหมดบนวัตถุ สามารถกำหนดค่าให้เอาต์พุตได้:

  • แผนที่แบบแบน: {rootObject.someField = Joe, rootObject.leafObject.someField = Jane} หรือ
  • แผนที่ที่มีโครงสร้าง: {someField = Joe, leafObject = {someField = Jane}}

นี่คือตัวอย่างจากเพจของพวกเขา:

public class Parent{
    private Child child;
    private String name; 
    // setters and getters are omitted
}

public class Child{
   private String name; 
   private List<String> nickNames;
   // setters and getters are omitted
}

ผลลัพธ์จะเป็น:

{person.name = George, person.child.name = Jenna, person.child.nickNames [0] = Bimbo . . ฯลฯ }

นอกจากนี้ยังมีหม้อแปลงไฟฟ้าย้อนกลับ


2

คุณสามารถใช้ Joda framework:

http://joda.sourceforge.net/

และใช้ประโยชน์จาก JodaProperties สิ่งนี้กำหนดให้คุณสร้างถั่วด้วยวิธีเฉพาะและใช้อินเทอร์เฟซเฉพาะ อย่างไรก็ตามจะอนุญาตให้คุณส่งคืนแผนที่คุณสมบัติจากคลาสเฉพาะโดยไม่ต้องสะท้อนกลับ โค้ดตัวอย่างอยู่ที่นี่:

http://pbin.oogly.co.uk/listings/viewlistingdetail/0e78eb6c76d071b4e22bbcac748c57


ดูน่าสนใจน่าเสียดายที่ดูเหมือนไม่ได้รับการบำรุงรักษาอีกต่อไป นอกจากนี้แผนที่คุณสมบัติที่ส่งคืนเป็นแผนที่ของ <String, String> ดังนั้นอย่าพิมพ์ปลอดภัย
Shahbaz

1
จริงอยู่ที่มันไม่ได้รับการดูแลมาตั้งแต่ปี 2002 ฉันแค่อยากรู้ว่ามีโซลูชันแบบไม่สะท้อนแสงหรือไม่ แผนที่คุณสมบัติที่ส่งคืนเป็นเพียงแผนที่มาตรฐานไม่มีชื่อสามัญเช่นนี้ ...
จอน

2

หากคุณไม่ต้องการฮาร์ดโค้ดเรียกไปยัง getter และ setter แต่ละตัวการสะท้อนเป็นวิธีเดียวที่จะเรียกเมธอดเหล่านี้ (แต่ก็ไม่ยาก)

คุณสามารถ refactor คลาสที่เป็นปัญหาเพื่อใช้ออบเจ็กต์ Properties เพื่อเก็บข้อมูลจริงและปล่อยให้ getter และ setter แต่ละตัวเรียก get / set ได้หรือไม่? จากนั้นคุณจะมีโครงสร้างที่เหมาะสมกับสิ่งที่คุณต้องการทำ มีแม้กระทั่งวิธีการบันทึกและโหลดในรูปแบบคีย์ - ค่า


ไม่มีวิธีการใด ๆ เพราะขึ้นอยู่กับคุณว่าอะไรคือกุญแจและคุณค่าคืออะไร! ควรเขียนบริการที่ทำ Conversion ดังกล่าวได้ง่าย สำหรับ CSV ที่เป็นตัวแทนอย่างง่ายอาจยอมรับได้
Martin K.

2

ทางออกที่ดีที่สุดคือการใช้ Dozer คุณต้องการสิ่งนี้ในไฟล์ mapper:

<mapping map-id="myTestMapping">
  <class-a>org.dozer.vo.map.SomeComplexType</class-a>
  <class-b>java.util.Map</class-b>
</mapping> 

แค่นี้แหละ Dozer ดูแลส่วนที่เหลือ !!!

URL เอกสาร Dozer


เหตุใดจึงต้องใช้ไฟล์การแมป ถ้ามันรู้วิธีการแปลงเหตุใดจึงต้องใช้งานพิเศษนี้ - เพียงแค่ใช้วัตถุต้นทางประเภทที่คาดหวัง
StaxMan

ตกลง. เป็นเรื่องดีที่รู้เหตุผลแม้ว่าฉันจะไม่แน่ใจว่าถูกต้อง
ก็ตาม

2

แน่นอนว่ามีวิธีการแปลงที่ง่ายที่สุดแน่นอน - ไม่มีการแปลงเลย!

แทนที่จะใช้ตัวแปรส่วนตัวที่กำหนดไว้ในคลาสทำให้คลาสมีเฉพาะ HashMap ที่เก็บค่าสำหรับอินสแตนซ์

จากนั้น getters และ setters ของคุณจะส่งคืนและกำหนดค่าเข้าและออกจาก HashMap และเมื่อถึงเวลาที่ต้องแปลงเป็นแผนที่ voila! - มันเป็นแผนที่อยู่แล้ว

ด้วยเวทมนตร์ AOP เล็กน้อยคุณสามารถรักษาความยืดหยุ่นที่มีอยู่ใน bean ได้โดยอนุญาตให้คุณยังคงใช้ getters และ setters เฉพาะสำหรับแต่ละชื่อค่าโดยไม่ต้องเขียน getters และ setters แต่ละตัว


2

คุณสามารถใช้คุณสมบัติตัวกรองสตรีม java 8

public Map<String, Object> objectToMap(Object obj) {
    return Arrays.stream(YourBean.class.getDeclaredMethods())
            .filter(p -> !p.getName().startsWith("set"))
            .filter(p -> !p.getName().startsWith("getClass"))
            .filter(p -> !p.getName().startsWith("setClass"))
            .collect(Collectors.toMap(
                    d -> d.getName().substring(3),
                    m -> {
                        try {
                            Object result = m.invoke(obj);
                            return result;
                        } catch (Exception e) {
                            return "";
                        }
                    }, (p1, p2) -> p1)
            );
}

1

โปรเซสเซอร์คำอธิบายประกอบ JavaDude Bean ของฉันสร้างโค้ดเพื่อทำสิ่งนี้

http://javadude.googlecode.com

ตัวอย่างเช่น:

@Bean(
  createPropertyMap=true,
  properties={
    @Property(name="name"),
    @Property(name="phone", bound=true),
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
  }
)
public class Person extends PersonGen {}

ข้างต้นสร้าง superclass PersonGen ที่มีเมธอด createPropertyMap () ที่สร้างแผนที่สำหรับคุณสมบัติทั้งหมดที่กำหนดโดยใช้ @Bean

(โปรดทราบว่าฉันกำลังเปลี่ยน API เล็กน้อยสำหรับเวอร์ชันถัดไป - แอตทริบิวต์คำอธิบายประกอบจะเป็น defineCreatePropertyMap = true)


คุณได้ทำการตรวจสอบโค้ดแล้วหรือยัง? การกระทำนี้ดูเหมือนจะไม่ใช่แนวทางที่ดี! คุณเปลี่ยนเส้นทางการสืบทอดด้วยคำอธิบายประกอบ! จะเกิดอะไรขึ้นถ้าถั่วขยายไปแล้วในชั้นเรียน! ทำไมคุณต้องเขียนแอตทริบิวต์สองครั้ง?
Martin K.

หากคุณมีซูเปอร์คลาสอยู่แล้วให้ใช้ @Bean (superclass = XXX.class, ... ) และแทรกซูเปอร์คลาสที่สร้างขึ้นระหว่าง นี่เป็นสิ่งที่ดีสำหรับการตรวจทานโค้ด - แบบสำเร็จรูปที่อาจเกิดข้อผิดพลาดได้น้อยกว่ามาก
Scott Stanchfield

ไม่แน่ใจว่าคุณหมายถึงอะไรโดย "เขียนแอตทริบิวต์สองครั้ง" ซึ่งจะแสดงขึ้นสองครั้งที่ไหน
Scott Stanchfield

@Martin K. ถ้าคุณไม่ต้องการใช้การสะท้อนแม้จะอยู่ภายใต้ประทุนคุณอาจถูกบังคับให้สร้างรหัสบางประเภท
extraneon

1

คุณควรเขียนบริการแปลงร่างทั่วไป! ใช้ generics เพื่อให้พิมพ์ฟรี (เพื่อให้คุณสามารถแปลงทุกออบเจ็กต์เป็น key => value และ back)

ฟิลด์ใดควรเป็นคีย์? รับฟิลด์นั้นจาก bean และต่อท้ายค่าอื่น ๆ ที่ไม่ใช่ชั่วคราวในแผนที่ค่า

ทางกลับค่อนข้างง่าย อ่านคีย์ (x) และเขียนคีย์ก่อนจากนั้นทุกรายการกลับไปที่อ็อบเจ็กต์ใหม่

คุณสามารถรับชื่อคุณสมบัติของถั่วด้วยถั่วapache คอมมอนส์ !


1

หากคุณต้องการประสิทธิภาพจริงๆคุณสามารถไปที่เส้นทางการสร้างรหัสได้

คุณสามารถทำสิ่งนี้ต่อไปได้โดยทำการสะท้อนของคุณเองและสร้าง AspectJ ITD แบบผสมผสาน

หรือคุณสามารถใช้ Spring Roo และสร้างSpring Roo AddonAddon ส่วนเสริม Roo ของคุณจะทำสิ่งที่คล้ายกับข้างต้น แต่จะพร้อมใช้งานสำหรับทุกคนที่ใช้ Spring Roo และคุณไม่จำเป็นต้องใช้คำอธิบายประกอบแบบรันไทม์

ฉันได้ทำทั้งสองอย่างแล้ว ผู้คนเบื่อหน่ายใน Spring Roo แต่มันเป็นการสร้างโค้ดที่ครอบคลุมที่สุดสำหรับ Java


1

อีกวิธีหนึ่งที่เป็นไปได้อยู่ที่นี่

BeanWrapper มีฟังก์ชันในการตั้งค่าและรับค่าคุณสมบัติ (เป็นรายบุคคลหรือจำนวนมาก) รับตัวบอกคุณสมบัติและสอบถามคุณสมบัติเพื่อพิจารณาว่าสามารถอ่านหรือเขียนได้หรือไม่

Company c = new Company();
 BeanWrapper bwComp = BeanWrapperImpl(c);
 bwComp.setPropertyValue("name", "your Company");

1

หากพูดถึงโครงสร้างออบเจ็กต์แบบธรรมดาไปจนถึงการแมปรายการค่าคีย์โดยที่คีย์อาจเป็นคำอธิบายเส้นทางแบบประจากองค์ประกอบรูทของอ็อบเจ็กต์ไปจนถึงลีฟที่กำลังตรวจสอบค่อนข้างชัดเจนว่าการแปลงทรีเป็นรายการคีย์ - ค่านั้นเปรียบได้กับ วัตถุในการแมป xml แต่ละองค์ประกอบภายในเอกสาร XML มีตำแหน่งที่กำหนดและสามารถแปลงเป็นเส้นทางได้ ดังนั้นฉันจึงใช้XStreamเป็นเครื่องมือการแปลงพื้นฐานและมีเสถียรภาพและแทนที่ไดรเวอร์ลำดับชั้นและชิ้นส่วนตัวเขียนด้วยการใช้งานของตัวเอง XStream ยังมาพร้อมกับกลไกการติดตามเส้นทางพื้นฐานซึ่ง - เมื่อรวมกับอีกสองรายการ - นำไปสู่โซลูชันที่เหมาะสมกับงานอย่างเคร่งครัด


1

ด้วยความช่วยเหลือของไลบรารี Jackson ฉันสามารถค้นหาคุณสมบัติคลาสทั้งหมดของประเภท String / integer / double และค่าตามลำดับในคลาส Map ( โดยไม่ต้องใช้ API การสะท้อน! )

TestClass testObject = new TestClass();
com.fasterxml.jackson.databind.ObjectMapper m = new com.fasterxml.jackson.databind.ObjectMapper();

Map<String,Object> props = m.convertValue(testObject, Map.class);

for(Map.Entry<String, Object> entry : props.entrySet()){
    if(entry.getValue() instanceof String || entry.getValue() instanceof Integer || entry.getValue() instanceof Double){
        System.out.println(entry.getKey() + "-->" + entry.getValue());
    }
}

0

โดยใช้ Gson

  1. แปลง POJO objectเป็น Json
  2. แปลง Json เป็น Map

        retMap = new Gson().fromJson(new Gson().toJson(object), 
                new TypeToken<HashMap<String, Object>>() {}.getType()
        );
    

0

เราสามารถใช้ไลบรารี Jackson เพื่อแปลงวัตถุ Java เป็นแผนที่ได้อย่างง่ายดาย

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.6.3</version>
</dependency>

หากใช้ในโปรเจ็กต์ Android คุณสามารถเพิ่มแจ็คสันใน build.gradle ของแอพได้ดังนี้:

implementation 'com.fasterxml.jackson.core:jackson-core:2.9.8'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.9.8'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'

การใช้งานตัวอย่าง

public class Employee {

    private String name;
    private int id;
    private List<String> skillSet;

    // getters setters
}

public class ObjectToMap {

 public static void main(String[] args) {

    ObjectMapper objectMapper = new ObjectMapper();

    Employee emp = new Employee();
    emp.setName("XYZ");
    emp.setId(1011);
    emp.setSkillSet(Arrays.asList("python","java"));

    // object -> Map
    Map<String, Object> map = objectMapper.convertValue(emp, 
    Map.class);
    System.out.println(map);

 }

}

เอาท์พุต:

{name = XYZ, id = 1011, skills = [python, java]}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.