Java 具有列表作为单个键的值的属性文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9737812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:56:05  来源:igfitidea点击:

Properties file with a list as the value for an individual key

javacollectionsmappropertiesset

提问by NIVESH SENGAR

For my program I want to read a key from a properties file and an associated List of values for the key.
Recently I was trying like that

对于我的程序,我想从属性文件中读取一个键和一个关联的键值列表。
最近我就是这样尝试的

public static Map<String,List<String>>categoryMap = new Hashtable<String, List<String>>();


    Properties prop = new Properties();


    try {

        prop2.load(new FileInputStream(/displayCategerization.properties));
        Set<Object> keys = prop.keySet();
        List<String> categoryList = new ArrayList<String>();
        for (Object key : keys) {
            categoryList.add((String)prop2.get(key));
            LogDisplayService.categoryMap.put((String)key,categoryList);
        }
        System.out.println(categoryList);
        System.out.println("Category Map :"+LogDisplayService.categoryMap);

        keys = null;
        prop = null;

    } catch (Throwable e) {
        e.printStackTrace();
    }

and my properties file is like below -

我的属性文件如下-

A=APPLE
A=ALPHABET
A=ANT
B=BAT
B=BALL
B=BUS

I want for key A there should be a list which contain [APPLE, ALPHABET,ANT]and B contain [BAT,BALL,BUS].
So Map should be like this {A=[APPLE, ALPHABET,ANT], B=[BAT,BALL,BUS]}but I get
{A=[ANT], B=[BUS]}
I searched on the internet for such a way but found nothing. I wish there should be a way. Any help?

我想要键 A 应该有一个包含[APPLE, ALPHABET,ANT]和 B 包含的列表[BAT,BALL,BUS]
所以地图应该是这样的,{A=[APPLE, ALPHABET,ANT], B=[BAT,BALL,BUS]}但我
{A=[ANT], B=[BUS]}
在互联网上搜索了这种方式,但一无所获。我希望应该有办法。有什么帮助吗?

采纳答案by DwB

Try writing the properties as a comma separated list, then split the value after the properties file is loaded. For example

尝试将属性编写为逗号分隔列表,然后在加载属性文件后拆分值。例如

a=one,two,three
b=nine,ten,fourteen

You can also use org.apache.commons.configurationand change the value delimiter using the AbstractConfiguration.setListDelimiter(char)method if you're using comma in your values.

如果您在值中使用逗号,您还可以使用org.apache.commons.configuration并使用AbstractConfiguration.setListDelimiter(char)方法更改值分隔符。

回答by davidfrancis

Create a wrapper around properties and assume your A value has keys A.1, A.2, etc. Then when asked for A your wrapper will read all the A.* items and build the list. HTH

创建一个围绕属性的包装器,并假设您的 A 值具有键 A.1、A.2 等。然后当要求 A 时,您的包装器将读取所有 A.* 项目并构建列表。HTH

回答by Jayan

If this is for some configuration file processing, consider using Apache configuration. https://commons.apache.org/proper/commons-configuration/javadocs/v1.10/apidocs/index.html?org/apache/commons/configuration/PropertiesConfiguration.htmlIt has way to multiple values to single key- The format is bit different though

如果这是为了一些配置文件处理,请考虑使用 Apache 配置。 https://commons.apache.org/proper/commons-configuration/javadocs/v1.10/apidocs/index.html?org/apache/commons/configuration/PropertiesConfiguration.html它可以将多个值转换为单个键-虽然格式有点不同

key=value1,value2,valu3gives three values against same key.

key=value1,value2,valu3针对同一个键给出三个值。

回答by Bohemian

Your logic is flawed... basically, you need to:

你的逻辑有缺陷......基本上,你需要:

  1. get the list for the key
  2. if the list is null, create a new list and put it in the map
  3. add the word to the list
  1. 获取密钥列表
  2. 如果列表为空,则创建一个新列表并将其放入地图中
  3. 将单词添加到列表中

You're not doing step 2.

您没有执行第 2 步。

Here's the code you want:

这是你想要的代码:

