Set接口的特点:
import javax.swing.text.html.HTMLDocument;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*使用hashset存储字符串并遍历
* set集合的特点:
* 1 无序(存储和读取的顺序有可能不一样)
* 2 元素不允许重复,要求元素唯一 最多只有一个null元素
* 3 没有索引*/
public class HashSetDemo {
public static void main(String[] args) {
//创建集合对象
HashSet<String> hs = new HashSet<String>();
Set<String> set = new HashSet<String>(); //父接口引用指向子类对象
//添加元素对象
set.add("hello");
set.add("world");
set.add("java");
//遍历集合对象 转数组 迭代器 增强for
//转数组
Object[] obj = set.toArray();
for (int i = 0; i < obj.length; i++) {
System.out.println(obj[i]);
}
//迭代器
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
//增强for
for (String s : set) {
System.out.println(s);
}
}
}
HashSet 存储自定义对象并遍历及解决HashSet中的去重问题。
import java.util.HashSet;
import java.util.Objects;
/*
* 利用HashSet存储自定义对象并遍历
* 分析为什么hashset存储自定义对象时没有去重:
* 通过查看源码发现:
* HashSet的add方法,首先会使用当前集合中的每一个元素和新添加的元素将进行hash值比较,如果hash值不一样则直接添加新的元素
* 如果hash值一样,比较地址值或者使用equals方法进行比较
* 如果比较结果一样 则以为是重复不添加
* 所有的比较结果都不一样则添加*
* 改进我们的程序 使HashSet存储自定义对象并去重
* 1 重写hashCode()方法 使其返回一样的哈希值
* 2 重写equals()方法 来比较是否有重复的对象
*
* hashcode()和equals()方法的改进
*/
public class HashSetDemo2 {
public static void main(String[] args) {
//创建集合对象
HashSet<Student> hs = new HashSet<Student>();
//创建元素对象
Student s1 = new Student("zhangsan",18);
Student s2 = new Student("lisi",20);
Student s3 = new Student("lisi",20);
//添加元素对象
hs.add(s1);
hs.add(s2);
hs.add(s3);
//遍历集合对象
for (Student student:hs) {
System.out.println(student.age);
}
}
}
class Student{
String name;
int age;
public Student(String name,int age)
{
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) { //重写equals方法
System.out.println("sssssssssssssss");
Student s = (Student)o; //向下转型 可以获取子类特有成员
if(this.age!=s.age)
return false;
if(!this.name.equals(s.name))
return false;
return true;
}
@Override
public int hashCode() { //使hash值一样 这样才能用equals方法进行比较
return 1;
}
}
HashSet去重方法的改进:
import java.util.HashSet;
import java.util.Objects;
/*
传统的去重:使HashSet存储自定义对象并去重
* 1 重写hashCode()方法 使其返回一样的哈希值
* 2 重写equals()方法 来比较是否有重复的对象
hashcode()和equals()方法的改进
我们发现放hashcode方法永远返回整数一时,所有对象的哈希值都是一样的
有一些对象的成员变量完全不同,但是他们还需要hash和equals方法的比较
如果我们可以让成员变量不同的对象,他们的哈希值不同,这就可以减少一部分equals方法的比较
可以尝试这让hashcode方法的返回值和对象的成员变量有关 例:hashcode的返回值不是return 1,而是return age;这样就减少了一部分equals方法的比较
可以让hashcode方法返回所有成员变量之和,让基本类型可以直接相加,然后引用数据类型,获取hashcode返回值后再相加(boolean类型不可以参加运算)
return age+name.hashcode(); 效率相对提高了很多
* */
public class HashSetDemo3 {
public static void main(String[] args) {
//创建集合对象
HashSet<Person> hs = new HashSet<Person>();
//创建元素对象
Person s1 = new Person("zhangsan",18);
Person s2 = new Person("lisi",20);
Person s3 = new Person("lisi",20);
//添加元素对象
hs.add(s1);
hs.add(s2);
hs.add(s3);
//遍历集合对象
for (Person person:hs) {
System.out.println(person.age);
}
}
}
class Person{
public String name;
public int age;
public Person(String name,int age)
{
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
System.out.println("............");
//提高效率
if(this == o) //向下转型之前的这些都是为了提高程序的健壮性
return true;
if(this.getClass()!=o.getClass())
return false;
Person p = (Person)o; //向下转型
if(this.age!=p.age)
return false;
if(!this.name.equals(p.name))
return false;
return true;
}
@Override
public int hashCode() {
return age+name.hashCode();
}
}