set集合

set集合

1.Set集合概述和特点

​ 总结:

a.Set集合的特点:

​ 1.不允许存储重复的元素

​ 2.没有索引

b.Set集合的基本使用

​ 因为Set集合也是接口所以只能以多态的形式,实现其子类对象

Set<String> set = new HashSet<>();

2.哈希值【理解】

  1. 总结:

    哈希值简介:

    a.用于计算存储元素的位置,提高存储元素和取出元素的效效率的。

    如何获取哈希值:

    a.使用object类中的HashCode()方法。

    哈希值的特点

    a.同一对象的哈希值是一样的。

    b.默认情况下,不同的对象哈希值是不一样的,重写HashCode就能达到不同对象的哈希值是一样的。

    3.hashSet集合概述和特点

    ​ 总结:

    ​ HashSet集合的特点:

    ​ 1.无序(存储顺序和取出的顺序有可能是不一致的)

    ​ 2.不允许存储重复的元素

    ​ 3.没有索引(所以不能用普通for循环遍历元素)

    ​ 数据结构:

    ​ JDK8之前:哈希表(数组+链表)

    ​ JDK8之后:哈希表(数组+链表+红黑树)


4.Hashset的基本使用

HashSet<String> set = new HashSet<>();
	Set.add("abc");
	set.add("def");
	set.add("egi");
	
    for(String s:set){
        Sys.out.println(s);
    }

5.HashSet集合保证元素唯一性源码分析

  1. 首先计算该元素的哈希值(hash()),在哈希表中找有没有相同的哈希值
  2. 如果没有相同的哈希值,认定为这个元素不是一个重复的元素,添加到哈希表中
  3. 如果有相同的哈希值,必须再调用equals方法判断相同的哈希表值的内容是否是一样的。
  4. 如果内容一样:认定为这个元素就是一个重复的元素,不存储
  5. 如果内容不一样,认定这个元素不是一个重复的元素,存储
结论:

​ 1.要判断一个元素是否是唯一的,必须重写HashCode和equals方法

​ 2.java自己给的类大部分都重写了HashCode和equals方法所以在自己建类时根据要求重写HashCode和equals方法。

HashSet案例:

/** 案例需求
  		 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
  	* 要求:学生对象的成员变量值相同,我们就认为是同一个对象

*/
package HashSetDemo01;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = 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 String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @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;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

//测试类
package HashSetDemo01;

import java.util.HashSet;

public class HashSetTest {
    public static void main(String[] args) {
        Student s = new Student("小黑",22);
        Student s1 = new Student("小花",24);
        Student s2 = new Student("小白",23);
        Student s4 = new Student("小白",23);
        HashSet<Student> hash = new HashSet<>();
        hash.add(s);
        hash.add(s1);
        hash.add(s2);
        hash.add(s4);
        for (Student student : hash) {
            System.out.println(student);
        }
    }
}

6.LinkedHashSet集合概述和特点【应用】

LinkedHashSet集合的特点

​ 1.有序(存储顺序和取出顺序是一致的)

​ 2.不允许存储重复的元素

​ 3.没有索引

​ 数据结构:

​ 哈希表 = (数组+链表+链表==>数组+双向链表)

LinkedHashSet集合基本使用
  public class LinkedHashSetDemo01 {
		    public static void main(String[] args) {
		        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
		        linkedHashSet.add(new String("重地"));
		        linkedHashSet.add(new String("通话"));
		        linkedHashSet.add(new String("cde"));
		        System.out.println(linkedHashSet);
		    }
		}

7.TreeSet集合概述和特点:

总结:

​ TreeSet集合的特点:

​ 1.有序(按照一定的规则进行排序,形成一定顺序的数据结构)

​ 2.不允许存储重复的元素

​ 3.没有索引

​ TreeSet构造方法

​ 1.TreeSet():按照自然顺序排序

​ 2.Tree(Comparator comparator):按照比较器进行比较

案例:

1.自然排序Comparable的使用

* 案例需求
    存储学生对象并遍历,创建TreeSet集合使用无参构造方法
    要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
* 实现步骤
    用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
    自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

		public class TreeSetDemo02 {
		    public static void main(String[] args) {
		        //创建集合对象
		        TreeSet<Student> ts = new TreeSet<Student>();

		        //创建学生对象
		        Student s1 = new Student("xishi", 29);
		        Student s2 = new Student("wangzhaojun", 28);
		        Student s3 = new Student("diaochan", 30);
		        Student s4 = new Student("yangyuhuan", 33);

		        Student s5 = new Student("linqingxia",33);
		        Student s6 = new Student("linqingxia",33);

		        //把学生添加到集合
		        ts.add(s1);
		        ts.add(s2);
		        ts.add(s3);
		        ts.add(s4);
		        ts.add(s5);
		        ts.add(s6);

		        //遍历集合
                for (Student s : ts) {
                    System.out.println(s.getName() + "," + s.getAge());
                }
            }

        }


	 public class Student implements Comparable<Student> {
	    private String name;
	    private int age;
		@Override
	    public int compareTo(Student s) {
	//        return 0;  表示比较的两个对象相等
	//        return 1;   表示的是按照升序排序
	//        return -1;  表示的是按照降序排序
	        //按照年龄从小到大排序
	        // int num = this.age - s.age;
	        //  按照年龄从大到小排序
	        int num = s.age - this.age; // 主要条件
	        // s.name.length() - this.name.length();
	        // s.name.charAt(0) - this.name.charAt(0);
	        //年龄相同时,按照姓名的字母顺序排序

	        // 次要条件
	        int num2 = num == 0 ? this.name.compareTo(s.name) : num;

	        return num2;


	    }
     }

