Set系列集合

无序、不重复、无索引

java 复制代码
public class test {
    public static void main(String [] args) {
    	Set<String> s=new HashSet<>();//创建set集合对象
    	s.add("张三");
    	s.add("李四");
    	s.add("王五");
    	System.out.println(s.add("王五"));
    	System.out.println(s);
    }
}

Set集合所使用的方法基本上与Collection一致。

Set实现类------HashSet

采用哈希表存储数据,组成:数组+链表+红黑树。

哈希值特点:

1)如果没有重写hashcode方法,不同对象计算出的哈希值是不同的。

java 复制代码
package test02;

public class Student {

	private String name;
	private int age;
	public Student() {
		
	}
	public Student(String name,int age) {
		this.setName(name);
		this.setAge(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 "Student{name="+name+"age="+age+"}";
	}
}
java 复制代码
public class test {
    public static void main(String [] args) {
    	Student s1=new Student("zhangsan",20);
    	Student s2=new Student("zhangsan",20);
    	//未重写方法
    	System.out.println(s1.hashCode());
    	System.out.println(s2.hashCode());
    }
}

2)如果已经重写hashcode方法,不同对象只要属性值相同,计算出哈希值相同。

java 复制代码
package test02;

import java.util.Objects;

public class Student {

	private String name;
	private int age;
	public Student() {
		
	}
	public Student(String name,int age) {
		this.setName(name);
		this.setAge(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;
	}
	@Override
	public int hashCode() {
		return Objects.hash(age, name);
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		return age == other.age && Objects.equals(name, other.name);
	}
	public String toString() {
		return "Student{name="+name+"age="+age+"}";
	}
}
java 复制代码
public class test {
    public static void main(String [] args) {
    	Student s1=new Student("zhangsan",20);
    	Student s2=new Student("zhangsan",20);
    	//已重写方法
    	System.out.println(s1.hashCode());
    	System.out.println(s2.hashCode());
    }
}

练习:利用HashSet集合去除重复元素

需求:创建一个存储学生对象的集合,存储多个学生对象。使用程序实现在控制台遍历该集合。

要求:学生对象的成员变量值相同,我们就认为是同一个对象

java 复制代码
package test02;

import java.util.Objects;

public class Student {

	private String name;
	private int age;
	public Student() {
		
	}
	public Student(String name,int age) {
		this.setName(name);
		this.setAge(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;
	}
	@Override
	public int hashCode() {
		return Objects.hash(age, name);
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		return age == other.age && Objects.equals(name, other.name);
	}
	public String toString() {
		return "Student{name="+name+",age="+age+"}";
	}
}
java 复制代码
public class test {
    public static void main(String [] args) {
    	Student s1=new Student("zhangsan",20);
    	Student s2=new Student("zhangsan",20);
    	Student s3=new Student("lisi",18);
    	Student s4=new Student("wangwu",21);
    	//去除重复元素,应用hashset集合,其集合有不重复性
    	HashSet<Student> h=new HashSet<>();
    	System.out.println(h.add(s1));
    	System.out.println(h.add(s2));
    	System.out.println(h.add(s3));
    	System.out.println(h.add(s4));
    	System.out.println(h);
    }
}

Set实现类------LinkHashSet

有序:保证存储和取出元素一致;不重复、无索引。

底层数据结构仍是哈希表,多了一个双链表。

java 复制代码
public class test {
    public static void main(String [] args) {
    	Student s1=new Student("zhangsan",20);
    	Student s2=new Student("zhangsan",20);
    	Student s3=new Student("lisi",18);
    	Student s4=new Student("wangwu",21);
        //有序
    	LinkedHashSet<Student> lh=new LinkedHashSet<>();
    	System.out.println(lh.add(s1));
    	System.out.println(lh.add(s2));
    	System.out.println(lh.add(s3));
    	System.out.println(lh.add(s4));
    	System.out.println(lh);
    }
}

Set实现类------TreeSet

不重复、无索引、可排序:按元素的默认规则(由小到大)排序。

TreeSet集合底层基于红黑树的数据结构实现排序。

TreeSet的两种比较比较方式:

1)默认排序/自然排序:javabean类实现Comparable接口指定的比较规则。

TreeSet对象排序练习题:创建TreeSet集合,并添加3个学生对象学生对象属性:姓名,年龄。

要求按照学生的年龄进行排序,同年龄按照姓名字母排列( 暂不考虑中文)同姓名,同年龄认为是同一个人。

java 复制代码
package test02;

import java.util.Objects;

public class Student implements Comparable<Student>{

