Java 11:转换列表<;字符串>;到TreeMap<;字符串,列表<;字符串>&燃气轮机;使用收集器
我有一份这样的清单Java 11:转换列表<;字符串>;到TreeMap<;字符串,列表<;字符串>&燃气轮机;使用收集器,java,java-stream,Java,Java Stream,我有一份这样的清单 List<String> customList = Arrays.asList( "5000 Buruli ulcer is an infectious disease", "6000 characterized by the development", "7000 of painless open wounds.", "8000 The disease larg
List<String> customList = Arrays.asList(
"5000 Buruli ulcer is an infectious disease",
"6000 characterized by the development",
"7000 of painless open wounds.",
"8000 The disease largely occurs in",
"10000 sub-Saharan Africa and Australia."
);
到目前为止,我的代码是:
TreeMap<String, List<String[]>> collect = customList.stream()
.map(s -> s.split(" ", 2))
.collect(Collectors
.groupingBy(a -> a[0], TreeMap::new, Collectors.mapping(a -> a[1].split(" "), Collectors.toList())));
TreeMap collect=customList.stream()
.map(s->s.split(“,2))
.收藏(收藏家)
.groupingBy(a->a[0],TreeMap::new,Collectors.mapping(a->a[1].split(“”),Collectors.toList());
我有两个问题
TreeMap::new
可能不起作用,因为顺序与原始的列表不同
列表
变成列表
我希望每个单词在列表中作为单独的元素。用你的 解决方案中,所有元素都在同一个列表条目中。例如,我 希望10000=[撒哈拉以南非洲和澳大利亚。] 为了实现这一点,您不应该拆分字符串 演示:
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> customList = Arrays.asList(
"5000 Buruli ulcer is an infectious disease",
"6000 characterized by the development",
"7000 of painless open wounds.",
"8000 The disease largely occurs in",
"10000 sub-Saharan Africa and Australia."
);
TreeMap<String, List<String>> collect = customList.stream().map(s -> s.split(" ", 2))
.collect(Collectors.groupingBy(a -> a[0],
() -> new TreeMap<String, List<String>>(Comparator.comparingInt(Integer::parseInt)),
Collectors.mapping(a -> a[1], Collectors.toList())));
System.out.println(collect);
}
}
{5000=[Buruli ulcer is an infectious disease], 6000=[characterized by the development], 7000=[of painless open wounds.], 8000=[The disease largely occurs in], 10000=[sub-Saharan Africa and Australia.]}
{10000=[sub-Saharan Africa and Australia.], 5000=[Buruli ulcer is an infectious disease], 6000=[characterized by the development], 7000=[of painless open wounds.], 8000=[The disease largely occurs in]}
{5000=[[Buruli, ulcer, is, an, infectious, disease]], 6000=[[characterized, by, the, development]], 7000=[[of, painless, open, wounds.]], 8000=[[The, disease, largely, occurs, in]], 10000=[[sub-Saharan, Africa, and, Australia.]]}
{10000=[[sub-Saharan, Africa, and, Australia.]], 5000=[[Buruli, ulcer, is, an, infectious, disease]], 6000=[[characterized, by, the, development]], 7000=[[of, painless, open, wounds.]], 8000=[[The, disease, largely, occurs, in]]}
或者根据我最初的答案:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> customList = Arrays.asList(
"5000 Buruli ulcer is an infectious disease",
"6000 characterized by the development",
"7000 of painless open wounds.",
"8000 The disease largely occurs in",
"10000 sub-Saharan Africa and Australia."
);
Map<String, List<String>> collect = customList.stream().map(s -> s.split("\\s+", 2))
.collect(Collectors.groupingBy(a -> a[0], TreeMap::new,
Collectors.mapping(a -> a[1], Collectors.toList())));
System.out.println(collect);
}
}
建议的解决办法是:
原始答复:
你就快到了。您可以按如下方式进行操作:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> customList = Arrays.asList(
"5000 Buruli ulcer is an infectious disease",
"6000 characterized by the development",
"7000 of painless open wounds.",
"8000 The disease largely occurs in",
"10000 sub-Saharan Africa and Australia."
);
Map<Object, List<Object>> collect = customList.stream().map(s -> s.split("\\s+", 2))
.collect(Collectors.groupingBy(a -> a[0], TreeMap::new,
Collectors.mapping(a -> Arrays.asList(a[1].split("\\s+")), Collectors.toList())));
System.out.println(collect);
}
}
您希望使用
LinkedHashMap
来保留原始顺序。因此,您的代码应该如下所示:
Map<String, List<String>> collect = customList.stream()
.map(s -> s.split(" +"))
.collect(Collectors.toMap(a -> a[0], a -> Arrays.asList(a)
.subList(1, a.length), (a, b) -> a, LinkedHashMap::new));
TreeMap
按键对条目进行排序。你想使用的LinkedHashMap
正是ernest_k所说的。你不想在这里分类。您希望保留顺序。这会产生预期的输出。或者,如果原始列表可能包含冲突,则(a,b)->a
可能是一个列表合并函数(不要忽略数组。asList()
返回一个不可扩展的列表)。@Thomas Yes,我假设键是唯一的。否则,正如Arvind所建议的那样,groupBy是实现这一点的方法(或者当然是toMap中合适的合并函数)。请注意,对于合并函数(第三个参数Collectors.toMap()
takes),您也可以这样做Collectors.groupingBy()
实际上将合并移动到下游,即toList()
收集器将处理该问题。@ernest_k这似乎是一个可以理解的原因,也意味着您认为这很重要。;-)我可以想象,对于大的输入字符串,您确实不想拆分两次。如果知道键是唯一的,那么使用groupBy
而不是toMap
有什么好处吗?@ThanosM-已经有很多很好的答案描述了这两个词之间的区别,例如,您可以检查。我希望每个词在列表
。在您的解决方案中,所有元素都位于相同的列表
条目中。例如,我想要10000=[撒哈拉以南非洲和澳大利亚]
@ThanosM-我出去吃午饭了。刚刚看到您的评论,并发布了一个更新,作为此需求的解决方案。如有任何进一步的疑问/问题,请随时发表评论。
{10000=[[sub-Saharan, Africa, and, Australia.]], 5000=[[Buruli, ulcer, is, an, infectious, disease]], 6000=[[characterized, by, the, development]], 7000=[[of, painless, open, wounds.]], 8000=[[The, disease, largely, occurs, in]]}
Map<String, List<String>> collect = customList.stream()
.map(s -> s.split(" +"))
.collect(Collectors.toMap(a -> a[0], a -> Arrays.asList(a)
.subList(1, a.length), (a, b) -> a, LinkedHashMap::new));
collect = customList.stream()
.map(s -> Arrays.asList(s.split(" +")))
.collect(Collectors.groupingBy(l -> l.get(0),
LinkedHashMap::new,
Collectors.flatMapping(l -> l.stream().skip(1), Collectors.toList())));