Set(接口)集合:Set集合底下分别有HashSet和TreeSet。
HashSet类:无索引,不重复,无序;此类实现Set接口,由哈希表支持。它不保证set的迭代顺序,特别是不保证该顺序恒久不变,允许使用null元素
HashSet存储自定义对象并遍历
由例子可以看出,添加元素时地址不一样哈希值也不一样,所以我们需要在People类里头重写equals方法和hashCode方法,才能保证HashSet不重复
为了优化,对于hashCode方法,属性相同的对象返回值必须相同,属性不同的返回值尽量不同(提高效率);equals方法属性相同返回true,否则false,并存储
LinkedHashSet类:LinkedHash的子类,是底层是链表实现的,可以保证怎么存怎么取
小程序:产生10个1-20的随机数,不能重复,并输出
package pra_12;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Random;
public class J_22 {
public static void main(String[] args) {
//HashSet存储字符串并遍历
HashSet<String> hs=new HashSet<>();
boolean b1=hs.add("a");
System.out.println(b1); //true
boolean b2=hs.add("a");
System.out.println(b2); //false
hs.add("c");
System.out.println(hs); //[c, a]
for (String string : hs) { //只要能用迭代器迭代的就可以使用增强for循环遍历
System.out.println(string);
}
//HashSet存储自定义对象并遍历
//有下面例子可以看出,添加元素时地址不一样哈希值也不一样,所以我们需要在People类里头重写equals方法和hashCode方法,才能保证HashSet不重复
//为了优化,对于hashCode方法,属性相同的对象返回值必须相同,属性不同的返回值尽量不同(提高效率);equals方法属性相同返回true,否则false,并存储
HashSet<People> hs2=new HashSet<>();
boolean h3=hs2.add(new People("aa",11));
System.out.println(h3);
boolean h4=hs2.add(new People("aa",11));
System.out.println(h4);
hs2.add(new People("bb",22));
hs2.add(new People("cc",33));
System.out.println(hs2.size()); //4
System.out.println(hs2);
for (People people : hs2) {
System.out.println(people.getName()+"..."+people.getAge());
}
//LinkedHashSet
LinkedHashSet<String> lhs=new LinkedHashSet<>();
lhs.add("a");
lhs.add("c");
lhs.add("b");
lhs.add("d");
lhs.add("a");
System.out.println(lhs); //[a, c, b, d]
//产生10个1-20的随机数,不能重复,并输出
Random r=new Random();
HashSet<Integer> hs3=new HashSet<>();
while(hs3.size()<10){
hs3.add(r.nextInt(20)+1);
}
for (Integer integer : hs3) {
System.out.println(integer);
}
}
}
class People{
private String name;
private int age;
public People() {
super();
}
public People(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "People [name=" + name + ", age=" + age + "]";
}
/*
//重写的方法在这!!!
public boolean equals(Object obj) {
People p=(People)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
@Override
public int hashCode() {
final int NUM=38; //降低存在相同地址的几率
return name.hashCode()*NUM+age;
}
*/
//alt+shif+s +h,自动生成重写的方法在这!
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) //调用的对象和传入的对象是同一个对象
return true;
if (obj == null) //传入的对象是否为null
return false;
if (getClass() != obj.getClass()) //判断两个对象对应的字节码文件是否是同一个字节码
return false;
People other = (People) obj; //向下转型
if (age != other.age) //调用对象的年龄不等于传入对象的年龄
return false;
if (name == null) { //调用对象的姓名为null
if (other.name != null) //传入对象的姓名不为null
return false;
} else if (!name.equals(other.name)) //调用对象的姓名不等于传入对象的姓名
return false;
return true;
}
}