1

Suppose I have a POJO like this:

class User {
    String id;
    String name;
    String job;

    // constructors here
}

I create a new object of user like this,

User u = new User("1", "Ash", "dev");

I need to convert this object to an array or list containing ["1", "Ash", "dev"]. Also, I need to maintain the order of values according to fields. I have implemented this using reflection. Is there any better approach?

8
  • 2
    If you want it to work with any class, reflection is the only way. You could also have your POJOs implement an interface with a toArray method or something of that sort. Commented Jan 2, 2019 at 12:16
  • Why would you want to do that? I guess that is really any of my business but I had ask. Anyway, why reflection if you know the class? Add a method that returns an array instead to the User class. Commented Jan 2, 2019 at 12:17
  • Actually, for example, I used only three fields. In reality, my POJO have lots of fields and I want to avoid use getter for each field while printing the value. If I can get the values in order I can just pass that instead. Commented Jan 2, 2019 at 12:20
  • Even using reflection won't solve you problem for sure. From Class.getDeclaredField javadoc The elements in the returned array are not sorted and are not in any particular order. Now, I would guess this will depends on the byte-code so on the same version, it is most likely to be OK but in different version, this could change. But you can always sort the fields based on the name first. Commented Jan 2, 2019 at 12:24
  • What about using an auxiliar list and putting the fields inside in the constructor order? Commented Jan 2, 2019 at 12:25

2 Answers 2

1

Here would be a simple solution to output the value always in the same order using reflection.

This is not perfect but the idea here is to show how to order the array of fields using something that should remain the same. Here the name.

public static void toArray(Object o){
    List<String> list;

    list = Arrays
            .stream(o.getClass().getDeclaredFields())
            .sorted((f1, f2) -> f1.getName().compareTo(
                    f2.getName())).map(f -> {
                try {
                    return Optional.ofNullable(f.get(o));
                } catch (Exception e) {
                    return Optional.empty();
                }
            })
            .map(opt -> opt.orElse("null"))
            .map(Object::toString)
            .collect(Collectors.toList());

    System.out.println(list);
}

And a quick example

public static void main(String[] args) {
    toArray(new TestClass("Foo", 1, 2L));
    toArray(new TestClass("Bar", 3, 4L));
    toArray(new TestClass(null, 5, 6L));
}

[1, 2, Foo]
[3, 4, Bar]
[5, 6, null]

For a more complete solution, I would use an annotation to set the position of each values but also to be able to ignore some fields.

Sign up to request clarification or add additional context in comments.

1 Comment

I use a similar approach but I got your point on using the annotations
0

You can do that in many ways!

Maybe overriding the toString Method is the thing you want!

@Override
public String toString(){
    return "[" + id + "," + name + "," + job + "]";
}

Then you can use split() method of String class to access the fields.

You can also have another method which returns an array of string containing the fields you want.

1 Comment

this doesn't solve my problem I could have generated the list or array itself. I want to avoid using getter or field variables in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.