blu*_*sky 5 java hashset treeset
下面的类输出是:大小是3大小是1
但是,如果我将TreeSet更改为HashSet,那么:
Set<SuggestionDetailBean> set = new TreeSet<SuggestionDetailBean>();
Run Code Online (Sandbox Code Playgroud)
变
Set<SuggestionDetailBean> set = new HashSet<SuggestionDetailBean>();
Run Code Online (Sandbox Code Playgroud)
输出是:大小是3大小是2
使用HashSet或TreeSet大喊不改变Set的大小?使用HashSet似乎表现得像预期的那样,因为它正在删除重复项,但是当我使用TreeSet时,重复项仍然存在?我认为SuggestionDetailBean中的hashcode和equals方法是否被正确覆盖?
这是代码:
public class TestSet {
public static void main(String args[]){
SuggestionDetailBean s = new SuggestionDetailBean();
s.setTagList("teddst");
s.setUrl("testurl");
SuggestionDetailBean s2 = new SuggestionDetailBean();
s2.setTagList("teddst");
s2.setUrl("testurl");
SuggestionDetailBean s3 = new SuggestionDetailBean();
s3.setTagList("tessdafat");
s3.setUrl("fdfaasdfredtestur ldd");
List<SuggestionDetailBean> list = new ArrayList<SuggestionDetailBean>();
list.add(s);
list.add(s2);
list.add(s3);
Set<SuggestionDetailBean> set = new TreeSet<SuggestionDetailBean>();
set.addAll(list);
System.out.println("size is "+list.size());
System.out.println("size is "+set.size());
}
}
public class SuggestionDetailBean implements Comparable<Object> {
private String url;
private String tagList;
private String numberOfRecommendations;
private String date;
private String time;
private String summary;
private String truncatedUrl;
public void setTruncatedUrl(String truncatedUrl) {
if(truncatedUrl.length() > 20){
truncatedUrl = truncatedUrl.substring(0, 20)+"...";
}
this.truncatedUrl = truncatedUrl;
}
public String getSummary() {
if(summary == null){
return "";
}
else {
return summary;
}
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTime() {
return time;
}
public String getTruncatedUrl() {
return this.truncatedUrl;
}
public void setTime(String time) {
this.time = time;
}
public String getTagList() {
if(tagList == null){
return "";
}
else {
return tagList;
}
}
public void setTagList(String tagList) {
this.tagList = tagList;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getNumberOfRecommendations() {
return numberOfRecommendations;
}
public void setNumberOfRecommendations(String numberOfRecommendations) {
this.numberOfRecommendations = numberOfRecommendations;
}
@Override
public int compareTo(Object o) {
DateFormat formatter;
Date date1 = null;
Date date2 = null;
SuggestionDetailBean other = (SuggestionDetailBean) o;
if(this.date == null || other.date == null){
return 0;
}
formatter = new SimpleDateFormat(SimpleDateFormatEnum.DATE.getSdfType()+" "+SimpleDateFormatEnum.TIME.getSdfType());
try {
date1 = (Date) formatter.parse(this.date + " " + this.time);
date2 = (Date) formatter.parse(other.date + " " + other.time);
} catch (ParseException e) {
System.out.println("Exception thrown in"+this.getClass().getName()+", compareTo method");
e.printStackTrace();
}
catch(NullPointerException npe){
System.out.println("Exception thrown "+npe.getMessage()+" date1 is "+date1+" date2 is "+date2);
}
return date2.compareTo(date1);
}
@Override
public int hashCode() {
return this.url.hashCode();
}
@Override
public boolean equals(Object obj) {
SuggestionDetailBean suggestionDetailBean = (SuggestionDetailBean) obj;
if(StringUtils.isEmpty(this.getTagList())){
return this.getUrl().equals(suggestionDetailBean.getUrl());
}
else {
return (this.getTagList().equals(suggestionDetailBean.getTagList())) &&
(this.getUrl().equals(suggestionDetailBean.getUrl()));
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:注意:如果我使用以下方法将hashset转换为树集:
Set<SuggestionDetailBean> sortedSet = new TreeSet<SuggestionDetailBean>(hashset);
Run Code Online (Sandbox Code Playgroud)
然后保持正确的排序,因为重复的删除基于对象哈希码并且等于方法而不是比较方法.
rua*_*akh 15
根据Javadoc的TreeSet说法:
请注意,如果要正确实现接口,则由集合维护的排序(无论是否提供显式比较器)必须与equals一致
Set.(参见Comparable或Comparator了解与equals一致的精确定义.)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此两个被认为相等的元素从集合的角度来看,方法是相等的.一套的行为 是明确的,即使它的排序和equals不一致; 它只是不遵守Set界面的一般合同.
所以,问题在于你的compareTo方法:要么是给出不一致的结果,要么就是给出一致的结果,这些结果不符合当前a.compareTo(b) == 0和仅当的规则a.equals(b).
例如,这一位:
if(this.date == null || other.date == null){
return 0;
}
Run Code Online (Sandbox Code Playgroud)
意思是"如果有this或other有date == null,然后报告this并且other相等",这当然不是你想要的.