【问题标题】:SetUniqueList, HashSet and Set don't remove duplicates from a List of an objectSetUniqueList、HashSet 和 Set 不会从对象列表中删除重复项
【发布时间】:2015-01-03 02:34:23
【问题描述】:

我一直在尝试做的是对 List 中的对象进行排序并从同一个 List 中删除重复的对象。

这是对象的类

public class Word implements Comparable<Word>{

private String wordName;
private int number;

 // There are only simple constructers, getters and setters 

 // This compareTo might be irrelevant for this question
@Override
public int compareTo(Word word) {
    int compareNumber = ((Word) word).getNumber();
    return compareNumber - this.number;

    }
}

这里是main方法的一部分

public class CommentEvaluationTester {
 final static private List<String> WordsList = new ArrayList<>();

 public static void main(String[] args) {

    boolean isContained;
    String comment = "";
    //This "comment" actually has a long string value
        for (String word : WordsInDB) {
        //WordsInDB is a List, containing String values

        isContained = comment.toLowerCase().contains(word.toLowerCase());
        if (isContained) {
            WordsList.add(word);
        }
    }

     List WordsListWithNumber = new ArrayList<>();

     for (String word : WordsList) {
            int occurrences = Collections.frequency(WordsList, word);

            Word addWord = new Word(word, occurrences);
            WordsListWithNumber.add(addWord);

     }

     //This might be irrelevant too   
     Collections.sort(WordsListWithNumber, new Comparator<Word>() {
            @Override
           public int compare(Word w1, Word w2) {
                return w2.getNumber() - w1.getNumber();
            }
        });

在这个阶段,“WordsListWithNumber”列表包含多个“Word”实例,我一直在尝试从该列表中消除重复项。

我在 Stackoverflow 上找到了几种方法。

  1. 设置唯一列表

    List<Word> NoDup = SetUniqueList.setUniqueList(WordsListWithNumber);
    
  2. 哈希集

    HashSet hs = new HashSet();
        hs.addAll(WordsListWithNumber);
        WordsListWithNumber.clear();
        WordsListWithNumber.addAll(hs);
    
  3. 设置

    Set<Word> noDupSet = new LinkedHashSet<Word>(WordsListWithNumber);
       List<Word> noDup = new ArrayList<>();
       noDup.addAll(noDupSet);
    

我已经确认所有这些方法都可以从“字符串”列表中删除重复项,但它似乎没有从此类列表中删除重复项。

我通过这样做检查了列表的内容...但是它们都显示相同的值。

    Word testWord = (Word) noDup.get(0);
    System.out.println("test1: noDup.get(0) : " + testWord.getWordName() + " , number : " + testWord.getNumber());
    testWord = (Word) noDup.get(1);
    System.out.println("test2: noDup.get(1) : " + testWord.getWordName() + " , number : " + testWord.getNumber());

如果您能提供任何见解,我将不胜感激。

附言

我意识到“数字”属性应该被命名为“数量”......似乎有些人认为这个“数字”属性类似于ID号,但它实际上表示“WordsList”中有多少个相同的单词" 包含。

我想比较“字名”,而不是“数字”。 抱歉,我的母语不是英语。

【问题讨论】:

  • 等待;你如何确定“重复”?这是Comparable.equals()/.hashCode() 的结果吗?
  • 为什么你的Comparable 只检查number
  • 问题是我们不知道wordNamenumber之间是否应该有任何联系。无论如何,基于减法的比较器不符合compareTo 的约定,因为减法可能会溢出。
  • >fge,只要删除重复项,任何选项都可以。我使用“Comparable”来按“number”属性对“WordsListWithNumber”列表进行排序。 (即我想对列表进行排序,以便第一个单词具有最大的“数字”属性)老实说,我还不熟悉 .equals()/.hashCode() 。我使用了 SetUniqueList、HashSet 和 Set,只是因为它们经常出现在 Stackoverflow 上。
  • >Elliott,我使用 Comparable 来对“WordsListWithNumber”列表进行排序,因为我希望列表中的第一个“单词”具有最大的“数字”属性。我没有用它来删除重复项... Comparable 可以用来删除重复项吗?

标签: java


【解决方案1】:

如果您想从List 中删除重复项,则需要指定何时将两个项目视为重复项。指定很重要,因为在您的情况下,word1word2 重复的含义至少有 4 种可能的解释:

  1. word1 == word2
  2. word1.number == word2.number
  3. word1.wordName.equals(word2.wordName)
  4. word1.number == word2.number &amp;&amp; word1.wordName.equals(word2.wordName)

你已经表明你的意思是 3。

您指定重复的含义的方法是覆盖equals 方法。你可以这样做。

@Override
public boolean equals(Object object) {
    return object instanceof Word && ((Word) object).wordName.equals(wordName);
}

无论何时覆盖equals 方法,您也必须覆盖hashCode。 (搜索 SO 以获取相关解释)。

这是Word 的一种可能的hashCode 方法。

@Override
public int hashCode() {
    return wordName.hashCode(); 
}

如果你这样做你会发现如果list是一个List&lt;Word&gt;,你可以通过写删除重复项

list = new ArrayList<Word>(new LinkedHashSet<Word>(list));

有关如何编写equalshashCodecompareTo 方法的完整详细信息(如果数字很大,您的compareTo 方法可能会失败),我推荐Joshua Bloch 的《Effective Java》一书。

祝你好运!

【讨论】:

  • 非常感谢...现在它可以按我的意愿工作了!我也去看看书。
  • 我很高兴能帮上忙 :)。你必须得到那本书。我从那本书中学到了关于 Java 的所有知识。
猜你喜欢
  • 2017-06-23
  • 2019-12-07
  • 2021-12-11
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多