这里输入了word并称为容器,它是一个存储字集合。
public class Part1 {
public static void main(String[] args) {
WordContainer wc = new WordContainer();
Scanner in = new Scanner(System.in);
String line;
while (in.hasNextLine() && !"stop".equals(line = in.nextLine())) {
wc.put(new Word(line));
}
in.close();
print();
}
public static void print() {
for (Word w : WordContainer.al) {
System.out.println(w + ": " + w.getfrequency());
}
}
}
存储单词的容器。如果单词在表格中,我们会增加频率,如果不是 - 添加新单词
public class WordContainer {
public static ArrayList<Word> al = new ArrayList<Word>();
public Word put(Word s) {
for (Word w : al) {
if (w.s.compareTo(s.getWord()) == 0) {
s.setfrequency();
} else {
al.add(new Word());
}
}
return s;
}
}
存储单词的单词类别及其出现频率
public class Word implements Comparable<Word> {
String s = "";
private int frequency = 0;
Word(String s) {
this.s = s;
frequency = 1;
}
Word() {
setfrequency();
}
public void setfrequency() {
++frequency;
}
public int getfrequency() {
return frequency;
}
public String getWord() {
return s;
}
@Override
public int compareTo(Word o) {
return s.compareTo(o.getWord());
}
}
我无法理解为什么它不起作用。 请帮帮我!
答案 0 :(得分:1)
如果找不到单词,则添加一个新的Word
,其中包含空字符串,而不仅仅是作为参数传递的Word
(或具有相同内容的副本)。此外,您为每个 Word
添加了一个新的Word
,其内容不匹配...
此外,增强的for循环尝试在修改后继续遍历列表,从而导致ConcurrentModificationException
。
此外,您可能希望从列表中返回Word
,而不是从参数传递的那个
按如下方式更改代码:
public Word put(Word s) {
for (Word w : al) {
if (w.s.compareTo(s.getWord()) == 0) {
w.setfrequency();
// found it, now stop searching
return w;
}
}
// didn't find it; insert
al.add(s);
return s;
}
我的代码中有几件事我认为设计不好:
static
中使用了WordContainer
列表,但put
方法是一种实例方法。这意味着将在WordContainer
的所有实例中共享数据,但您需要创建一个实例来调用put
。该列表也应该是非static
字段。WordContainer
类的“内部数据”为public
。此外Word
是可修改的(您可以在其上调用setfrequency
),这可以让您轻松打破封装。解决此问题的最简单方法是将Word
类设为WordContainer
的内部类,将setfrequency
方法更改为private
并将String
传递给put
方法。public class WordContainer {
public static class Word implements Comparable<Word> {
private final String s;
private int frequency;
private Word(String s) {
this.s = s;
frequency = 1;
}
/*Word() {
this("");
}*/
private void setfrequency() {
++frequency;
}
public int getfrequency() {
return frequency;
}
public String getWord() {
return s;
}
@Override
public int compareTo(Word o) {
return s.compareTo(o.getWord());
}
}
private final List<Word> al = new ArrayList<Word>();
private final List<Word> unmodifiableWords = Collections.unmodifiableList(al);
public Word put(String s) {
for (Word w : al) {
if (w.s.equals(s)) {
w.setfrequency();
return w;
}
}
Word word = new Word(s);
al.add(word);
return word;
}
public List<Word> getWords() {
// do not allow for external modification of the list
return unmodifiableWords;
}
}
答案 1 :(得分:0)
我认为问题在于您班级put
中的WordContainer
方法。您正在向列表中添加新的Word
对象,而不是使用方法中传递的对象。
if (w.s.compareTo(s.getWord()) == 0) {
s.setfrequency();
} else {
al.add(new Word()); // This is the likely reason, remove this line
// you should not be adding a new object
al.add(s); // Try this, you should be adding the object s
}
更新:
您现有的实施需要进行2项更改,之前我没有意识到这一点。
首先,您需要查看您在WordContainer
中列出的内容是否已获得该词。如果没有,那么你需要添加它。
第二,要使其正常工作,您需要在Word方法中覆盖equals方法,因为contains
方法会尝试使用equals
来比较对象
public Word put(Word s) {
if (al.contains(s)) {
for (Word w : al) {
if (w.s.compareTo(s.getWord()) == 0) {
s.setfrequency();
}// else { //Remove this else, as you add element outside
// al.add(s);
//}
}
} else
al.add(s);
return s;
}
并覆盖equals
课程中的Word
方法。 Eclipse生成的典型覆盖方法如下所示:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Word other = (Word) obj;
if (frequency != other.frequency)
return false;
if (s == null) {
if (other.s != null)
return false;
} else if (!s.equals(other.s))
return false;
return true;
}
更新2:
Fabian的答案是一种很好而优雅的方式。
答案 2 :(得分:0)
这是我拍摄的一个问题。我认为问题在于WordContainer put方法。
public class WordContainer {
public static ArrayList<Word> al = new ArrayList<Word>();
public Word put(Word s) {
for (Word w : al) {
if (w.s.compareTo(s.getWord()) == 0) {
//s.setfrequency();
w.setfrequency(); // <-- set frequency of existing word in al
return w; // <-- return word object that is in al
}
// no need to add new word to list after every failed comparison
// unless that's what you want to do.
}
al.add(s);
return s;
}