Properties prop = new Properties();
prop.load(new FileInputStream("/displayCategerization.properties"));
for (Map.Entry<Object, Object> entry : prop.entrySet())
{
    List<String> categoryList = categoryMap.get((String) entry.getKey());
    if (categoryList == null)
    {
        categoryList = new ArrayList<String>();
        LogDisplayService.categoryMap.put((String) entry.getKey(), categoryList);
    }
    categoryList.add((String) entry.getValue());
}

Note also the "correct" way to iterate over the entries of a map/properties - via its entrySet().

还要注意迭代地图/属性条目的“正确”方法 - 通过其entrySet().

回答by subie

The comma separated list option is the easiest but becomes challenging if the values could include commas.

逗号分隔列表选项是最简单的,但如果值可以包含逗号,则变得具有挑战性。

Here is an example of the a.1, a.2, ... approach:

以下是 a.1, a.2, ... 方法的示例:

for (String value : getPropertyList(prop, "a"))
{
    System.out.println(value);
}

public static List<String> getPropertyList(Properties properties, String name) 
{
    List<String> result = new ArrayList<String>();
    for (Map.Entry<Object, Object> entry : properties.entrySet())
    {
        if (((String)entry.getKey()).matches("^" + Pattern.quote(name) + "\.\d+$"))
        {
            result.add((String) entry.getValue());
        }
    }
    return result;
}

回答by Gunnlaugur

There's probably a another way or better. But this is how I do this in Spring Boot.

可能有另一种方式或更好的方式。但这就是我在 Spring Boot 中执行此操作的方式。

My property file contains the following lines. "," is the delimiter in each line.

我的属性文件包含以下几行。“,”是每一行的分隔符。

mml.pots=STDEP:DETY=LI3;,STDEP:DETY=LIMA;
mml.isdn.grunntengingar=STDEP:DETY=LIBAE;,STDEP:DETY=LIBAMA;
mml.isdn.stofntengingar=STDEP:DETY=LIPRAE;,STDEP:DETY=LIPRAM;,STDEP:DETY=LIPRAGS;,STDEP:DETY=LIPRVGS;

My server config

我的服务器配置

@Configuration
public class ServerConfig {

    @Inject
    private Environment env;

    @Bean
    public MMLProperties mmlProperties() {
        MMLProperties properties = new MMLProperties();
        properties.setMmmlPots(env.getProperty("mml.pots"));
        properties.setMmmlPots(env.getProperty("mml.isdn.grunntengingar"));
        properties.setMmmlPots(env.getProperty("mml.isdn.stofntengingar"));
        return properties;
    }
}

MMLProperties class.

MMLProperties 类。

public class MMLProperties {
    private String mmlPots;
    private String mmlIsdnGrunntengingar;
    private String mmlIsdnStofntengingar;

    public MMLProperties() {
        super();
    }

    public void setMmmlPots(String mmlPots) {
        this.mmlPots = mmlPots;
    }

    public void setMmlIsdnGrunntengingar(String mmlIsdnGrunntengingar) {
        this.mmlIsdnGrunntengingar = mmlIsdnGrunntengingar;
    }

    public void setMmlIsdnStofntengingar(String mmlIsdnStofntengingar) {
        this.mmlIsdnStofntengingar = mmlIsdnStofntengingar;
    }

    // These three public getXXX functions then take care of spliting the properties into List
    public List<String> getMmmlCommandForPotsAsList() {
        return getPropertieAsList(mmlPots);
    }

    public List<String> getMmlCommandsForIsdnGrunntengingarAsList() {
        return getPropertieAsList(mmlIsdnGrunntengingar);
    }

    public List<String> getMmlCommandsForIsdnStofntengingarAsList() {
        return getPropertieAsList(mmlIsdnStofntengingar);
    }

    private List<String> getPropertieAsList(String propertie) {
        return ((propertie != null) || (propertie.length() > 0))
        ? Arrays.asList(propertie.split("\s*,\s*"))
        : Collections.emptyList();
    }
}

Then in my Runner class I Autowire MMLProperties

然后在我的 Runner 类中我 Autowire MMLProperties

@Component
public class Runner implements CommandLineRunner {

    @Autowired
    MMLProperties mmlProperties;

    @Override
    public void run(String... arg0) throws Exception {
        // Now I can call my getXXX function to retrieve the properties as List
        for (String command : mmlProperties.getMmmlCommandForPotsAsList()) {
            System.out.println(command);
        }
    }
}

Hope this helps

希望这可以帮助