1

我正在创建一个类,它解析文件中的所有字符并查找每个字母的出现次数。

在一个步骤中,当我浏览添加字符的文件时,我检查字符列表是否已经包含我所在的特定字符。如果没有,它将其添加到列表中,出现值为 1,如果它已经包含它,则将出现值加 1。

但是,我下面的代码没有正确确定列表是否已经包含特定字符。

我正在使用 ArrayList,并且我知道我必须重写 CharProfile 类中的 equals 方法,我这样做了,以便让 contains() 使用的 equals() 方法正常工作。

覆盖 CharProfile 中的 equals 方法:

    @Override
    public boolean equals(Object o) {
        if (this.character == ((Character)o)) {
            return true;
        }
        else {
            return false;
        }
    }

代码:

import java.util.*;
import java.io.*;

public class HuffmanCoder {
    public static void main(String[] args) throws IOException {
        Scanner keyboard = new Scanner(System.in);

        System.out.print("Please enter the name of the file to be read from: ");
        String fileName = keyboard.nextLine();

        File file = new File(fileName);
        Scanner inputFile = new Scanner(file);

        int charCount = 0;
        ArrayList<CharProfile> charOccurrences = new ArrayList<CharProfile>();

        while (inputFile.hasNext()) {
            // Grabs the next word in the file and converts it into a char array
            String word = inputFile.next();
            char[] wordArray = word.toCharArray();

            // Parses the word on a char-by-char basis
            for (int i = 0; i < wordArray.length; i++) {
                if (wordArray[i] != ' ') {
                    charCount++;

                    // Constructs the list of chars and their respective number of occurrences
                    if (!charOccurrences.contains(wordArray[i])) {
                        charOccurrences.add(new CharProfile(wordArray[i]));
                    }
                    else {
                        for (int j = 0; j < charOccurrences.size(); j++) {
                            if (charOccurrences.get(j).getCharacter() == wordArray[i]) {
                                charOccurrences.get(j).incremementOccurrences();
                                break;
                            }
                        }
                    }
                }
            }
        }

        // Figure out each char's probability
        for (int i = 0; i < charOccurrences.size(); i++) {
            System.out.println(charOccurrences.get(i).getCharacter());
        }
    }   
}

完整的 CharProfile 类:

public class CharProfile {
    private char character;
    private int occurrences;
    private double probability;

    public CharProfile(char character) {
        this.character = character;
        occurrences = 1;
    }

    public void incremementOccurrences() {
        occurrences++;
    }

    public char getCharacter() {
        return character;
    }

    public void setCharacter(char character) {
        this.character = character;
    }

    public int getOccurrences() {
        return occurrences;
    }

    public void setOccurrences(int occurrences) {
        this.occurrences = occurrences;
    }

    public double getProbability() {
        return probability;
    }

    public void setProbability(double probability) {
        this.probability = probability;
    }

    public boolean equals(char character) {
        if (this.character == character) {
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this.character == ((Character)o)) {
            return true;
        }
        else if (this.character == ((Character)o).charValue()) {
            return true;
        }
        else {
            return false;
        }
    }
}

简而言之:在检查列表是否已包含该字符时,它不会返回 true,而是似乎总是返回 false,从而导致文件中的每个字符都被添加到列表中,而它应该只是唯一的字符。

4

2 回答 2

1

这只是比较对象引用是否相同,并且实例Character不是CharProfile

@Override
public boolean equals(Object o) {
    if (this.character == ((Character)o)) {
        return true;
    }
    else {
        return false;
    }
}

您需要更改您的 equals 方法以接受实例CharProfile并比较其中的字符值,如下所示:

@Override
public boolean equals(Object o) {
    if(this.character == ((CharProfile)o).getCharacter()) {
        return true;
    }else {
        return false;
    }
}

编辑:您的 equal 方法没有被调用,因为您将 char 传递给contains方法。

请将其更改为:

         // Constructs the list of chars and their respective number of occurrences
         CharProfile charProfile = new CharProfile(wordArray[i]);
         if (!charOccurrences.contains(charProfile)) {
              charOccurrences.add(charProfile);
         }
于 2012-10-28T23:56:28.950 回答
0

你犯了一个典型的错误:==混淆equals().

在java中(不同于javascript):

  • ==测试两个操作数是否是同一个实例
  • equals()具有与 相同的默认行为==,但在实现时通常会测试两个操作数是否具有相同的

如果你改变所有你==.equals()问题应该得到解决。


您的equals()方法有太多代码 - 它可以用这个替换,它的作用完全相同

@Override
public boolean equals(Object o) {
    return this.character.equals(o);
}

但我会这样做,以处理所有合理的类型:

@Override
public boolean equals(Object o) {
    if (o instanceof Character) {
        return character.equals(o);
    }
    if (o instanceof CharProfile) {
        return character.equals(((CharProfile)o).character);
    }
    return false;
}


此外,在覆盖时,equals()您还应该覆盖hashCode()以保持一致 - 即返回正在比较的值的 hashCode,如下所示:

@Override
public int hashCode() {
    return character.hashCode();
}
于 2012-10-29T00:27:50.620 回答