java - Hashmap 未收到预期值

标签 java string arraylist hashmap linkedhashmap

抱歉,如果这是一个愚蠢的问题,我对使用 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/

相关文章:

java - 如何使用 neo4j/Java 查找特定节点

android - 检查数组列表是否在android中多次包含一个值

java - 从 ArrayList 中删除某个字符串找到的第一个元素?

ruby - 字符串中的字母计数,Ruby

python - 将不同的列表数据类型连接成字符串

c++ - 确保文件扩展名与 C++ 中的文件类型匹配

Java:如何在arraylist中写入计算数据?

java - 当服务器不可用时抛出异常

java - 添加 JLabel 并使用 For 循环显示它

java - 如何为 GWT AutoBean 设置默认值?