SetUniqueList、HashSet 和 Set 不会从对象列表中删除重复项
SetUniqueList, HashSet and Set don't remove duplicates from a List of an object
我一直在尝试做的是对列表中的对象进行排序,并从同一个列表中删除重复的对象。
这里是对象的class
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" 实例,我一直在尝试从该列表中删除重复项。
我在 Whosebug 上找到了几种方法。
SetUniqueList
List<Word> NoDup = SetUniqueList.setUniqueList(WordsListWithNumber);
哈希集
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" 的列表中删除重复项,但似乎无法从 class.[=16= 的列表中删除重复项]
我通过这样做检查了列表的内容...但是它们都显示相同的值。
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.
我意识到"number"属性应该命名为"quantity"...好像有人认为这个"number"属性是身份证号码之类的东西,但实际上它表示"WordsList" 包含多少个相同的词。
我想比较 "wordname",而不是 "number"。
抱歉造成混淆,我的母语不是英语。
如果您想从 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 以获取对此的解释)。
这是 Word
的一种可能的 hashCode
方法。
@Override
public int hashCode() {
return wordName.hashCode();
}
如果你这样做你会发现如果list
是一个List<Word>
,你可以通过写
来删除重复项
list = new ArrayList<Word>(new LinkedHashSet<Word>(list));
有关如何编写 equals
、hashCode
和 compareTo
方法的完整详细信息(如果数字很大,您的 compareTo
方法可能会失败),我推荐Joshua Bloch 的书 Effective Java。
祝你好运!
我一直在尝试做的是对列表中的对象进行排序,并从同一个列表中删除重复的对象。
这里是对象的class
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" 实例,我一直在尝试从该列表中删除重复项。
我在 Whosebug 上找到了几种方法。
SetUniqueList
List<Word> NoDup = SetUniqueList.setUniqueList(WordsListWithNumber);
哈希集
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" 的列表中删除重复项,但似乎无法从 class.[=16= 的列表中删除重复项]
我通过这样做检查了列表的内容...但是它们都显示相同的值。
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.
我意识到"number"属性应该命名为"quantity"...好像有人认为这个"number"属性是身份证号码之类的东西,但实际上它表示"WordsList" 包含多少个相同的词。
我想比较 "wordname",而不是 "number"。 抱歉造成混淆,我的母语不是英语。
如果您想从 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 以获取对此的解释)。
这是 Word
的一种可能的 hashCode
方法。
@Override
public int hashCode() {
return wordName.hashCode();
}
如果你这样做你会发现如果list
是一个List<Word>
,你可以通过写
list = new ArrayList<Word>(new LinkedHashSet<Word>(list));
有关如何编写 equals
、hashCode
和 compareTo
方法的完整详细信息(如果数字很大,您的 compareTo
方法可能会失败),我推荐Joshua Bloch 的书 Effective Java。
祝你好运!