-2

I have 3 big domain classes like below, and I need their values as a string array like in the example.

It is very time consuming and error prone to write all fields one by one like this, is there a quick way to this? It will iterate over all fields and get their string values?

Maybe with guava or reflection?

Class Cart1{


 //Domain class with 100s of Items with getters and setters
 //..


 public String[] toStringArray() {

    return new String[]{
            nullToEmpty(String.valueOf(getSomeItem1())),
            nullToEmpty(String.valueOf(getOtherItem2())),
            .
            .  
            nullToEmpty(String.valueOf(getSomeFreakItem100())),

 }
}

Edit : I need this for opencvs, it expects for a String[] as in this example:

How to use opencsv with my collection (list)?

Community
  • 1
  • 1
Spring
  • 8,976
  • 26
  • 96
  • 175
  • You could try http://commons.apache.org/proper/commons-beanutils/, it has a [BeanMap](http://commons.apache.org/proper/commons-beanutils/javadocs/v1.8.3/apidocs/org/apache/commons/beanutils/BeanMap.html) that will generate a map of property names -> values for a given object (presuming bean-style getters/setters exist). You could also roll your own with reflection (or some of the lower level utilities in BeanUtils), optionally using custom annotations for more control (e.g. flagging properties to include / exclude, specifying their index in the resulting string array, etc.). – Jason C Feb 20 '14 at 18:40
  • It seems suspicious that you need to do this. It starts to sound like these should be held in a `Map` or some other bulk data structure rather than all smushed together as fields in an object. – Louis Wasserman Feb 20 '14 at 19:12
  • @Louis Wasserman I use opencvs and expects for a String[]..you have a better idea? – Spring Feb 20 '14 at 19:49
  • I have no objection to the `String[]`, my concern is that these things aren't in a `String[]` or some collection type to start with. – Louis Wasserman Feb 20 '14 at 20:27
  • @Louis Wasserman it represents a table in db – Spring Feb 20 '14 at 21:08

3 Answers3

2
Field[] fields = Cart1.getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i= 0; i < fields.length; i++) {
    fieldNames[i] = fields[i].getName();
}
jpdymond
  • 1,367
  • 7
  • 10
  • and how wilL i use this? ok my field names are in a list, but i need to be able to get all values of those as a string array – Spring Feb 20 '14 at 18:50
  • Do you mean the the String representation of the object? – jpdymond Feb 20 '14 at 19:01
  • 1
    I think he meant the value of the field, not just the name of the field. For that, you would have to have `Object value = fields[i].get(cart)` – Ray Feb 20 '14 at 19:09
2

You can use Introspector for programmatically read values from POJOs

public String[] toStringArray() {
    PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(getClass()).getPropertyDescriptors();
    List<String> values = new ArrayList<String>();
    for (PropertyDescriptor descriptor : propertyDescriptors) {
        Method readMethod = descriptor.getReadMethod();
        if (!readMethod.getName().equals("getClass")) {
            values.add(nullToEmpty((String) readMethod.invoke(this)));
        }
    }
    return values.toArray(new String[0]);
}
renke
  • 1,070
  • 1
  • 9
  • 25
1

With Java reflection you could use something like below. Get all getter methods (except getClass()) from your class, then invoke them on an instance of this class and pack into an array.

Or, you can think of using other data structure for your data. E.g. Map, with item name as a map key and item value as a map value.

public String[] toStringArray(Cart cart) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    List<Method> getters = getGetters(cart.getClass());
    String[] result = new String[getters.size()];
    for (int i = 0; i < getters.size(); i++) {
        Object value = getters.get(i).invoke(cart);
        result[i] = String.valueOf(value);
    }
    return result;
}

private List<Method> getGetters(Class clazz) throws SecurityException {
    List<Method> getters = new ArrayList<Method>();

    for (Method method : clazz.getMethods()) {
        if (method.getName().startsWith("get") && !"getClass".equals(method.getName())) {
            getters.add(method);
        }
    }
    return getters;
}
Jakub Godoniuk
  • 394
  • 1
  • 6
  • 10
  • Perhaps allow `"is"` as well as `"get"`; the naming convention for getters for booleans is `isXxx` instead of `getXxx`. Also, I wonder if it's worth checking the parameter types (`.length == 0`) and return type (`.equals(Void.class)`) – Ray Feb 20 '14 at 19:08
  • @Jakub Godoniuk tnx I use opencvs and expects for a String[]..you have an idea to do this without reflection? – Spring Feb 20 '14 at 19:49
  • @Spring, in your question, you specifically gave "reflection" as an option. It's considered rude at best to change the requirements after getting an answer that meets what you've asked. Consider opening a new question for further refinement – Ray Feb 20 '14 at 20:00
  • @Ray Not that I will learn how to behave from you..but I will accept your answer if that's what deeply worries you..tho requirement is not changing..I am asking..watch your attitude – Spring Feb 20 '14 at 20:10
  • @Spring, I've not provided an answer; it is of no benefit to me – Ray Feb 20 '14 at 20:14