Hashmap未收到预期值

时间:2017-10-31 04:50:58

标签: java string arraylist hashmap linkedhashmap

对不起,如果这是一个愚蠢的问题,我对使用地图很新。

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)));
      }
    }
  }

目的是根据提供的字符串列表“text”,将给定的空映射whatComesNext与一组特定的键和值组合在一起。每个键都是一个String列表,其中包含一对来自文本的单词。例如,给定7个元素的列表,键将是包含元素[0]和元素[1],元素[1]和元素[2]等的列表,直到最后一个键包含元素[5]和[6]。

分配给每个键的值将是紧跟在键中两个字符串之后的文本中的元素。例如,密钥&lt; 0 1&gt;将具有值&lt; 2&gt;。如果您有字符串列表“Hello there StackOverflow,我需要您的帮助。” (你用.split(“”)分隔字符串的地方)hashmap将是

  

[Hello / there,StackOverflow]

     

[there / StackOverflow ,, I]

     

[StackOverflow,/ I,need]

     

[我/需要,你的]

     

[需要/你,帮助。]

斜杠表示包含两个元素的String列表,斜杠前后的字符串。

虽然这里的细微之处在于每个字符串列表“text”可以假设其前两个元素为“”,其最后一个元素为“”。这些仍被视为常规键和值(因此[/ 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”键而不是接下来的两个键后面返回接下来的四个元素。

编辑:我还需要提一下,如果包含前两个非“”字符串的密钥稍后在循环中被覆盖(如果这些字符串再次以相同的顺序出现),则覆盖的值列表仍然包含以下两个字符串。

1 个答案:

答案 0 :(得分:2)

您的代码的一个大问题是您正在更改地图密钥的状态,在将该密钥放入地图后,您应该从不执行此操作。合同被破坏,它会影响地图的每个操作。

您应该为每对单词创建一个新的密钥对象。一个更好的选择是使用不可变对象作为映射键。