Java:通过匹配LinkedHashMap

时间:2017-04-30 05:45:48

标签: java hashmap treemap linkedhashmap

我有一个LinkedHashMap,并希望执行以下操作:

  1. 循环浏览HashMap并检查Key中的字符串是否包含“Group”字样
  2. 创建与该键字符串匹配的所有值的字符串[]
  3. 例如,如果我有像下面这样的LinkedHashMap

    HashMap<String, String> nameNum = new LinkedHashMap<String, String>();
    nameNum.put("row 1", "data 1");
    nameNum.put("Group_Colour_R", "Red");
    nameNum.put("Group_Colour_B", "Blue");
    nameNum.put("row 4", "data 4");
    nameNum.put("row 5", "data 5");
    nameNum.put("Group_Shape_R", "Rectangle");
    nameNum.put("Group_Shape_T", "Triangle");
    nameNum.put("Group_Shape_C", "Circle");
    nameNum.put("row 9", "data 9");
    nameNum.put("row 10", "data 10");
    nameNum.put("row 11", "data 11");
    

    循环上面的HashMap之后,我应该有2个String []

    String[] colour = {"Red", "Blue"}; 
    String[] shape = {"Rectangle", "Triangle", "Circle"};
    

    我只是不确定如何实现它。

    有些内容与我想要的相关,并在此处找到:Partial search in HashMap

    基于上面我实现了它,如下所示,但正如您所看到的,它会多次运行相同的值。我不确定何时以及如何打破循环以便它只给出一次值:

    import java.util.Map;
    import java.util.SortedMap;
    import java.util.TreeMap;
    
    import org.apache.commons.lang3.StringUtils;
    
    public class MainClass {
        public static void main(String[] args) {
            SortedMap<String, String> nameNum = new TreeMap<String, String>();
            nameNum.put("row 1", "data 1");
            nameNum.put("Group_Colour_R", "Red");
            nameNum.put("Group_Colour_B", "Blue");
            nameNum.put("row 4", "data 4");
            nameNum.put("row 5", "data 5");
            nameNum.put("Group_Shape_R", "Rectangle");
            nameNum.put("Group_Shape_T", "Triangle");
            nameNum.put("Group_Shape_C", "Circle");
            nameNum.put("row 9", "data 9");
            nameNum.put("row 10", "data 10");
            nameNum.put("row 11", "data 11");
    
    
            for (Map.Entry<String, String> entry : nameNum.entrySet()) {
                String prefix = entry.getKey();
                if (prefix.contains("Group")) {
                    prefix = prefix.substring(0, StringUtils.lastIndexOf(prefix, "_"));
                    System.out.println("******");
                    for (Map.Entry<String, String> entry1 : filterPrefix(nameNum, prefix).entrySet()) {
                        System.out.println(entry1);
                    }
                    System.out.println("******");
                }
            }
        }
    
        public static <V> SortedMap<String, V> filterPrefix(SortedMap<String,V> baseMap, String prefix) {
            if(prefix.length() > 0) {
                char nextLetter = (char) (prefix.charAt(prefix.length() -1) + 1);
                String end = prefix.substring(0, prefix.length()-1) + nextLetter;
                return baseMap.subMap(prefix, end);
            }
            return baseMap;
        }
    }
    

    理想情况下,我想使用LinkedHashMap,因为我想保留订单。我非常感谢有关如何实现类似功能的任何指针/代码。任何代码段都将受到高度赞赏。提前谢谢。

3 个答案:

答案 0 :(得分:0)

请删除for循环以避免多个重复结果。您需要使用&#34; Group _&#34; Color&#34;进行两次通话。和&#34; Group_Shade&#34;作为过滤方法的前缀,以获得所需的结果。

答案 1 :(得分:0)

也许Java 8 Stream API在这里可能会有所帮助。您可以尝试使用Collectors.groupingBy

将相关条目组合在一起
Map<String,List<String>> groups =
    nameNum.entrySet()
           .stream()
           .filter(entry -> entry.getKey().contains("Group"))
           .collect(Collectors.groupingBy(entry -> entry.getKey().substring(0, entry.getKey().lastIndexOf("_")),
                                          Collectors.mapping(Map.Entry::getValue,
                                                             Collectors.toList()));

这会产生Map包含:

{Group_Shape=[Rectangle, Triangle, Circle], Group_Colour=[Red, Blue]}

如果您愿意,也可以强制输出MapLinkedHashMap

Map<String,List<String>> groups =
    nameNum.entrySet()
           .stream()
           .filter(entry -> entry.getKey().contains("Group"))
           .collect(Collectors.groupingBy(entry -> entry.getKey().substring(0, entry.getKey().lastIndexOf("_")),                     
                                          LinkedHashMap::new, 
                                          Collectors.mapping(Map.Entry::getValue,
                                                             Collectors.toList()));

这会改变输出Map的迭代顺序:

{Group_Colour=[Red, Blue], Group_Shape=[Rectangle, Triangle, Circle]}

答案 2 :(得分:0)

您可以使用 HashMap 代替Arrays存储值,如下所示:

HashMap<String,ArrayList<String>> groupList = new HashMap<String, ArrayList<String>>();

然后在内部循环中,您可以实现以下逻辑来存储重复的组密钥及其值:

if(prefix.contains("Group")){
    String keyGrp = prefix.split("_")[1];
    if(groupList.containsKey(keyGrp)){
        groupList.get(keyGrp).add(entry.getValue());
    }else{
        ArrayList<String> grpVal = new ArrayList<String>();
        grpVal.add(entry.getValue());
        groupList.put(keyGrp, grpVal);
    }
}