1.概述
set集合的特点是:set无序,不可以有重复元素
hashset:数据结构为哈希表,线程是非同步的。保证元素唯一性的原理是:判断元素的hashcode值是否相同,如果相同,还会继续判断元素的euals方法,是否为ture;为ture,则是同一个对象,否则不是。
treeset:可以对set集合元素进行排序,数据结构为二叉树。保证元素唯一性的原理是:compareTo方法返回0;
简单说:hashset去重(hashcode,equals),散列。treeset方法:去重(实现comparale或comparator接口重写自定义方法中,compareto方法返回0的条件是判断去重的依据),排序(实现comparale或comparator接口重写自定义方法中,compareto方法返回的+1,-1,0,进行排序)
2.使用treeset实现去重:1.自定义一个对象,2.定义一个容器,让其具有比较性(实现comparator接口,重写compare方法),将此对象作为参数传入 treeset中,
public class Teacher {
private String name;
private int age;
/**
* Creates a new instance of Teacher.
*
* @param name
* @param age
*/
public Teacher(String name, int age) {
super();
this.name = name;
this.age = age;
}
/**
* name.
*
* @return the name
* @since JDK 1.6
*/
public String getName() {
return name;
}
/**
* name.
*
* @param name the name to set
* @since JDK 1.6
*/
public void setName(String name) {
this.name = name;
}
/**
* age.
*
* @return the age
* @since JDK 1.6
*/
public int getAge() {
return age;
}
/**
* age.
*
* @param age the age to set
* @since JDK 1.6
*/
public void setAge(int age) {
this.age = age;
}
}
}
public class MyCompare implements Comparator<Object> {
@Override
public int compare(Object o1, Object o2) {
// TODO Auto-generated method stub
Teacher s1=(Teacher)o1;
Teacher s2=(Teacher)o2;
int n=s1.getName().compareTo(s2.getName());
if(n==0){//姓名相同,比较统计数
n=new Integer(s1.getAge()).compareTo(s2.getAge());
}
return n;
}
}
测试类:
System.out.println("==================");
Set<Teacher> t=new TreeSet<Teacher>(new MyCompare());
t.add(new Teacher("liu",89));
t.add(new Teacher("jian",123));
t.add(new Teacher("jian",123));
t.add(new Teacher("juf",123));
t.add(new Teacher("four",4));
t.add(new Teacher("ni",56));
t.add(new Teacher("ni",56));
t.add(new Teacher("hao",23));
System.out.println("排序后遍历:");
for(Teacher s:t){
System.out.println(s.getName()+"=="+s.getAge());
}
结果为:
排序后遍历:
1.four==4
2.hao==23
3.jian==123
4.juf==123 //
5.liu==89
6.ni==56
结论:结果的3,4说明:只有name,age同时相同才判断为同一对象。符合我们在自定义 的compare方法中定义的:姓名相同比较age,如果age比较后返回0,既是同一个对象,去重。
2.使用hashset实现去重:我们知道treeset,hashset存储的类型为string,interger等常用类型均能实现自动的去重。但如果要实现自定义对象实现去重效果,则需要自定义对象实现equals和hashcode方法。
2.1 以对象的所有属性相同作为重复的依据
public class EntityTerm2 {
private String name;//名称
private String termNature;//词性
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTermNature() {
return termNature;
}
public void setTermNature(String termNature) {
this.termNature = termNature;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((age == null) ? 0 : age.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result
+ ((termNature == null) ? 0 : termNature.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EntityTerm2 other = (EntityTerm2) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (termNature == null) {
if (other.termNature != null)
return false;
} else if (!termNature.equals(other.termNature))
return false;
return true;
}
public EntityTerm2(String name, String termNature, String age) {
super();
this.name = name;
this.termNature = termNature;
this.age = age;
}
}
public class Test {
public static void main(String[] args){
Set<EntityTerm2> et2=new HashSet<EntityTerm2>();//
et2.add(new EntityTerm2("zhangsan","nr","123"));
et2.add(new EntityTerm2("zhangsan","nrd","1234"));
et2.add(new EntityTerm2("lisi","ntc","45"));
et2.add(new EntityTerm2("wanwu","nr","4"));
for(EntityTerm2 e:et2){
System.out.println(e.getName()+"!!!"+e.getAge());
}
}
}
结果为:
lisi!!!45
wanwu!!!4
zhangsan!!!1234
zhangsan!!!123
修改元素有相同值时:
public class Test {
public static void main(String[] args){
Set<EntityTerm2> et2=new HashSet<EntityTerm2>();//使用treeset存放对象,对象必须实现comparable接口,hashset则不用
et2.add(new EntityTerm2("zhangsan","nr","123"));
et2.add(new EntityTerm2("zhangsan","nr","123"));
et2.add(new EntityTerm2("lisi","ntc","45"));
et2.add(new EntityTerm2("wanwu","nr","4"));
for(EntityTerm2 e:et2){
System.out.println(e.getName()+"!!!"+e.getAge());
}
}
}
结果为:
lisi!!!45
wanwu!!!4
zhangsan!!!123
1.2 以对象的name的值相同作为重复的依据
public class EntityTerm2 implements Comparable<EntityTerm2> {
private String name;//名称
private String termNature;//词性
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTermNature() {
return termNature;
}
public void setTermNature(String termNature) {
this.termNature = termNature;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EntityTerm2 other = (EntityTerm2) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public EntityTerm2(String name, String termNature, String age) {
super();
this.name = name;
this.termNature = termNature;
this.age = age;
}
}
public class Test {
public static void main(String[] args){
Set<EntityTerm2> et2=new HashSet<EntityTerm2>();//使用treeset存放对象,对象必须实现comparable接口
et2.add(new EntityTerm2("zhangsan","nrd","123"));//hashset则不用,实现了去重
et2.add(new EntityTerm2("zhangsan","nr2","123d"));
et2.add(new EntityTerm2("lisi","ntc","45"));
et2.add(new EntityTerm2("wanwu","nr","4"));
for(EntityTerm2 e:et2){
System.out.println(e.getName()+"!!!"+e.getAge());
}
}
}
结果为:
zhangsan!!!123
lisi!!!45
wanwu!!!4