首页 > 解决方案 > 如何验证具有特定属性值的对象是否存在于arraylist中?

问题描述

我想通读一个文本文档,然后只将唯一的单词添加到“Word”对象的数组列表中。看来我现在的代码根本没有在 wordList 数组列表中输入任何单词。

public ArrayList<Word> wordList = new ArrayList<Word>();
    String fileName, word;
    int counter;
    Scanner reader = null;
    Scanner scanner = new Scanner(System.in);

try {
            reader = new Scanner(new FileInputStream(fileName));
        }
        catch(FileNotFoundException e) {
            System.out.println("The file could not be found. The program will now exit.");
            System.exit(0);
        }

    while (reader.hasNext()) {
                word = reader.next().toLowerCase();
                for (Word value : wordList) {
                    if(value.getValue().contains(word)) {
                        Word newWord = new Word(word);
                        wordList.add(newWord);
                    }
                }
                counter++;
            }

    public class Word {

        String value;
        int frequency;

        public Word(String v) {
            value = v;
            frequency = 1;
        }

        public String getValue() {
            return value;
        }

    public String toString() {
        return value + " " + frequency;
    }

}

标签: javaarraylist

解决方案


好吧,让我们从修复您当前的代码开始。您遇到的问题是,您只是在已经存在一个新单词对象时才向列表中添加一个新单词对象。相反,您需要在不存在时添加新的 Word 对象,否则增加频率。这是一个示例修复:

    ArrayList<Word> wordList = new ArrayList<Word>();
    String fileName, word;
    Scanner reader = null;
    Scanner scanner = new Scanner(System.in);

    try {
        reader = new Scanner(new FileInputStream(fileName));
    }
    catch(FileNotFoundException e) {
        System.out.println("The file could not be found. The program will now exit.");
        System.exit(0);
    }

    while (reader.hasNext()) {
            word = reader.next().toLowerCase();
            boolean wordExists = false;
            for (Word value : wordList) {
               // We have seen the word before so increase frequency.
               if(value.getValue().equals(word)) {
                    value.frequency++;
                    wordExists = true;
                    break;
               }
            }
            // This is the first time we have seen the word!
            if (!wordExists) {
                Word newValue = new Word(word);
                newValue.frequency = 1;
                wordList.add(newValue);
             }
        }
}

但是,这是一个非常糟糕的解决方案(O(n^2) 运行时)。相反,我们应该使用称为Map的数据结构,这将使我们的运行时间降低到 (O(n))

    ArrayList<Word> wordList = new ArrayList<Word>();
    String fileName, word;
    int counter;
    Scanner reader = null;
    Scanner scanner = new Scanner(System.in);

    try {
        reader = new Scanner(new FileInputStream(fileName));
    }
    catch(FileNotFoundException e) {
        System.out.println("The file could not be found. The program will now exit.");
        System.exit(0);
    }
    Map<String, Integer> frequencyMap = new HashMap<String, Integer>();
    while (reader.hasNext()) {
       word = reader.next().toLowerCase();
       // This is equivalent to searching every word in the list via hashing (O(1))
       if(!frequencyMap.containsKey(word)) {
          frequencyMap.put(word, 1);
       } else {
          // We have already seen the word, increase frequency.
          frequencyMap.put(word, frequencyMap.get(word) + 1);
       } 
    }

    // Convert our map of word->frequency to a list of Word objects.
    for(Map.Entry<String, Integer> entry : frequencyMap.entrySet()) {
      Word word = new Word(entry.getKey());
      word.frequency = entry.getValue();
      wordList.add(word);
    }
}

推荐阅读