Set集合的特点
不包含重复元素的集合
没有带索引的方法,所以不能使用普通for循环遍历
HashSet对集合的迭代顺序不作任何保证
Set集合的遍历
有两种方式遍历一种是迭代器一种是增强for
package dayhou40.day49; import java.util.HashSet; import java.util.Set; public class SetTest { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("hello"); set.add("hi"); set.add("hello"); set.add("last"); for (String s : set) { System.out.println(s); } } }
Set集合没有什么 特殊的功能需要我们学习它的功能全部来自Collection集合
哈希值
哈希值:是根据jdk对象的地址或者字符或者数字算出来的的int类型的数值
Object对象中的public int hashCode:返回对象的哈希码值
package dayhou40.day50; public class student { private String name; private int age; public student(String name, int age) { this.name = name; this.age = age; } public student() { } 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; } }
package dayhou40.day50; public class hashCodeTest { public static void main(String[] args) { student s1 = new student("张三", 12); System.out.println(s1.hashCode()); System.out.println(s1.hashCode()); student s2 = new student("张三", 12); System.out.println(s2.hashCode()); } }
我们由上面可以得到结论:
同一个对象多次调用hashCode()方法返回的Hash值是相同的
默认情况下,实现不同对象的Hash值是不同的
通过重写Hashcode方法得到的Hash值是相同的
package dayhou40.day50; import java.util.Objects; public class student { private String name; private int age; public student(String name, int age) { this.name = name; this.age = age; } public student() { } 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; } @Override public int hashCode() { return 0; } }
注意String重写了object中的hashcode
HashSet保证集合元素唯一性的原因
如果Hash表未初始化,就对其进行初始化
根据对象的哈希值计算对象的存储位置,如果该位置没有元素,就存储元素
如果有元素则存入的元素和以前的元素进行比较Hash值
如果Hash值不同,会继续执行下去,把元素添加进来
如果哈希值相同则通过equals()方法比较如果都相同则不存储,否则就存储
LinkedHashSet
特点
1.哈希表和链表实现的set接口,具有可预测的迭代次数
2.由链表保证元素有序,也就是说元素的存储顺序和取出顺序是一致的
3.由哈希表保证元素的唯一性
package dayhou40.day51; import java.util.LinkedHashSet; public class LinkedhashsetTest { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("hi"); set.add("hello"); set.add("world"); set.add("world"); for (String s : set) { System.out.println(s); } } }
TreeSet集合
Treeset集合的特点
-
元素有序性(这个有序性不是指存入和取出的顺序一致而是按照一定的规则进行排序,具体方法取决于构造方法)
-
TreeSet():根据元素的自然排序进行排序
-
TreeSet(Comparator comparator):根据指定的比较器排序
-
-
由于没有索引所以不能使用普通for遍历
-
是set集合不存在重复元素
自然排序
package dayhou40.day51; import java.util.TreeSet; public class TreesetTest { public static void main(String[] args) { TreeSet<Integer> set = new TreeSet<>(); set.add(30); set.add(20); set.add(30); set.add(10); set.add(90); for (Integer integer : set) { System.out.println(integer); } } }
Comparable的使用
package dayhou40.day52; public class student { private String name; public int age; public student(String name, int age) { this.name = name; this.age = age; } public student() { } 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; } }
package dayhou40.day52; import java.util.TreeSet; public class comparableTest { public static void main(String[] args) { TreeSet<student> set = new TreeSet<>(); student s1 = new student("张三", 22); student s2 = new student("李四", 23); student s3 = new student("王五", 20); set.add(s1); set.add(s2); set.add(s3); for (student student : set) { System.out.println(student.getName()+" "+student.getAge()); } } }
结果出现了报错
这是为什么呢? 因为自然排序实现了compareTo方法 而在我们的学生类中我们没有继承comparable接口重写compareTo方法
这个规则如果返回值是0那么就会存储一个元素
这个规则如果返回值是1那么就会按照升序排序
这个规则如果返回值是-1那么就会按照降序排序
那么如何按照年龄的升序排序呢?
package dayhou40.day52; public class student implements Comparable<student>{ private String name; public int age; public student(String name, int age) { this.name = name; this.age = age; } public student() { } 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; } @Override public int compareTo(student o) { return this.getAge()-o.getAge(); } }
如果想要升序this就放在前面,如果想要降序this就放在后面
ComparaTo方法的使用
package dayhou40.day52; public class student{ private String name; public int age; public student(String name, int age) { this.name = name; this.age = age; } public student() { } 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; } }
package dayhou40.day52; import java.util.Comparator; import java.util.TreeSet; public class comparableTest { public static void main(String[] args) { TreeSet<student> set = new TreeSet<>(new Comparator<student>() { @Override public int compare(student o1, student o2) { int sum1= o1.getAge()-o2.getAge(); int sum2= o1.getAge()==o2.getAge()?o1.getName().compareTo(o2.getName()):sum1; return sum2; } }); student s1 = new student("张三", 22); student s2 = new student("李三", 22); student s3 = new student("李四", 23); student s4 = new student("王五", 20); set.add(s1); set.add(s2); set.add(s3); set.add(s4); for (student student : set) { System.out.println(student.getName()+" "+student.getAge()); } } }
我们在TreeSet<>(new Comparator<student>()然后进行排序