web-dev-qa-db-fra.com

Fichier de propriétés avec une liste comme valeur pour une clé individuelle

Pour mon programme, je veux lire une clé d'un fichier de propriétés et une liste de valeurs associée pour la clé.
Récemment j'essayais comme ça

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

et mon fichier de propriétés est comme ci-dessous - 

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

Je veux pour la clé A, il devrait y avoir une liste contenant [Apple, ALPHABET,ANT] et B contenant [BAT,BALL,BUS].
Donc, Map devrait ressembler à ceci {A=[Apple, ALPHABET,ANT], B=[BAT,BALL,BUS]} mais je reçois 
{A=[ANT], B=[BUS]}
J'ai cherché sur Internet un tel moyen mais je n'ai rien trouvé. Je souhaite qu'il y ait un moyen . Toute aide?

22
NIVESH SENGAR

Essayez d’écrire les propriétés sous la forme d’une liste séparée par des virgules, puis divisez la valeur après le chargement du fichier de propriétés, par exemple.

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

Vous pouvez également utiliser org.Apache.commons.configuration et modifier le séparateur de valeur à l'aide de la méthode AbstractConfiguration.setListDelimiter (char) si vous utilisez une virgule dans vos valeurs.

36
DwB

L'option de liste séparée par des virgules est la plus simple mais elle devient difficile si les valeurs peuvent inclure des virgules.

Voici un exemple de l'approche 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;
}
11
subie

S'il s'agit d'un traitement de fichier de configuration, envisagez d'utiliser la configuration Apache. https://commons.Apache.org/proper/commons-configuration/javadocs/v1.10/apidocs/index.html?org/Apache/commons/configuration/PropertiesConfiguration.html plusieurs valeurs en une seule clé - Le format est un peu différent si

key=value1,value2,valu3 donne trois valeurs contre la même clé.

4
Jayan

Votre logique est imparfaite ... en gros, vous devez:

  1. obtenir la liste pour la clé
  2. si la liste est nulle, créez une nouvelle liste et mettez-la dans la carte
  3. ajouter le mot à la liste

Vous ne faites pas l'étape 2.

Voici le code que vous voulez:

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

Notez également la manière "correcte" de parcourir les entrées d'une carte/propriété - via sa entrySet()

3
Bohemian

Créez un wrapper autour des propriétés et supposez que votre valeur A a les clés A.1, A.2, etc. Puis, quand on vous le demande, votre wrapper lira tous les éléments A. * et construira la liste. HTH

2
davidfrancis

Il y a probablement une autre façon ou mieux. Mais c'est comme ça que je fais cela dans Spring Boot.

Mon fichier de propriétés contient les lignes suivantes. "," est le délimiteur dans chaque ligne.

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;

Ma configuration serveur

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

Classe 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();
    }
}

Puis, dans ma classe Runner, je 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);
        }
    }
}

J'espère que cela t'aides

1
Gunnlaugur