说我有Map<List<String>, List<String>> whatComesNext
,
在for循环中,对于每次迭代,我想将List<String> text
的第n个元素添加到whatComesNext
的值。为什么我不能执行whatComesNext.put(key, whatComesNext.get(key).add(text.get(n)))
?我们的想法是从散列映射中的相应键中检索值,并将所需的String添加到其中。这假设hashmap中的每个键都有一个值。
以下是我的完整代码:
static void learnFromText(Map<List<String>, List<String>> whatComesNext, List<String> text) {
for (int i=0; i<=text.size()-3; i++) {
if (whatComesNext.containsKey(Arrays.asList(text.get(i),text.get(i+1)))==false) {
whatComesNext.put(Arrays.asList(text.get(i),text.get(i+1)), Arrays.asList(""));
}
whatComesNext.put(Arrays.asList(text.get(i),text.get(i+1)), whatComesNext.get(Arrays.asList(text.get(i),text.get(i+1))).add(text.get(i+2)));
}
}
Arrays.asList()
看起来很复杂,但这是因为我试图初始化我自己的字符串列表来尝试保存我的键和值时得到空映射,有人告诉我这是因为我反复清除列表钥匙和钥匙值已分配给,将它们保留为空。我以为我会通过直接引用原始List<String> text
来解决这个问题,因为它保持不变。我们的想法是首先检查地图中是否存在某个键,如果是,则为其分配一个空List作为值,然后将text
中的字符串添加到地图的值中。
运行代码时出现的错误是行Error: incompatible types: boolean cannot be converted to java.util.List<java.lang.String>
中的whatComesNext.get(Arrays.asList(text.get(i),text.get(i+1))).add(text.get(i+2)));
。我不明白这可能会出错,因为我没有看到哪个方法返回一个布尔值。
答案 0 :(得分:2)
错误来自List.add(Object o)
返回boolean
而非List本身的事实。声明Map
包含List<String>
的实例作为值。如果您只想为列表添加值,只需从地图中检索它并在其上调用add
即可。检查null
的获取过程的结果并创建一个新列表并将其放入地图中(如果是这样的话)
我也可以看到其他一些问题:
Arrays.asList(...)
创建具有相同元素的多个列表。这是一个主要的性能问题,而且您很幸运,返回的列表实际上是在实现equals
,因此您的逻辑实际上正在工作(我希望这是您的问题&#34;不会在更新之前#39; t&#34; -description。在不改变Map a键的类型的情况下 - 在我看来 - 更好的实现看起来像这样:
static void learnFromText(Map<List<String> whatComesNext, List<String>, List<String> text) {
for (int i=0; i<= text.size() - 3; i++) {
List<String> listKey = text.subList(i, i+2);
List<String> value = whatComesNext.get(listKey);
if (value == null) {
value = new ArrayList<>();
whatComesNext.put(listKey, value);
}
value.add(text.get(i+2)));
}
}
密钥列表的计算只发生一次,从而提高了性能并减少了资源需求。而且我认为它也更具可读性。
答案 1 :(得分:1)
.add()方法返回一个布尔值,括号错位,用这一行替换你的最后一行:
whatComesNext.put(Arrays.asList(text.get(i),text.get(i+1)), whatComesNext.get(Arrays.asList(text.get(i),text.get(i+1)))).add(text.get(i+2));