2.10 比较器排序Comparator的使用

/* 案例需求
	      存储学生对象并遍历,创建TreeSet集合使用带参构造方法
	      要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
	* 实现步骤
	      用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
	      比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
	   	  重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

	案例代码:*/

		public class TreeSetDemo {
		    public static void main(String[] args) {
		        //创建集合对象
		        // 先定义一个Comparator实现类 重写compare方法,在创建TreeSet的时候,将omparator实现类的对象给这个构造
		        TreeSet<Student> ts = new TreeSet<Student>(new ComparatorImpl());

		        //创建学生对象
		        Student s1 = new Student("xishi", 29);
		        Student s2 = new Student("wangzhaojun", 28);
		        Student s3 = new Student("diaochan", 30);
		        Student s4 = new Student("yangyuhuan", 33);

		        Student s5 = new Student("linqingxia",33);
		        Student s6 = new Student("linqingxia",33);

		        //把学生添加到集合
		        ts.add(s1);
		        ts.add(s2);
		        ts.add(s3);
		        ts.add(s4);
		        ts.add(s5);
		        ts.add(s6);

		        //遍历集合
		        for (Student s : ts) {
		            System.out.println(s.getName() + "," + s.getAge());
		        }
		    }
		}

		class ComparatorImpl implements Comparator<Student>{


		    public int compare(Student s1, Student s2) {
		        //this.age - s.age
		        //s1,s2  s1 - s2 按照升序进行排序  s2 - s1 : 按照降序进行排序
		        int num = s1.getAge() - s2.getAge();
		        int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
		        return num2;
		    }
		}

		public class Student {
		    private String name;
		    private int age;
		}

3.综合排序

/* 案例需求
  * 用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合
  * 要求:按照总分从高到低出现*/



	public class TreeSetDemo {
	    public static void main(String[] args) {
	        //创建TreeSet集合对象,通过比较器排序进行排序
	        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
	            @Override
	            public int compare(Student s1, Student s2) {
	//                int num = (s2.getChinese()+s2.getMath())-(s1.getChinese()+s1.getMath());
	                //主要条件 按照总成绩的降序排序
	                int num = s2.getSum() - s1.getSum();
	                //次要条件 如果总成绩相等 就按照语文成绩进行排序 按照语文的升序进行排序
	                int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
	                // 如果是总成绩一样 语文成绩也一样就按照名字进行排序 ,按照自然顺序进行排序
	                int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2;
	                return num3;
	            }
	        });

	        //创建学生对象
	        Student s1 = new Student("林青霞", 98, 100);
	        Student s2 = new Student("张曼玉", 95, 95);
	        Student s3 = new Student("王祖贤", 100, 93);
	        Student s4 = new Student("柳岩", 100, 97);
	        Student s5 = new Student("风清扬", 98, 98);

	        Student s6 = new Student("左冷禅", 97, 99);
	//        Student s7 = new Student("左冷禅", 97, 99);
	        Student s7 = new Student("赵云", 97, 99);

	        //把学生对象添加到集合
	        ts.add(s1);
	        ts.add(s2);
	        ts.add(s3);
	        ts.add(s4);
	        ts.add(s5);
	        ts.add(s6);
	        ts.add(s7);

	        //遍历集合
	        for (Student s : ts) {
	            System.out.println(s.getName() + "," + s.getChinese() + "," + s.getMath() + "," + s.getSum());
	        }
	    }
	}


	public class Student {
	    private String name;
	    private int chinese;
	    private int math;

	    public Student() {
	    }

	    public Student(String name, int chinese, int math) {
	        this.name = name;
	        this.chinese = chinese;
	        this.math = math;
	    }

	    public String getName() {
	        return name;
	    }

	    public void setName(String name) {
	        this.name = name;
	    }

	    public int getChinese() {
	        return chinese;
	    }

	    public void setChinese(int chinese) {
	        this.chinese = chinese;
	    }

	    public int getMath() {
	        return math;
	    }

	    public void setMath(int math) {
	        this.math = math;
	    }

	    public int getSum() {
	        return this.chinese + this.math;
	    }
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值