ArrayList 作为 HashMap 中的键

2022-09-02 00:55:55

是否可以添加 一个 作为 的键。我想保留双目的频率计数。双字母是关键,值是它的频率。ArrayListHashMap

对于每个像“他是”这样的双行者,我为它创建一个并将其插入到.但是我没有得到正确的输出。ArrayListHashMap

public HashMap<ArrayList<String>, Integer> getBigramMap(String word1, String word2) {
    HashMap<ArrayList<String>, Integer> hm = new HashMap<ArrayList<String>, Integer>();
    ArrayList<String> arrList1 = new ArrayList<String>();
    arrList1 = getBigram(word1, word2);
    if (hm.get(arrList1) != null) {
        hm.put(arrList1, hm.get(arrList1) + 1);
    } else {
        hm.put(arrList1, 1);
    }
    System.out.println(hm.get(arrList1));
    return hm;
}


public ArrayList<String> getBigram(String word1, String word2) {
    ArrayList<String> arrList2 = new ArrayList<String>();
    arrList2.add(word1);
    arrList2.add(word2);
    return arrList2;
}

答案 1

是的,您可以在哈希映射中使用s作为键,但这是一个非常糟糕的主意,因为它们是可变的ArrayList

如果您以任何方式(或其任何元素)更改,映射基本上将丢失,因为密钥将与插入时的密钥不同。ArrayListhashCode

经验法则是仅使用不可变数据类型作为哈希映射中的键。正如 Alex Stybaev 所建议的那样,您可能希望创建一个这样的类:Bigram

final class Bigram {

    private final String word1, word2;

    public Bigram(String word1, String word2) {
        this.word1 = word1;
        this.word2 = word2;
    }

    public String getWord1() {
        return word1;
    }

    public String getWord2() {
        return word2;
    }

    @Override
    public int hashCode() {
        return word1.hashCode() ^ word2.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return (obj instanceof Bigram) && ((Bigram) obj).word1.equals(word1)
                                       && ((Bigram) obj).word2.equals(word2);
    }
}

答案 2

为什么不能使用这样的东西:

class Bigram{
    private String firstItem;
    private String secondItem;

    <getters/setters>

    @Override
    public int hashCode(){
        ...
    }

    @Override 
    public boolean equals(){
        ...
    }
}

而不是对有限数量的项目(两个)使用动态集合。