List和Set都是collection接口下的,本节学习Set接口及其两个实现类HashSet和TreeSet。
Set中的元素不可重复,无序。几个常用的方法remove(),clear()等和上一节的List一样,就不写了。
HashSet相当于一个哈希表(操作时间复杂度一般是常数级),用hashcode和equals()保证不重复。
TreeSet相当于一个树(操作时间复杂度一般是对数级),可以实现comparable接口以作排序。
*测试HashSet
package day33;运行结果:
import java.util.HashSet;
import java.util.Iterator;
class Person
{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return id+":"+name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
HashSet<String> hs=new HashSet<String>();
//.添加
hs.add("three");
hs.add("one");
hs.add("two");
hs.add("one");//尝试重复添加
//.遍历
for(String e:hs)
{
System.out.print(e+" ");
}
System.out.println();
//.迭代器
Iterator<String> it=hs.iterator();
while(it.hasNext())
{
System.out.print(it.next()+" ");
}
System.out.println();
/**************************************/
HashSet<Person> hs2=new HashSet<Person>();
Person p1=new Person(1,"Tom");
Person p2=new Person(2,"Flora");
Person p3=new Person(3,"Json");
Person p4=new Person(2,"Flora");
//.添加
hs2.add(p1);
hs2.add(p2);
hs2.add(p3);
hs2.add(p4);
//.遍历
for(Person e:hs2)
{
System.out.print(e+" ");
}
System.out.println();
//.迭代器
Iterator<Person> it2=hs2.iterator();
while(it2.hasNext())
{
System.out.print(it2.next()+" ");
}
System.out.println();
}
}
one three two
one three two
3:Json 1:Tom 2:Flora 2:Flora
3:Json 1:Tom 2:Flora 2:Flora
可以看到泛型具体为String时是没有问题的,当用自己写的Person类时并没有识别出这两个2:Flora是相同的,而我们说Set是不能重复的,这就需要我们覆写equals()和hashCode()方法,以告诉它"如何判断相同"。
*覆写equals()和hashCode()方法
package day33;运行结果:
import java.util.HashSet;
import java.util.Iterator;
class Person
{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
Person p1=(Person)obj;//强制转换
return p1.id==this.id;//自己为这个类定义的判定一致的方式
}
@Override
public int hashCode() {
//如何指定唯一的hashCode是一门学问,这里只是一个演示
return this.id+this.name.hashCode();
}
@Override
public String toString() {
return id+":"+name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
HashSet<Person> hs2=new HashSet<Person>();
Person p1=new Person(1,"Tom");
Person p2=new Person(2,"Flora");
Person p3=new Person(3,"Json");
Person p4=new Person(2,"Flora");
//.添加
hs2.add(p1);
hs2.add(p2);
hs2.add(p3);
hs2.add(p4);
//.遍历
for(Person e:hs2)
{
System.out.print(e+" ");
}
System.out.println();
//.迭代器
Iterator<Person> it2=hs2.iterator();
while(it2.hasNext())
{
System.out.print(it2.next()+" ");
}
System.out.println();
}
}
1:Tom 2:Flora 3:Json
1:Tom 2:Flora 3:Json
*用Eclipse自动生成这两个方法
package day33;运行结果:
import java.util.HashSet;
import java.util.Iterator;
class Person
{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
//@Override
//public boolean equals(Object obj) {
//Person p1=(Person)obj;//强制转换
//return p1.id==this.id;//自己为这个类定义的判定一致的方式
//}
//
//@Override
//public int hashCode() {
////如何指定唯一的hashCode是一门学问,这里只是一个演示
//return this.id+this.name.hashCode();
//}
@Override
public String toString() {
return id+":"+name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.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;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
HashSet<Person> hs2=new HashSet<Person>();
Person p1=new Person(1,"Tom");
Person p2=new Person(2,"Flora");
Person p3=new Person(3,"Json");
Person p4=new Person(2,"Flora");
//.添加
hs2.add(p1);
hs2.add(p2);
hs2.add(p3);
hs2.add(p4);
//.遍历
for(Person e:hs2)
{
System.out.print(e+" ");
}
System.out.println();
//.迭代器
Iterator<Person> it2=hs2.iterator();
while(it2.hasNext())
{
System.out.print(it2.next()+" ");
}
System.out.println();
}
}
1:Tom 3:Json 2:Flora
1:Tom 3:Json 2:Flora
*测试TreeSet
package day33;这时出现了错误:
import java.util.TreeSet;
class Person
{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return id+":"+name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
TreeSet<String> ts=new TreeSet();
//.添加
ts.add("one");
ts.add("two");
ts.add("three");
ts.add("one");
//.遍历
for(String e:ts)
{
System.out.print(e+" ");
}
/***************************************/
TreeSet<Person> ts2=new TreeSet<Person>();
Person p1=new Person(1,"Tom");
Person p2=new Person(2,"Flora");
Person p3=new Person(3,"Json");
Person p4=new Person(2,"Flora");
//.添加
ts2.add(p1);
ts2.add(p2);
ts2.add(p3);
ts2.add(p4);
//.遍历
for(Person e:ts2)
{
System.out.print(e+" ");
}
}
}
放到TreeSet里的对象的类必须实现comparable接口(String本身已经实现了这个接口),并且实现这个接口中的compareTo()方法。
*实现了comparable接口的TreeSet测试
package day33;运行结果:
import java.util.TreeSet;
class Person implements Comparable<Person>
{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return id+":"+name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Person o) {
if(this.id>o.id)
return 1;
else if(this.id<o.id)
return -1;
return 0;
}
}
public class Test {
public static void main(String[] args) {
TreeSet<String> ts=new TreeSet();
//.添加
ts.add("one");
ts.add("two");
ts.add("three");
ts.add("one");
//.遍历
for(String e:ts)
{
System.out.print(e+" ");
}
/***************************************/
TreeSet<Person> ts2=new TreeSet<Person>();
Person p2=new Person(2,"Flora");
Person p1=new Person(1,"Tom");
Person p3=new Person(3,"Json");
Person p4=new Person(2,"Flora");
//.添加
ts2.add(p2);
ts2.add(p1);
ts2.add(p3);
ts2.add(p4);
//.遍历
for(Person e:ts2)
{
System.out.print(e+" ");
}
}
}
one three two 1:Tom 2:Flora 3:Json
可以看到Person对象是升序排列的,如果要降序排列,那么只要修改为:
@Override运行结果:
public int compareTo(Person o) {
if(this.id>o.id)
return -1;
else if(this.id<o.id)
return 1;
return 0;
}
one three two 3:Json 2:Flora 1:Tom