抱歉,如果这是一个愚蠢的问题,我对使用 map 还很陌生。
static void redacted(Map<List<String>, List<String>> whatComesNext, List<String> text) {
List<String> maurice = new ArrayList<String>(); //feeds the double string key to the map whatComesNext
List<String> masterHash = new ArrayList<String>(); //keeps track of the first two non "<START>" keys
List <String> bryan = new ArrayList<String>(); //returns a double value to the map when masterhash appears
masterHash.add(text.get(2)); //adds third element of the list to masterHash
masterHash.add(text.get(3)); //adds fourth element to masterHash
for (int i=0; i<=text.size()-3; i++) {
maurice.clear();
maurice.add(text.get(i)); //gets nth element of the list and adds to maurice
maurice.add(text.get(i+1)); //gets element following the nth one
if (maurice.equals(masterHash)) { //assigns two strings to masterHash key instead of one
bryan.add(text.get(i+2));
bryan.add(text.get(i+3));
whatComesNext.put(masterHash, bryan);
}
else {
whatComesNext.put(maurice, Arrays.asList(text.get(i+2)));
}
}
}
目的是根据提供的字符串列表“文本”用一组特定的键和值组装给定的空映射,whatComesNext。每个键都是一个字符串列表,其中包含文本中的一对单词。例如,给定一个包含 7 个元素的列表,键将是包含元素 [0] 和元素 [1]、元素 [1] 和元素 [2] 等的列表,直到最终键包含元素 [5] 和[6].
分配给每个键的值将是文本中紧跟在键中两个字符串之后的元素。例如,键 <0 1> 将具有值 <2>。如果您有字符串列表“你好,StackOverflow,我需要你的帮助。” (用 .split("") 分隔字符串的地方) HashMap 将是
[Hello/there, StackOverflow]
[there/StackOverflow,, I]
[StackOverflow,/I, need]
[I/need, your]
[need/your, help.]
其中斜杠表示包含两个元素的字符串列表,即斜杠之前和之后的字符串。
这里的一个小问题是,每个字符串列表“文本”都可以假设其前两个元素为“”,最后一个元素为“”。这些仍然被视为常规键和值(因此 [/Hello, StackOverflow] 的哈希对是合理的)第一个不包含“”的键必须具有以下两个字符串的值列表。
希望我还没有失去你。这是测试我的想法的代码:
List<String> prisoner =
Arrays.asList("<START> <START> I am not a number. I am a free man! <END>".split(" "));
Map<List<String>, List<String>> whatComesNext = new LinkedHashMap<>();
MarkovText.learnFromText(whatComesNext, prisoner);
System.out.println(whatComesNext);
assertEquals(10, whatComesNext.size());
assertEquals(Arrays.asList("not", "a"),
whatComesNext.get(Arrays.asList("I", "am")));
assertEquals(Arrays.asList("free"),
whatComesNext.get(Arrays.asList("am", "a")));
assertEquals(Arrays.asList("<END>"),
whatComesNext.get(Arrays.asList("free","man!")));
为此,我认为一切正常,除了我以某种方式返回“masterHash”键后面的接下来的四个元素而不是接下来的两个元素。
编辑:我还需要提到,如果包含前两个非“”字符串的键稍后在循环中被覆盖(如果这些字符串以相同的顺序再次出现),则覆盖的值列表仍然包含以下两个字符串。
最佳答案
您的代码的一个大问题是您正在更改 map 键的状态,在将该键放入 map 后,您不应该永远这样做。契约(Contract)被破坏,它影响了 map 上的每项操作。
您应该为每对单词创建一个新的键对象。更好的选择是使用不可变对象(immutable对象)作为映射键。
关于java - Hashmap 未收到预期值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47028107/