Set集合特点:
(1)不包含重复元素的集合;
(2)没有带索引的方法,所以不能使用普通for循环遍历。
package Set_practice;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Set_1 {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("tjs");
set.add("pjh");
set.add("sjl");
set.add("pjh");//无效添加
//强制遍历
for (String s:set){
System.out.println(s);
}
//迭代器遍历
Iterator<String> it = set.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
public int hashCode();
默认情况下,不同对象的哈希值是不相同的;但是通过方法重写,可以实现不同对象的哈希值是相同的。
HashSet< E >集合 是Set的实现类
(1)底层数据结构是哈希表;
(2)对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序是一致的;
(3)没有带索引的方法,所以不能使用普通for循环遍历;
(4)由于是Set集合,所以是不包含重复元素的集合。
哈希表
JDK8之前,底层采用 数组+链表 实现,可以说是一个元素为链表的数组
JDK8以后,在长度比较长的时候,底层实现了优化
存储过程:先比较哈希值对16取模后的值确定存储位置;再比较哈希值,如果不同就直接存储,如果相同就比较内容,如果不同就存储,如果相同就不存储。
package Set_practice;
public class student {
private String name;
private int age;
private String number;
private String address;
public student(){}
public student(String name, int age, String number, String address){
this.name = name;
this.age = age;
this.number = number;
this.address = address;
}
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 getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public void show(){
System.out.println("姓名:"+this.name+" ,学号:"+this.number+" ,年龄:"+this.age+" ,居住地:"+this.address);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
student student = (student) o;
if (age != student.age) return false;
if (name != null ? !name.equals(student.name) : student.name != null) return false;
if (number != null ? !number.equals(student.number) : student.number != null) return false;
return address != null ? address.equals(student.address) : student.address == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
result = 31 * result + (number != null ? number.hashCode() : 0);
result = 31 * result + (address != null ? address.hashCode() : 0);
return result;
}
}
package Set_practice;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class hashset {
public static void main(String[] args) {
HashSet<student> s = new HashSet<student>();
student pijiahao = new student("pjh",23,"s200101207","chongqing");
student tanjinsen = new student("tjs",22,"s200101208","changsha");
student songjialin = new student("sjl",24,"s200101209","chengdu");
student songjialin2 = new student("sjl",24,"s200101209","chengdu");
s.add(pijiahao);
s.add(tanjinsen);
s.add(songjialin);
s.add(songjialin2);
for (student S:s){
S.show();
}
System.out.println("==============================================");
Iterator<student> it = s.iterator();
while (it.hasNext()){
student S = it.next();
S.show();
}
}
}
LinkedHashSet< E >集合
(1)哈希表和链表实现的Set接口,具有可预测的迭代次序;
(2)由链表保证元素有序,也就是元素存储和取出的顺序是一致的;
(3)由哈希表表示元素唯一,也就是说没有重复的元素。
package Set_practice;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class LinkHashSet {
public static void main(String[] args) {
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
lhs.add("pjh");
lhs.add("sjl");
lhs.add("tjs");
for (String s:lhs){
System.out.println(s);
}
System.out.println("=============");
lhs.add("tjs");
Iterator<String> it = lhs.iterator();
while (it.hasNext()){
String S = it.next();
System.out.println(S);
}
}
}
TreeSet< E > 集合
(1)元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体的排序方式取决于构造方法。
TreeSet():根据其元素的自然排序进行排序;
TreeSet(Comparator comparator):根据指定的比较器进行排序。
(2)没有带索引的方法,所以不能使用普通的 for 循环遍历;
(3)由于是 Set 集合,所以不包含重复元素的集合。
自然排序Comparable的使用
(1)使用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的;
(2)自然排序,就是让元素所属的类实现Comparable接口,重写comparableTo(T o)方法;
(3)重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写。
package Set_practice;
public class student implements Comparable<student>{
private String name;
private int age;
private String number;
private String address;
public student(){}
public student(String name, int age, String number, String address){
this.name = name;
this.age = age;
this.number = number;
this.address = address;
}
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 getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public void show(){
System.out.println("姓名:"+this.name+" ,学号:"+this.number+" ,年龄:"+this.age+" ,居住地:"+this.address);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
student student = (student) o;
if (age != student.age) return false;
if (name != null ? !name.equals(student.name) : student.name != null) return false;
if (number != null ? !number.equals(student.number) : student.number != null) return false;
return address != null ? address.equals(student.address) : student.address == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
result = 31 * result + (number != null ? number.hashCode() : 0);
result = 31 * result + (address != null ? address.hashCode() : 0);
return result;
}
@Override
public int compareTo(student o) {
//return 0; 重复 不添加元素
//return 1; 升序存储
//return -1;降序存储
//int num = this.age - o.age; 按年龄升序排列
int num = o.age - this.age;
int num2 = num==0?this.name.compareTo(o.name):num;
return num2;
}
}
package Set_practice;
import java.util.Comparator;
import java.util.TreeSet;
public class Treeset2 {
public static void main(String[] args) {
TreeSet<student> s = new TreeSet<student>();
student s1 = new student("pjh",23,"s21","cq");
student s2 = new student("tjs",22,"s24","cd");
student s3 = new student("sjl",24,"s25","cs");
student s4 = new student("qcx",25,"s33","pzh");
student s5 = new student("fjr",25,"s33","pzh");
s.add(s1);
s.add(s2);
s.add(s3);
s.add(s4);
s.add(s5);
for (student S:s){
S.show();
}
}
}
比较排序Comparator的使用方法
(1)用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的;
(2)比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法;
(3)重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件写。
package Set_practice;
import java.util.Comparator;
import java.util.TreeSet;
public class Treeset3 {
public static void main(String[] args) {
TreeSet<student> ts = new TreeSet<student>(new Comparator<student>() {
@Override
public int compare(student s1, student s2) {
//重写规则
int num = s1.getAge() - s2.getAge();
int num2 = num==0?s1.getName().compareTo(s2.getName()):num;
return num2;
}
});
student s1 = new student("pjh",23,"s21","cq");
student s2 = new student("tjs",22,"s24","cd");
student s3 = new student("sjl",24,"s25","cs");
student s4 = new student("qcx",25,"s33","pzh");
student s5 = new student("fjr",25,"s33","pzh");
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for (student S:ts){
S.show();
}
}
}