	private String name;
	private int age;
	public Student() {
		
	}
	public Student(String name,int age) {
		this.setName(name);
		this.setAge(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;
	}
	@Override
	public int hashCode() {
		return Objects.hash(age, name);
	}
	public String toString() {
		return "Student{name="+name+",age="+age+"}";
	}
	@Override
	public int compareTo(Student o) {//排序规则
		return this.getAge()-o.getAge();
		//this表示当前要添加的元素
		//o表示已经在红黑树中的元素
		//返回值:
		//负数:认为添加的元素小,存左边
		//正数:认为添加的元素大,存右边
		//0:认为添加的元素已经存在,舍弃
	}
}
java 复制代码
public class test {
    public static void main(String [] args) {
    	Student s1=new Student("zhangsan",20);
    	Student s2=new Student("zhangsan",20);
    	Student s3=new Student("lisi",18);
    	Student s4=new Student("wangwu",21);
       
    	TreeSet<Student> t=new TreeSet<>();
    	System.out.println(t.add(s1));
    	System.out.println(t.add(s2));
    	System.out.println(t.add(s3));
    	System.out.println(t.add(s4));
    	System.out.println(t);
    }
}

2)比较器排序:创建TreeSet对象时,传递比较器Comparator指定规则。

默认使用第一种排序,第一种不满足使用第二种。

要求:存入四个字符串,"c" "ab" "df",' qwer',按照长度排序,如果一样长则按照首字母排序.

使用比较器排序:

java 复制代码
public class test {
    public static void main(String [] args) {
    	
    	TreeSet<String> ts=new TreeSet<>(new Comparator<String>() {
    		public int compare(String o1,String o2) {
    			int i=o1.length()-o2.length();
    			i=i==0? o1.compareTo(o2):i;
    			return i;
    		}
    	});
    	ts.add("c");
    	ts.add("ab");
    	ts.add("df");
    	ts.add("qwer");
    	System.out.println(ts);
    }
}

练习:TreeSet对象排序练习题

需求:创建5个学生对象

属性: (姓名,年龄,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

如果总分一样,按照语文成绩排

如果语文一样,按照数学成绩排

如果数学成绩一样,按照英语成绩排

如果英文成绩一-样,按照年龄排

如果年龄一样,按照姓名的字母顺序排

如果都一样,认为是同一一个学生,不存。

java 复制代码
package test02;
import java.util.Objects;
public class Student implements Comparable<Student>{
	private String name;
	private int age;
	private int math;
	private int chinese;
	private int English;
	public Student() {
		
	}
	public Student(String name,int age,int math,int chinese,int English) {
		this.setName(name);
		this.setAge(age);
		this.setMath(math);
		this.setChinese(chinese);
		this.setEnglish(English);
	}
	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 int getMath() {
		return math;
	}
	public void setMath(int math) {
		this.math = math;
	}
	public int getChinese() {
		return chinese;
	}
	public void setChinese(int chinese) {
		this.chinese = chinese;
	}
	public int getEnglish() {
		return English;
	}
	public void setEnglish(int english) {
		English = english;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", math=" + math + ", chinese=" + chinese + ", English="
				+ English + "]";
	}
	@Override
	public int compareTo(Student o) {//排序规则
		//
		int sum1=this.getChinese()+this.getEnglish()+this.getMath();
		int sum2=o.getChinese()+o.getEnglish()+o.getMath();
		int i=sum1-sum2;
		//如果总分一样,按语文成绩排
		i=i==0 ? this.getChinese()-o.getChinese():i;
		//数学成绩
		i=i==0 ? this.getMath()-o.getMath():i;
		//英语成绩
		i=i==0 ?this.getEnglish()-o.getEnglish():i;
		//如果英语成绩一样,按年龄排
		i=i==0 ? this.getAge()-o.getAge():i;
		//如果年龄一样,按姓名字母顺序排
		i=i==0 ?this.getName().compareTo(o.getName()):i;
		return i;
	}
}
java 复制代码
public class test {
    public static void main(String [] args) {
    	Student s1=new Student("zhangsan",20,88,88,89);
    	Student s2=new Student("qingliu",20,88,88,89);
    	Student s3=new Student("lisi",18,88,85,90);
    	Student s4=new Student("wangwu",21,90,91,92);
       
    	TreeSet<Student> t=new TreeSet<>();
    	System.out.println(t.add(s1));
    	System.out.println(t.add(s2));
    	System.out.println(t.add(s3));
    	System.out.println(t.add(s4));
    	System.out.println(t);
    }
}
相关推荐
诚丞成2 分钟前
计算世界之安生:C++继承的文水和智慧(上)
开发语言·c++
Smile灬凉城66614 分钟前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
lsx20240625 分钟前
SQL MID()
开发语言
Dream_Snowar28 分钟前
速通Python 第四节——函数
开发语言·python·算法
西猫雷婶30 分钟前
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
开发语言·python·opencv
鸿蒙自习室30 分钟前
鸿蒙UI开发——组件滤镜效果
开发语言·前端·javascript
星河梦瑾30 分钟前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全
黄名富34 分钟前
Redis 附加功能(二)— 自动过期、流水线与事务及Lua脚本
java·数据库·redis·lua
love静思冥想35 分钟前
JMeter 使用详解
java·jmeter
言、雲38 分钟前
从tryLock()源码来出发,解析Redisson的重试机制和看门狗机制
java·开发语言·数据库