HashSet , LinkedHashSet与TreeSet

HashSet
  • 此类实现Set接口,由哈希表(实际为HashMap实例)支持。 对集合的迭代次序不作任何保证; 特别是,它不能保证订单在一段时间内保持不变。 这个类允许null元素。

    这个类提供了基本操作(add,remove,containssize)固定的时间性能,假定哈希函数将分散的桶中正确的元素。 迭代此集合需要与HashSet实例的大小(元素数量)和后台HashMap实例(桶数)的“容量”的总和成比例的时间。 因此,如果迭代性能很重要,不要将初始容量设置得太高(或负载因子太低)是非常重要的。

    HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。


HashSet集合特点

1.底层数据结构是哈希表
2.对集合的迭代顺序不做任何保证,也就是说不保证储存和取出的元素顺序一致
3.没有带索引的方法,所以不能使用普通for循环遍历
4.由于是Set集合,所以是不包含重复元素的集合
package com.ye.mySet.itheima03;

import java.util.HashSet;


public class HashSetDemo1 {
    public static void main(String[] args) {
        HashSet<String> hs = new HashSet<>();

        hs.add("双笙");
        hs.add("叶子");
        hs.add("元汐");

        hs.add("双笙");

        for (String h : hs) {
            System.out.println(h);
        }
    }
}

HashSet实例

需求:
创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
要求:学生对象的成员变量吃相同,我们就认为是同一个对象
思路:
1.定义学生类
2.创建HashSet集合对象
3.创建学生对象
4.把学生添加到集合
5.遍历集合(增强for循环)
6.在学生类中重写两个方法
hashCode()和equals()
自动生成即可


HashSet实例方法
package com.ye.mySet.itheima03;

import java.util.HashSet;

public class HashSetDemo2 {

    public static void main(String[] args) {
        //创建一个HashSet集合对象
        HashSet<Student> hs = new  HashSet<Student>();

        //创建学生对象
        Student s1 = new Student("双笙",21);
        Student s2 = new Student("叶子",20);
        Student s3 = new Student("小曾",19);

        Student s4 = new Student("双笙",21);

        //把学生添加到集合
        hs.add(s1);
        hs.add(s2);
        hs.add(s3);

        hs.add(s4);

        //遍历集合(增强for循环)
        for (Student h : hs) {
            System.out.println(h.getName()+","+h.getAge());
        }

    }

}

学生类

package com.ye.mySet.itheima03;

import java.util.Objects;

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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

 

 

LinkedHashSet
  • 哈希表和链表实现了Set接口,具有可预测的迭代次序。 这种实现不同于HashSet,它维持于所有条目的运行双向链表。 该链表定义了迭代排序,它是将元素插入集合(插入顺序的顺序 。 请注意,如果一个元件被重新插入到组插入顺序不受影响 。 (元件e重新插入一组s如果当s.contains(e)将返回true之前立即调用s.add(e)被调用。)

    此实现可以让客户从提供的指定,通常杂乱无章的排序HashSet ,而不会导致与其相关的成本增加TreeSet 。 它可以用于生成与原始文件具有相同顺序的集合的副本,而不管原始集的实现:

      void foo(Set s) {
             Set copy = new LinkedHashSet(s);
             ...
         } 
LinkedHashSet集合特点
1.哈希表和链表实现Set接口,具有可预测的迭代次序
2.由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
3.由哈希表保证元素唯一,也就是说没有重复的元素
package com.ye.mySet.itheima04;

import java.util.LinkedHashSet;

public class LinkedHashSetDemo01 {
    public static void main(String[] args) {
        //创建集合对象
        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();

        //添加元素
        linkedHashSet.add("双笙");
        linkedHashSet.add("叶子");
        linkedHashSet.add("元汐");

        linkedHashSet.add("双笙");

        for (String s : linkedHashSet) {
            System.out.println(s);
        }

    }
}

 

 

TreeSet

 

TreeSet是一个有序的集合,它的作用是提供有序的Set集合。它继承了AbstractSet抽象类,实现了NavigableSet,Cloneable,Serializable接口。

TreeSet是基于TreeMap实现的,TreeSet的元素支持2种排序方式:自然排序或者根据提供的Comparator进行排序。

 

(1)TreeSet继承于AbstractSet,并且实现了NavigableSet接口。
(2)TreeSet是一个包含有序的且没有重复元素的集合,通过TreeMap实现。TreeSet中含有一个"NavigableMap类型的成员变量"m,而m实际上是"TreeMap的实例"。

 

 

TreeSet集合特点
1.元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方法取决于构造方法
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator):根据指定的比较器进行排序
2.没有带索引的方法,所以不能使用普通for循环遍历
3.由于是Set集合,所以不包括重复元素的集合
package com.ye.mySet.itheima05;

import java.util.TreeSet;

public class TreeSetDemo01 {
    public static void main(String[] args) {
        //创建集合对象  应该用int类型的包装类型
        TreeSet<Integer> ts = new TreeSet<Integer>();

        //添加元素
        ts.add(10);
        ts.add(50);
        ts.add(33);
        ts.add(22);
        ts.add(88);

        //遍历集合对象
        for (Integer t : ts) {
            System.out.println(t);
        }
    }
}

 

 

TreeSet使用Comparable方法实例

存储学生对象并遍历,创建集合使用无参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
package com.ye.mySet.itheima05;

import java.util.TreeSet;

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

        //创建学生对象
        Student s1 = new Student("shuangsheng",20);
        Student s2 = new Student("yezi",25);
        Student s3 = new Student("zengsiyu",18);
        Student s4 = new Student("xiaojiu",2);

        Student s5 = new Student("wangyuhan",18);
        Student s6 = new Student("wangyuhan",18);

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

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

学生类

package com.ye.mySet.itheima05;

public class Student implements Comparable<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 int compareTo(Student s) {
//        return 1;
        int num = this.age - s.age;
        //return num;

        //年龄相同时,按照姓名的字母顺序排序
        int num2 = num == 0?this.name.compareTo(s.name):num;
        return num2;
    }
}

 

TreeSet使用Comparator方法实例

存储学生对象并遍历,创建TreeSet集合使用带参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
package com.ye.mySet.itheima06;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo {

    public static void main(String[] args) {
        //创建集合对象
        TreeSet<Student> st = 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("shuangsheng",20);
        Student s2 = new Student("yezi",25);
        Student s3 = new Student("zengsiyu",18);
        Student s4 = new Student("xiaojiu",2);

        Student s5 = new Student("wangyuhan",18);
        Student s6 = new Student("wangyuhan",18);

        st.add(s1);
        st.add(s2);
        st.add(s3);
        st.add(s4);
        st.add(s5);
        st.add(s6);

        for (Student s : st) {
            System.out.println(s.getName()+"\t"+s.getAge());
        }

    }

}

学生类

package com.ye.mySet.itheima06;

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;
    }

}

 

posted on 2022-07-07 11:34  叶子1111  阅读(49)  评论(0编辑  收藏  举报

导航