Java:通过匹配 LinkedHashMap 中的相似键来复制值
Java: copy values by matching similar keys from LinkedHashMap
我有一个 LinkedHashMap 并想执行以下操作:
- 遍历 HashMap 并检查 Key 中的字符串是否包含 'Group' 个单词
- 创建与该键字符串匹配的所有值的字符串[]
例如,如果我有如下所示的 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,因为我想保留顺序。我非常感谢任何 pointers/code 如何实现类似的东西。任何代码片段将不胜感激。提前致谢。
请删除 for 循环以避免出现多个重复结果。您需要使用 "Group_"Colour" 和 "Group_Shade" 作为过滤器方法的前缀进行两次调用,以获得所需的结果。
也许 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]}
如果您愿意,也可以强制输出 Map
为 LinkedHashMap
:
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]}
您可以使用 HashMap 代替数组来存储 Group 值,如下所示:
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);
}
}
我有一个 LinkedHashMap 并想执行以下操作:
- 遍历 HashMap 并检查 Key 中的字符串是否包含 'Group' 个单词
- 创建与该键字符串匹配的所有值的字符串[]
例如,如果我有如下所示的 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,因为我想保留顺序。我非常感谢任何 pointers/code 如何实现类似的东西。任何代码片段将不胜感激。提前致谢。
请删除 for 循环以避免出现多个重复结果。您需要使用 "Group_"Colour" 和 "Group_Shade" 作为过滤器方法的前缀进行两次调用,以获得所需的结果。
也许 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]}
如果您愿意,也可以强制输出 Map
为 LinkedHashMap
:
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]}
您可以使用 HashMap 代替数组来存储 Group 值,如下所示:
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);
}
}