我正在创建一个解析文件中所有字符的类,并查找每个字母的出现次数。
一步,当我浏览添加字符的文件时,我会检查字符列表是否已包含我所在的特定字符。如果没有,则将其添加到列表中,其出现值为1,如果已经包含它,则会将出现值增加1。
但是,我的下面的代码没有正确确定列表是否已包含特定字符。
我正在使用一个ArrayList,我知道我必须覆盖我所做的CharProfile类中的equals方法,以便让包含()的equals()方法正常工作。
在CharProfile中覆盖等于方法:
@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());
}
}
}
Full 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;
}
}
}
问题简而言之:当检查列表是否已包含该char时,它不会返回true,而是总是返回false,导致文件中的每个char都被添加到列表中,而它应该只是唯一的
答案 0 :(得分:1)
这只是将对象引用比较为相同,并且实例是Character
而不是CharProfile
。
@Override
public boolean equals(Object o) {
if (this.character == ((Character)o)) {
return true;
}
else {
return false;
}
}
您需要更改等号方法以接受CharProfile
的实例并比较其中的字符值,如下所示:
@Override
public boolean equals(Object o) {
if(this.character == ((CharProfile)o).getCharacter()) {
return true;
}else {
return false;
}
}
编辑:您的等号方法未被调用,因为您将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);
}
答案 1 :(得分: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();
}