根据密钥中某些字符串的一部分从HashMap中检索密钥?

时间:2014-10-03 01:40:26

标签: java

任务:读取XML文件以创建模板;

我正在阅读下面提到的这个XML文件并将其放在HashMap中。获得一个键值对, 其中Key是Element属性下的值" name"和价值是元素价值。 例如:Key:map.abc.color.PRIMARY和Value:#FFFFFF 例如:Key:map.abc.node.TEXT1和Value:value1

<properties>
    <property name="map.abc.color.PRIMARY">#FFFFFF</property>
    <property name="map.abc.color.SECONDARY">#F0F0F0</property>
    <property name="map.abc.node.TEXT1">value1</property>
    <property name="map.abc.node.TEXT2">value2</property>
    <property name="map.abc.node.lowercase">value3</property>   
    <property name="map.abc.strFile">/path/to/file</property>

    <property name="map.pqr.color.PRIMARY">#000000</property>
    <property name="map.pqr.color.SECONDARY">#ABABAB</property>
    <property name="map.pqr.node.WORD1">value4</property>
    <property name="map.pqr.node.WORD2">value5</property>
    <property name="map.abc.node.lowercase">value6</property>
    <property name="map.pqr.strFile">/path/to/file</property>
</properties>

以下是要写入文件的模板(使用StringBuffer)输出。

abc = {
    color: {PRIMARY_COLOR:"#FFFFFF",SECONDARY_COLOR:"#F0F0F0"}
    node:{TEXT1:"value1",TEXT2:"value2"}
};

pqr = {
    color: {PRIMARY_COLOR:"#FFFFFF",SECONDARY_COLOR:"#F0F0F0"}
    node:{WORD1:"value4",WORD2:"value5"}
};

Offnote:我正在使用以下模式,该工作正常。

key.matches("map.abc.*.*\\p{Lu}$") or key.matches("map.*.*\\p{Lu}$")

因此,我希望找到一种方法,让所有键在HashMap的Key中的最后一个句点之后以大写字母结尾(或者可能是任何其他选项)

3 个答案:

答案 0 :(得分:1)

您可以将密钥与以下正则表达式匹配,并查看它是否返回true:

key.matches(".*\\.[A-Z]+");

答案 1 :(得分:1)

好的,既然我们有更多细节,我们就可以解决您的数据结构问题。在我看来,你在这里有一个分层图。您的name似乎定义了层次结构。我会使用地图图来存储它:

Map<String, Map<String, Map<String, String>>> structure = new HashMap<>();

解析并填充地图(完全只是伪代码):

path = name.split(".")
// ignore path[0] since it's just 'map'
structure.get(path[1]).get(path[2]).put(path[3], value)

并检索值

for (Map<String, Map<String, String>> element : structure){
  for(Map<String, String> group : element) {
    for(String attribute : group.keys){
      if(allUpper(attribute)) {  //DO YOUR THING HERE }
    }
  }
}

答案 2 :(得分:0)

在我看来,您正在尝试将java属性样式的值列表转换为javascript对象。

这是一种可能性:您可以将属性样式Map“展开”为映射/值的递归映射,然后利用其中一个JSON库来输出值。以下是一些解决问题的代码:

public class Foo {
  private static final String ROOT_NAME = "map";

  private static boolean noLowercase(CharSequence s) {
    return !s.chars().anyMatch(Character::isLowerCase);
  }

  private static Map<String, Object> getNextMap(Map<String, Object> map, String mapName) {
    Object nextObj = map.get(mapName);
    if (nextObj == null) {
      nextObj = new LinkedHashMap<String, Object>();
      map.put(mapName, nextObj);
    }
    @SuppressWarnings("unchecked")
    Map<String, Object> nextMap = (Map<String, Object>)nextObj;
    return nextMap;
  }

  public static Map<String, Object> unflatten(Map<String, String> properties) {
    List<String> sortedKeys = new ArrayList<>(properties.keySet());
    Collections.sort(sortedKeys);
    Map<String, Object> rootObject = new LinkedHashMap<>();
    for (String key : sortedKeys) {
      String[] splitKey = key.split("\\.");
      String lastItem = splitKey[splitKey.length - 1];
      if (noLowercase(lastItem)) {
        Map<String, Object> currentMap = rootObject;
        for (int i = 1; i < splitKey.length - 1; ++i) {
          currentMap = getNextMap(currentMap, splitKey[i]);
        }
        currentMap.put(lastItem, properties.get(key));
      }
    }
    return rootObject;
  }
}

在此之后,使用Gson或Jackson进行序列化应该非常简单。以下是使用Gson的示例:

  public static void printMap(Map<String, String> map) {
    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    for (Map.Entry<String, Object> entry : unflatten(map).entrySet()) {
      System.out.format("%s = ", entry.getKey());
      System.out.print(gson.toJson(entry.getValue()));
      System.out.println(";");
      System.out.println();
    }
  }

或者,为地图数据结构地图编写自己的打印例程应该不会太难。