2012-03-16 4 views
18

Para mi programa, quiero leer una clave de un archivo de propiedades y una Lista de valores asociada para la clave.
Recientemente yo estaba tratando de esa maneraArchivo de propiedades con una lista como el valor de una clave individual

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

y mi archivo de propiedades es como abajo -

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

que quiero para la tecla A debe haber una lista que contiene [APPLE, ALPHABET,ANT] y B contienen [BAT,BALL,BUS].
Así que el mapa debería ser así {A=[APPLE, ALPHABET,ANT], B=[BAT,BALL,BUS]} pero obtengo
{A=[ANT], B=[BUS]}
Realicé búsquedas en Internet de esa forma pero no encontré nada. Ojalá hubiera una manera. ¿Alguna ayuda?

+1

propiedad sólo soportan 'clave, valor' par. cuando hay varias filas con la misma clave, la última gana (incluso eso podría ser un comportamiento "indefinido"). Esa es su entrada alimentada a la categoría. Map no es lo mismo que usted piensa. Sugeriría que escribas una pequeña prueba 'junit'. – Jayan

Respuesta

32

Intente escribir las propiedades como una lista separada por comas, y luego divida el valor después de cargar el archivo de propiedades. Por ejemplo

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

También puede utilizar org.apache.commons.configuration y cambiar el valor delimitador utilizando el método AbstractConfiguration.setListDelimiter(char) si está usando coma en sus valores.

+0

Buena respuesta. Estaba pensando en tener un archivo xml y luego escribir mucho código analizándolo y almacenando objetos desde él. –

+1

One-liner con Apache configuration2: 'nuevo DefaultListDelimiterHandler (','). Split (" a, b, c ", true)' da: una lista de '" a "," b "," c "' . Javadoc: https://commons.apache.org/proper/commons-configuration/apidocs/org/apache/commons/configuration2/convert/DefaultListDelimiterHandler.html – Marcin

1

Cree un envoltorio alrededor de las propiedades y suponga que su valor A tiene las claves A.1, A.2, etc. Luego, cuando se le pregunte por A, su envoltura leerá todos los elementos A. * y compilará la lista. HTH

3

Su lógica falla ... básicamente, es necesario:

  1. obtener la lista para la tecla
  2. si la lista es nula, crear una nueva lista y la puso en el mapa
  3. añadir la palabra a la lista

usted no está haciendo el paso 2.

Aquí está el código que desea:

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

Tenga en cuenta también la forma "correcta" para repetir las entradas de un mapa/propiedades - a través de su entrySet().

8

La opción de lista separada por comas es la más fácil pero se vuelve difícil si los valores pueden incluir comas.

Aquí se muestra un ejemplo de la A.1, A.2, ... enfoque:

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

Probablemente hay una manera u otra mejor. Pero así es como hago esto en Spring Boot.

Mi archivo de propiedad contiene las siguientes líneas."," es el delimitador en cada línea.

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; 

Mi configuración del servidor

@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 clase.

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

Luego, en mi clase Runner I 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); 
     } 
    } 
} 

Esperanza esto ayuda

Cuestiones relacionadas