Set的实现类有HashSet类和LinkedHashSet类
-
Set接口的特点
Set体系的集合:
* 1、无序(存储和读取的顺序有可能不一样)
* 2、不允许重复(元素唯一)
* 3、无索引
package com.myset;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*
* 使用HsahSet存储字符串并且遍历
*
* Set的特点:
* 1、无序(存储和读取的顺序有可能不一样)
* 2、不允许重复(元素唯一)
* 3、无索引
*
*/
public class HashSetDemo01 {
public static void main(String[] args) {
//创建集合对象
//HashSet<String> hs = new HashSet<String>();
Set<String> set = new HashSet<String>();//多态,父接口引用指向子类对象(如果此时这样创建的话,
//我们是无法去调用子类的特有的成员方法的)
//添加元素对象
set.add("hello");
set.add("word");
set.add("java");
//遍历集合对象(3种)
//转数组
//method1(set);
//迭代器
//method2(set);
//增强for循环
method3(set);
}
private static void method3(Set<String> set) {
//增强for循环
for (String string : set) {
System.out.println(string);
}
}
private static void method2(Set<String> set) {
Iterator<String> it = set.iterator();//创建迭代器对象那个
while(it.hasNext()) {//如果有下一个元素
String str = it.next();//取下一个元素,直到取完(null)为止。
System.out.println(str);
}
}
private static void method1(Set<String> set) {
//转数组
Object[] obj = set.toArray();
for (int i = 0; i < obj.length; i++) {
System.out.println(obj[i]);
}
}
}
HashSet存储自定义对象没有去重的原因:
HsahSet:不允许重复(元素唯一)
*但是:通过源码查询发现HsahSet的add()方法首先会使用
*当前集合中的每一个元素和新添加的元素进行hash值比较
*如果hash值不一样则直接添加新的元素
*如果hash值一样,就去比较地址值或者使用equals方法进行比较
*比较结果一样,则认为是重复不添加
package com.myset;
import java.util.HashSet;
import java.util.Iterator;
/*
* 使用HashSet存储自定义对象并遍历
*/
public class HashSetDemo02 {
public static void main(String[] args) {
//创建集合对象
HashSet<Student> hs = new HashSet<Student>();
//创建元素对象
Student stu = new Student("二狗", 17);
Student stu2 = new Student("李东", 17);
Student stu3 = new Student("李东", 17);
//添加元素对象
hs.add(stu);
hs.add(stu2);
hs.add(stu3); /*OUT:Student [name=二狗, age=17]
Student [name=李东, age=17]
Student [name=李东, age=17]
HsahSet:不允许重复(元素唯一)
*但是:通过源码查询发现HsahSet的add()方法首先会使用
*当前集合中的每一个元素和新添加的元素进行hash值比较
*如果hash值不一样则直接添加新的元素
*如果hash值一样,就去比较地址值或者使用equals方法进行比较
*比较结果一样,则认为是重复不添加
*///??????
//遍历集合
for (Student student : hs) {
System.out.println(student);
/*OUT:Student [name=二狗, age=17]
Student [name=李东, age=17]*/
}
}
}
class Student{
String name;
int age;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
但是咋们要怎么去重呢?
@Override
public boolean equals(Object obj) {
System.out.println("-----------------");
Student s = (Student) obj;//向下转型可以获取类成员
if(this.age != s.age) {//比较年龄
return false;
}
if(!this.name.equals(s.name)) {//比较姓名
return false;
}
return true;//说明两个学生是相等的
}
@Override
public int hashCode() {
return 1;
}
重写它的equals(Object obj)方法和 hashCode()方法;
优化方案(equals(Object obj)少运行几次)
@Override
public int hashCode() {
//return 1;
return age+name.hashCode();//(优化方案)
}