HashMap 不替换值

HashMap not replacing values

我想做的是检查输入的 10 个字符长的子字符串是否在输入中重复,如果重复,我需要将其添加到列表中。此列表不能有重复项。为此,我使用了 HashMap。以下是我的程序逻辑:

检查子字符串是否在我的 HashMap 中。如果不是,那么我想将映射 (substring, 1) 添加到我的地图中。如果是并且映射 = 1,那么我想将它添加到我的 ls ArrayList 并将其映射增加 1。

奇怪的是,我下面的代码似乎没有替换到递增整数的映射(参见下面的 println 和程序标准输出)。我知道我可以用 HashSet 解决这个问题,但我想知道为什么 HashMap 的行为如此奇怪(我想了解它是如何工作的)以及我如何使用 HashMap 解决这个问题。请参阅下面的输入、代码和输出:

输入:“AAAAAAAAAAAAAA”

代码:

class Solution {
public List<String> findRepeatedDnaSequences(String s) {
    int begin_window=0;
    List<String> ls = new ArrayList<String>();
    HashMap<String,Integer> hm = new HashMap<String,Integer>();
    while(begin_window+10<=s.length()){
        String temp = s.substring(begin_window,begin_window+10);
        if( hm.put(temp,1) != null){
            System.out.println(hm.get(temp));
            if( hm.get(temp) == 1){
                ls.add(temp);
                hm.put(temp,2);
            }
        }
        begin_window++;
    }
    return ls;
}

}

输出:

["AAAAAAAAAA","AAAAAAAAAA","AAAAAAAAAA"]

输出应该是 ["AAAAAAAAAA"],因为我们不希望重复

Stdout:
1
1
1

对于那些好奇的人,这里是问题的来源:https://leetcode.com/problems/repeated-dna-sequences/

您可以使用上面的 link 来测试我的代码。

提前致谢!

除了算法,我会使用Map<String, MutableInt>(来自apache commons-lang3)并做类似的事情:

首先,您数数:

HashMap<String,Integer> hm = new HashMap<String,Integer>();
while(begin_window+10<=s.length()){
  String temp = s.substring(begin_window,begin_window+10);
  hm.computeIfAbsent(temp, ignored -> new MutableInt(0))
    .increment();
}

然后你发现重复的序列:

hm.entrySet()
  .stream()
  .filter(entry -> entry.getValue().intValue() > 1)
  .forEach(entry -> { // or use map(Map.Entry::getKey).collect(toList())
    System.out.println(entry.getKey() + ": " + entry.getValue());
  }); 

注意: MutableInt 不是义务。您可以以 unboxing/boxing 为代价坚持使用 Integer。您可以使用 AtomicInteger 但这不是同一个目的。

由于我的名气太小无法评论:

如果 Key 已经存在,HashMap.put() 方法不会 return null。 它没有任何 return 值,因为它无论如何都是空的。

如果 Key 已经存在于 HashMap 中,并且您对其调用 .put() 方法,它只会覆盖关联的值。

在您的情况下,必须使用 HashMap.containsKey() 检查键是否已存在于地图中。这 return 是对还是错。

您可以在 if 条件下检查它并执行增量和其他所有操作:

class Solution {
public List<String> findRepeatedDnaSequences(String s) {
    int begin_window=0;
    List<String> ls = new ArrayList<String>();
    HashMap<String,Integer> hm = new HashMap<String,Integer>();
    while(begin_window+10<=s.length()){
        String temp = s.substring(begin_window,begin_window+10);
            if ( hm.containsKey(temp)) { // check if key exists
                Int newValue = hm.get(temp); // get value
                newValue++;  // increase it
                ls.add(temp); // add to your list
                hm.put(temp,newValue);
                System.out.println(hm.get(temp));
            } else {
                hm.put(temp,1);
        }
        begin_window++;
    }
    return ls;
}

JavaDoc 让您快速了解 HashMap 的方法:https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html