英文:
Group Values of map with same prefix entry key
问题
我有一个哈希映射,其中包含类似a.01、a.02、b.01、b.02的字符串,并且值是列表。
现在我想创建一个新的映射,并将原映射中的键的前缀(如a、b等)作为新映射的键,将具有相似前缀的元素的列表内容作为值。
示例:将具有前缀a和b的列表分组
输入:Map<String, List> input = {(a.1, l1), (a.2, l2), (b.1, l3), (b.2, l4)}
输出:Map<String, List> output = {(a, {l1, l2}), (b, {l3, l4})}
我尝试了以下方法,但它不起作用:
public static Set<String> prefixName(final Map<String, List> names, final String prefix) {
return names.entrySet().stream()
.filter(entry -> entry.getKey().startsWith(prefix)).map(entry -> prefix);
}
英文:
I have hash map which contains strings like a.01, a.02, b.01, b.02 and a list as value.
Now I would like to create a new map and put there as a key the prefix of the keys (like a, b,.. etc) and as value the content of the lists of the elements with similar prefix.
Example: group lists of prefix a and b
input: Map<String, List> input = {(a.1,l1), (a.2,l2),(b.1,l3), (b.2,l4)}
Output: Map<String, List> output = {(a,{l1,l2}), (b,{l3,l4})}
I tried the following but it is not working
public static Set<String> prefixName(final Map<String, List> names, final String prefix) {
return names.entrySet().stream()
.filter(entry -> entry.getKey().startsWith(prefix)).map(entry -> prefix);
}
答案1
得分: 1
这是命令式方法的示例代码:
public class Main {
public static void main(String[] args) {
Map<String, List<String>> originalMap = new HashMap<>();
originalMap.put("a.1", Arrays.asList("l1"));
originalMap.put("a.2", Arrays.asList("l2"));
originalMap.put("b.1", Arrays.asList("l3"));
originalMap.put("b.2", Arrays.asList("l4"));
Map<String, List<String>> newMap = new HashMap<>();
for (Map.Entry<String, List<String>> entry : originalMap.entrySet()) {
String newKey = entry.getKey().split("\\.")[0];
if (!newMap.containsKey(newKey)) {
newMap.put(newKey, new ArrayList<>());
}
newMap.get(newKey).addAll(entry.getValue());
}
System.out.println(newMap);
}
}
英文:
Try this imperative approach:
public class Main {
public static void main(String[] args) {
Map<String, List<String>> originalMap = new HashMap<>();
originalMap.put("a.1",Arrays.asList("l1"));
originalMap.put("a.2",Arrays.asList("l2"));
originalMap.put("b.1",Arrays.asList("l3"));
originalMap.put("b.2",Arrays.asList("l4"));
Map<String,List<String>> newMap = new HashMap<>();
for (Map.Entry<String,List<String>> entry: originalMap.entrySet()){
String newKey = entry.getKey().split("\\.")[0];
if(!newMap.containsKey(newKey)){
newMap.put(newKey,new ArrayList<>());
}
newMap.get(newKey).addAll(entry.getValue());
}
System.out.println(newMap);
}
答案2
得分: 1
如果此任务不需要_streams_,您可以使用以下方法。
遍历原始映射,检查新映射是否包含_prefix_键。
然后,要么将列表添加到新映射列表中,要么创建新的映射条目。
Map<String, List<List>> parse(Map<String, List> mapA) {
Map<String, List<List>> mapB = new HashMap<>();
String prefix;
List<List> lists;
for (Map.Entry<String, List> entry : mapA.entrySet()) {
prefix = prefix(entry.getKey());
if (mapB.containsKey(prefix))
mapB.get(prefix).add(entry.getValue());
else {
lists = new ArrayList<>();
lists.add(entry.getValue());
mapB.put(prefix, lists);
}
}
return mapB;
}
另外,我在这里创建了一个方法,用于从_key_中提取_prefix_子串。
其中,我认为这可能比单独的子串更复杂。
String prefix(String string) {
/* a.01, a.02, b.01, 等等。 */
return string.substring(0, string.indexOf('.'));
}
以下是输入和输出的示例。
Map<String, List> mapA = new HashMap<>();
mapA.put("a.01", List.of(1, 2, 3, 4));
mapA.put("a.02", List.of(5, 6, 7, 8));
mapA.put("b.01", List.of(9, 0, 1, 2));
mapA.put("b.02", List.of(3, 4, 5, 6));
Map<String, List<List>> mapB = parse(mapA);
System.out.println(mapB);
{a=[[1, 2, 3, 4], [5, 6, 7, 8]], b=[[9, 0, 1, 2], [3, 4, 5, 6]]}
英文:
If this task does not require streams, you can use the following.
Traverse the original map, checking if the new map contains the prefix key.
Then, either add the list to the new map list, or create a new map entry.
Map<String, List<List>> parse(Map<String, List> mapA) {
Map<String, List<List>> mapB = new HashMap<>();
String prefix;
List<List> lists;
for (Map.Entry<String, List> entry : mapA.entrySet()) {
prefix = prefix(entry.getKey());
if (mapB.containsKey(prefix))
mapB.get(prefix).add(entry.getValue());
else {
lists = new ArrayList<>();
lists.add(entry.getValue());
mapB.put(prefix, lists);
}
}
return mapB;
}
Additionally, I created a method here, to substring the prefix from the key.
In which, I presume may be more complicated than a single substring.
String prefix(String string) {
/* a.01, a.02, b.01, etc. */
return string.substring(0, string.indexOf('.'));
}
Here is an example of an input and output.
Map<String, List> mapA = new HashMap<>();
mapA.put("a.01", List.of(1, 2, 3, 4));
mapA.put("a.02", List.of(5, 6, 7, 8));
mapA.put("b.01", List.of(9, 0, 1, 2));
mapA.put("b.02", List.of(3, 4, 5, 6));
Map<String, List<List>> mapB = parse(mapA);
System.out.println(mapB);
{a=[[1, 2, 3, 4], [5, 6, 7, 8]], b=[[9, 0, 1, 2], [3, 4, 5, 6]]}
答案3
得分: 1
如果你想以流的方式进行操作,你可以使用映射函数作为集合操作的一部分。这将允许创建一个多重映射,其中你的简化和减少的键会与该键的原始值(类型为List<string>
)一起收集到一个封闭的List<List<String>>
中:
import java.util.stream.*;
import static java.util.stream.Collectors.*;
import java.util.*;
public class Grouping {
public static void main(String[] args) {
try {
List<String> l1 = List.of("foo", "bar");
List<String> l2 = List.of("goo", "car");
List<String> l3 = List.of("boo", "par");
List<String> l4 = List.of("loo", "tar");
Map<String, List<String>> mapped = Map.of(
"a.1", l1,
"a.2", l2,
"b.1", l3,
"b.2", l4);
Map<String, List<List<String>>> grouped = mapped.entrySet().
stream().
collect(groupingBy(e ->e.getKey().substring(0, 1), mapping(e ->e.getValue(), toList())));
System.out.println(grouped);
}
catch(Throwable t) {
t.printStackTrace();
}
}
}
输出为:
{a=[[foo, bar], [goo, car]], b=[[boo, par], [loo, tar]]}
英文:
If you want to do it stream-wise you can use a mapping function as part of a collection operation. This will enable a multimap to be created with your simplified and reduced key, with the original values of that key (type List<string>
) collected into an enclosing List<List<String>>
:
import java.util.stream.*;
import static java.util.stream.Collectors.*;
import java.util.*;
public class Grouping {
public static void main(String[] args) {
try {
List<String> l1 = List.of("foo", "bar");
List<String> l2 = List.of("goo", "car");
List<String> l3 = List.of("boo", "par");
List<String> l4 = List.of("loo", "tar");
Map<String, List<String>> mapped = Map.of(
"a.1", l1,
"a.2", l2,
"b.1", l3,
"b.2", l4);
Map<String, List<List<String>>> grouped = mapped.entrySet().
stream().
collect(groupingBy(e ->e.getKey().substring(0, 1), mapping(e ->e.getValue(), toList())));
System.out.println(grouped);
}
catch(Throwable t) {
t.printStackTrace();
}
}
}
The output being:
{a=[[foo, bar], [goo, car]], b=[[boo, par], [loo, tar]]}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论