【问题标题】:Adding object to arraylist unless it's already there将对象添加到数组列表,除非它已经存在
【发布时间】:2016-10-10 10:06:31
【问题描述】:

我应该通读一个文件,将所有新单词添加到一个数组列表中,如果该单词已经在列表中,则增加一个计数器来计算它出现的次数。我读的很好,但是在将它们添加到列表时,它似乎忽略了检查单词是否已经在列表中并添加相同单词的倍数的部分。我有什么:

阅读方法:

public void read(String text) throws Exception{
  File fileText = new File(text);
  Scanner in = new Scanner(fileText);
  while(in.hasNextLine()){
    newWord = new Word(in.nextLine());
    add(newWord.text);
    }
  }

添加到arraylist的方法

public void add(String text){
  for(Word o: wordList){
    if(wordList.contains(newWord.text){
      newWord.increaseCount();
    }else{
      wordList.add(newWord);  
     }
   }

非常感谢一些帮助,我完全不知道问题出在哪里......

【问题讨论】:

  • 使用地图会更方便
  • Java 集合的“包含”方法依赖于它们包含的类型(在您的情况下为 Word.java)的“等于”和“哈希码”方法。如果这些方法没有从 Object 覆盖,它们将不会进行“语义”比较(这两个字符串是否相同),而是内存引用比较(这两个指针是否位于同一位置)。阅读有关 equals 和 hashcode 的更多信息,这将是有意义的。
  • 顺便说一句:在您的 add 方法中,您遍历您的 wordlist 并为每次迭代执行包含检查 + 添加。因此,如果您的列表有 10 个元素大并且您调用 add 方法,则新值将被插入一次,然后计数器增加 9 倍。 (或者如果您的 Word 对象没有覆盖“equals”和“hashcode”正确,它将被插入 10 次)。您需要删除“for(Word o: wordList)”循环。无论如何,您都不使用“o”对象。所以这是一种毫无意义的迭代。
  • 另外,您的 add 方法接受一个参数“Sting text”,然后绝对不使用它。这不可能是正确的。

标签: java arraylist


【解决方案1】:

在使用 for-each 循环迭代列表时,您不能在结构上修改列表。

在文档中说明 -

结构修改是添加或删除一个或 更多元素,或显式调整后备数组的大小;只是设置 元素的值不是结构修改

看到这个 -

In Java, can you modify a List while iterating through it?

【讨论】:

  • 但是如何遍历列表以检查它是否已经包含对象?
  • @Telanore 在我的回答中我说你不能在结构上修改列表,即从列表中执行添加或删除,当然你可以检查列表是否包含对象,但为此你必须覆盖 equals 和 hashcode 方法,希望你这样做,如果没有看到这个 - stackoverflow.com/questions/2265503/…
【解决方案2】:

看来newWord 是你自定义类的一个实例。你的单词表应该是一个字符串列表而不是这种类型,因为你对文本进行检查(我假设它是一个字符串)。这就是为什么每个对象都被添加到列表中,因为您使用 newWord 文本检查实例地址。所以改变 wordList.add(newWord);到 wordList.add(newWord.text);

【讨论】:

    【解决方案3】:

    我猜,因为您没有包含 Word 类的代码。

    下面是您的 add 方法的编写方式。您要么添加计数,要么添加一个新单词。我还假设单词的大小写无关紧要。

    public void add(String text){
        for (Word o: wordList) {
            if (o.getWord().equalsIgnoreCase(text) {
                o.increaseCount();
                return;
            }   
        }
        wordList.add(new Word(text.toLowerCase());
    }
    

    您的 read 方法只是调用 add 方法。

    public void read(String text) throws Exception{
       File fileText = new File(text);
       Scanner in = new Scanner(fileText);
       while (in.hasNextLine()) {
           add(in.nextLine().trim());
       }
       in.close();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 2012-09-12
      • 2019-12-23
      • 1970-01-01
      • 2013-09-03
      • 2012-08-02
      • 2020-07-25
      • 2013-04-27
      • 2013-02-22
      相关资源
      最近更新 更多