【问题标题】:How does get() work on hashmapget() 如何在 hashmap 上工作
【发布时间】:2012-04-23 08:43:29
【问题描述】:

当java从hashmap调用get方法时java会执行equals()比较吗?

我读过它确实如此,但由于我遇到的错误,它似乎在进行 == 比较。

公共类 UniversalFiniteStateAutomaton {

State currentState;
State initialState;
State trapState;

public UniversalFiniteStateAutomaton(ArrayList<String> finalStates,
        ArrayList<String> transitions) {
    String statesAndTransitions[];
    Map<Symbol<E>, State> createdStates = new HashMap<Symbol<E>, State>();
    for (String s : transitions) {
        // Replace the stuff that doesn't matter
        s = s.replaceAll("[()]", "");
        // Split the transition into states and transitions
        statesAndTransitions = s.split("\\s+");

        // Create the state if its not already created
        if (finalStates.contains(new Symbol(statesAndTransitions[0]))) {
            if (!createdStates.containsKey((new Symbol(statesAndTransitions[0])))) {
                createdStates.put(new Symbol(statesAndTransitions[0]),
                        new FinalState(this));
                System.out.println("Created one symb " + new Symbol(statesAndTransitions));
            }
        } else {
            if (!createdStates.containsKey(new Symbol(statesAndTransitions[0]))) {
                createdStates.put(new Symbol(statesAndTransitions[0]),
                        new NormalState(this));
                System.out.println("Created one symb " + new Symbol(statesAndTransitions[0]));
            }
        }
        // Make sure that the next state is created
        if (finalStates.contains(new Symbol(statesAndTransitions[2]))) {
            if (!createdStates.containsKey(new Symbol(statesAndTransitions[2]))) {
                createdStates.put(new Symbol(statesAndTransitions[2]),
                        new FinalState(this));
            }
        } else {
            if (!createdStates.containsKey(new Symbol(statesAndTransitions[2]))) {
                createdStates.put(new Symbol(statesAndTransitions[2]),
                        new NormalState(this));
            }
        }

        System.out.println(createdStates);
        // Define the transition
        createdStates.get(new Symbol(statesAndTransitions[0])).addTransition(
                new Symbol(statesAndTransitions[1]),
                createdStates.get(new Symbol(statesAndTransitions[2])));

    }
    this.currentState = createdStates.get(new Symbol("0"));
}

public String analyzeInput(String input) {
    String splitInput[] = input.split("\\s+");
    for(String s: splitInput)
        try {
            currentState.transition(new Symbol(s));
        } catch (TrapException e) {
            return("Reject");
        }
    if(currentState.type()==0)
        return "Accept";
    return "Reject";
}


public void setState(State currentState) {
    this.currentState = currentState;
}
 }




public class Symbol<E> {
private E symbol;

public Symbol(E symbol){
    this.symbol = symbol;
}

public E getSymbol() {
    return symbol;
}

public void setSymbol(E symbol) {
    this.symbol = symbol;
}

public String toString(){ return "" +symbol;}

}

【问题讨论】:

  • 需要更多信息......你到底想做什么?代码 sn-ps 也会有所帮助
  • 请向我们展示您的代码,以及您遇到的确切错误。 Have you implemented both equals and hashCode properly on your key objects?
  • 另一个需要考虑的重要事情是 HashMap 键应该是不可变的(至少只要它们在 Map 中)。如果某个键在放入 HashMap 后更改了其 hashCode,则查找将无法正常工作。
  • 如果有人需要快速方法,我通过在 eclipse 下转到以下内容来修复它:source --> generate hashcode and equals

标签: java hashmap


【解决方案1】:

是的。但是,如果您没有为自己的类定义自己的equals(),它会使用Object.equals(),而确实使用==。这就是为什么如果你想将你的对象放入一个集合中,你应该覆盖equals()(和hashcode())。

【讨论】:

  • 如果您想将您的对象用作 HashMap 中的键。 Collections 中的其他用途可能适用于默认实现。
  • 如果你想把对象放在一个集合中,你应该重写'equals'和'hashCode'的说法过于宽泛了。您无需覆盖任何一个即可将它们放入List;如果你想将它们放在TreeMapTreeSet 中,你需要覆盖equals,但不是hashCode,但你可能确实需要实现Comparable
  • @TomAnderson:如果你想使用 indexOf 之类的东西,你可能仍然需要 equalsList 中。
  • @TomAnderson:实际上,如果您将它们放在TreeMap 中,您应该 覆盖equals(),而不需要这样做。如果你覆盖equals(),根据惯例,你应该也覆盖hashCode()。根据comparator的javadocs:It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)).
  • @amit:如果实例身份适合您,则无需覆盖 equals。
【解决方案2】:
【解决方案3】:

它使用 hashcode() 来定位潜在的匹配,然后使用 equals 来找到精确匹配。如果其用户定义的对象,请确保实现 equals 和 hashcode 以遵守合同(在 Object 的类文档中提到)。

【讨论】:

    【解决方案4】:

    get 首先使用 == 来检查它是否是同一个对象。如果不是,则使用等于。

    在此处查看代码 http://www.docjar.com/html/api/java/util/HashMap.java.html

    /**
      298        * Returns the value to which the specified key is mapped,
      299        * or {@code null} if this map contains no mapping for the key.
      300        *
      301        * <p>More formally, if this map contains a mapping from a key
      302        * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
      303        * key.equals(k))}, then this method returns {@code v}; otherwise
      304        * it returns {@code null}.  (There can be at most one such mapping.)
      305        *
      306        * <p>A return value of {@code null} does not <i>necessarily</i>
      307        * indicate that the map contains no mapping for the key; it's also
      308        * possible that the map explicitly maps the key to {@code null}.
      309        * The {@link #containsKey containsKey} operation may be used to
      310        * distinguish these two cases.
      311        *
      312        * @see #put(Object, Object)
      313        */
      314       public V get(Object key) {
      315           if (key == null)
      316               return getForNullKey();
      317           int hash = hash(key.hashCode());
      318           for (Entry<K,V> e = table[indexFor(hash, table.length)];
      319                e != null;
      320                e = e.next) {
      321               Object k;
      322               if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
      323                   return e.value;
      324           }
      325           return null;
      326       }
    

    【讨论】:

    • @PéterTörök:错了。第 322 行。
    • 为什么要看 if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
    【解决方案5】:

    【讨论】:

    • 更重要的是,它使用哈希码首先找到合适的桶。
    【解决方案6】:

    Hashmap 使用 hashcode() 首先找到合适的桶,如果在桶中找到多个条目,则使用 equals 方法。

    如果您没有根据您的要求在您的类中定义 equals 方法,那么它将使用父类 Object 的定义,这是简单的“==”操作。

    如果您使用您的类作为 hashmap 中的键,最好覆盖 hashcode 和 equals 方法。

    【讨论】:

      猜你喜欢
      • 2014-09-29
      • 2013-03-16
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      相关资源
      最近更新 更多