【问题标题】:OpenCVS: How to get an objects all field values as array? [closed]OpenCVS:如何将对象的所有字段值作为数组获取? [关闭]
【发布时间】:2023-03-08 04:44:01
【问题描述】:

我有 3 个如下所示的域类,我需要将它们的值作为示例中的字符串数组。

这样一个一个地写所有字段非常耗时且容易出错,也许有更快的方法?它将遍历所有字段并获取它们的字符串值

也许用番石榴或反射?

Class Cart1{
 //Domain class with 100s of fields with getters & setters
 
 public String[] toStringArray() {
    return new String[]{
            nullToEmpty(String.valueOf(getSomeItem1())),
            nullToEmpty(String.valueOf(getOtherItem2())),
            . 
            nullToEmpty(String.valueOf(getSomeFreakItem100())),

 }
}

编辑:我需要这个用于 opencvs,它需要一个 String[],如本例所示:

How to use opencsv with my collection (list)?

【问题讨论】:

  • 你可以试试commons.apache.org/proper/commons-beanutils,它有一个BeanMap,它将为给定的对象生成一个属性名称的映射-> 值(假设存在bean 样式的getter/setter)。您还可以使用反射(或 BeanUtils 中的一些较低级别的实用程序)自行开发,可选地使用自定义注释以进行更多控制(例如,标记要包含/排除的属性,在结果字符串数组中指定它们的索引等)。
  • 您需要这样做似乎很可疑。听起来这些应该保存在Map 或其他一些大容量数据结构中,而不是全部作为对象中的字段混合在一起。
  • @Louis Wasserman 我使用 opencvs 并期望 String[] ..你有更好的主意吗?
  • 我对@9​​87654326@ 没有异议,我担心这些东西不在String[] 或某个集合类型中。
  • @Louis Wasserman 它代表 db 中的一个表

标签: java guava opencsv


【解决方案1】:
Field[] fields = Cart1.getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i= 0; i < fields.length; i++) {
    fieldNames[i] = fields[i].getName();
}

【讨论】:

  • 我将如何使用它?好的,我的字段名称在列表中,但我需要能够将这些字段的所有值作为字符串数组获取
  • 你的意思是对象的String表示吗?
  • 我认为他的意思是字段的值,而不仅仅是字段的名称。为此,您必须拥有Object value = fields[i].get(cart)
【解决方案2】:

您可以使用Introspector 以编程方式从 POJO 中读取值

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]);
}

【讨论】:

    【解决方案3】:

    通过 Java 反射,您可以使用如下所示的内容。从您的类中获取所有 getter 方法(getClass() 除外),然后在此类的实例上调用它们并打包到一个数组中。

    或者,您可以考虑为您的数据使用其他数据结构。例如。映射,项目名称作为映射键,项目值作为映射值。

    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;
    }
    

    【讨论】:

    • 也许允许"is" 以及"get";布尔值 getter 的命名约定是 isXxx 而不是 getXxx。另外,我想知道是否值得检查参数类型(.length == 0)和返回类型(.equals(Void.class)
    • @Jakub Godoniuk tnx 我使用 opencvs 并期望 String[] ..你有一个想法可以不经过反思就做到这一点?
    • @Spring,在您的问题中,您特别提供了“反射”作为选项。在得到满足您所要求的答案后更改要求充其量被认为是粗鲁的。考虑打开一个新问题以进一步完善
    • @Ray 并不是说​​我会向你学习如何表现..但如果你对此深感担忧,我会接受你的回答..要求没有改变..我在问..注意你的态度
    • @Spring,我没有提供答案;这对我没有任何好处
    猜你喜欢
    • 1970-01-01
    • 2019-12-03
    • 2020-10-17
    • 2019-01-04
    • 1970-01-01
    • 2020-04-15
    • 2018-11-14
    • 2016-01-02
    • 1970-01-01
    相关资源
    最近更新 更多