首页 > 解决方案 > 如何在属性文件中定义对象数组并从 Java 程序中读取

问题描述

我有一个这样的属性文件。

property[0].name=A
property[0].value=1
property[1].name=B
property[1].value=2
property[2].name=C
property[2].value=3

如何在使用 ResourceBundle 或 Properties 的普通 java 程序中将此文件作为类 {name, value} 的对象列表读取?

这是课程。

public class XYZ {
  private String name;
  private String value;
  // Getters & Setters
}

我需要这样。

ArrayList<XYZ> propertiesList = SomeUtility.getProperties("property", XYZ.class);

实用程序类可能是这样的。

public class SomeUtility {
  public static ArrayList getProperties(String key, Class cls) {
    //logic
  }
}

标签: javaproperties

解决方案


这是我写的解决方案,但它涉及到 Reflect 和 Gson。有没有更好的方法来做到这一点?任何已经可用的可以像 Apache 一样微调的东西。

import com.google.gson.Gson;
import com.google.gson.JsonObject;

import java.lang.reflect.Field;
import java.util.*;

public class ListResourceBundle {

    public static final Gson gson = new Gson();

    private final ResourceBundle bundle;

    public ListResourceBundle(ResourceBundle bundle) {
        this.bundle = bundle;
    }

    public List<?> getProperties(String key, Class<?> cls) {
        final int maxArraySize = getMaxArraySize(key, getMatchingKeys(key));
        final List<String> fields = getFields(cls);

        final List<Object> result = new ArrayList<>();
        for (int i = 0; i < maxArraySize; i++) {
            JsonObject jsonObject = new JsonObject();
            for (String field : fields) {
                jsonObject.addProperty(field, getStringOrNull(key + "[" + i + "]." + field));
            }

            result.add(gson.fromJson(jsonObject, cls));
        }

        System.out.println("result.toString() = " + result.toString());
        return result;
    }

    public List<String> getMatchingKeys(String key) {
        Enumeration<String> keys = bundle.getKeys();
        List<String> matchingKeys = new ArrayList<>();
        while(keys.hasMoreElements()) {
            String k = keys.nextElement();
            if(k.startsWith(key)) {
                matchingKeys.add(k);
            }
        }
        Collections.sort(matchingKeys);
        return matchingKeys;
    }

    public int getMaxArraySize(String key, List<String> matchingKeys) {
        int maxArraySize = 0;
        for (int i = 0; ; i++) {
            boolean indexAvailable = false;
            for (String matchingKey : matchingKeys) {
                if(matchingKey.startsWith(key + "[" + i + "]")) {
                    indexAvailable = true;
                    break;
                }
            }
            if(indexAvailable) {
                maxArraySize++;
            } else {
                break;
            }
        }

        return maxArraySize;
    }

    public String getStringOrNull(String key) {
        try {
            return bundle.getString(key);
        } catch (MissingResourceException e) {
            return null;
        }
    }

    public List<String> getFields(Class<?> cls) {
        final List<String> fields = new ArrayList<>();
        for (Field field : cls.getDeclaredFields()) {
            fields.add(field.getName());
        }
        return fields;
    }

    public static void main(String[] args) {
        ResourceBundle bundle = ResourceBundle.getBundle("com.example.application.resources.Resource");
        ListResourceBundle applicationResourceBundle = new ListResourceBundle(bundle);
        applicationResourceBundle.getProperties("property", ReportParam.class);
    }

}

资源:

property[0].name=A
property[0].value=1
property[1].name=B
property[1].value=2
property[2].name=C
property[2].value=3

输出:

result.toString() = [
ReportParam{name='A', value='1'}, 
ReportParam{name='B', value='2'}, 
ReportParam{name='C', value='3'}]

Process finished with exit code 0

推荐阅读