我一直想做的是对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;
}
}
这是主要方法的一部分
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上找到了几种方法。
SetUniqueList
List<Word> NoDup = SetUniqueList.setUniqueList(WordsListWithNumber);
HashSet的
HashSet hs = new HashSet();
hs.addAll(WordsListWithNumber);
WordsListWithNumber.clear();
WordsListWithNumber.addAll(hs);
集
Set<Word> noDupSet = new LinkedHashSet<Word>(WordsListWithNumber);
List<Word> noDup = new ArrayList<>();
noDup.addAll(noDupSet);
我已经确认所有这些方法都可以从“String”列表中删除重复项,但它似乎没有从此类的List中删除重复项。
我通过这样做来检查列表的内容......但是它们都显示相同的值。
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());
如果您愿意提供任何见解,我将不胜感激。
P.S。
我意识到“数字”属性应该被命名为“数量”......似乎有些人认为这个“数字”属性类似于ID号,但它实际上表明了多少相同的单词“WordsList” “包含。
我想比较“wordname”,而不是“数字”。 抱歉令人困惑,我不是母语为英语的人。
答案 0 :(得分:2)
如果要从List
中删除重复项,则需要指定何时考虑重复两项。重要的是要指定,因为在您的情况下,对word1
和word2
重复的含义至少有4种可能的解释:
word1 == word2
。word1.number == word2.number
word1.wordName.equals(word2.wordName)
word1.number == word2.number && 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以获得解释)。
以下是hashCode
的可能Word
方法。
@Override
public int hashCode() {
return wordName.hashCode();
}
如果您执行此操作,您会发现如果list
是List<Word>
,则可以通过编写
list = new ArrayList<Word>(new LinkedHashSet<Word>(list));
有关如何编写equals
,hashCode
和compareTo
方法的详细信息(如果数字很大,您的compareTo
方法可能会失败),我建议使用Java作者:Joshua Bloch。