浅析HashSet和TreeSet

Set

Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类。

Set集合框架结构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-666TXAgG-1636942816281)(C:\Users\HJY\AppData\Roaming\Typora\typora-user-images\image-20211115092250475.png)]

  1. set中的常用方法:

    public interface Set<E> extends Collection<E> {
    
        A:添加功能
        boolean add(E e);
        boolean addAll(Collection<? extends E> c);
    
        B:删除功能
        boolean remove(Object o);
        boolean removeAll(Collection<?> c);
        void clear();
    
        C:长度功能
        int size();
    
        D:判断功能
        boolean isEmpty();
        boolean contains(Object o);
        boolean containsAll(Collection<?> c);
        boolean retainAll(Collection<?> c); 
    
        E:获取Set集合的迭代器:
        Iterator<E> iterator();
    
        F:把集合转换成数组
        Object[] toArray();
        <T> T[] toArray(T[] a);
        
        //判断元素是否重复,为子类提高重写方法
        boolean equals(Object o);
        int hashCode();
    }
    

HashSet

HashSet底层使用了HashMap

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lM6TczIH-1636942816284)(C:\Users\HJY\AppData\Roaming\Typora\typora-user-images\image-20211115093449371.png)]

(1) HashSet实现了Set接口,所以Set的方法都可以使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SkxySJfK-1636942816285)(C:\Users\HJY\AppData\Roaming\Typora\typora-user-images\image-20211115093708718.png)]

(2) HashSet add()方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JV2uNQct-1636942816286)(C:\Users\HJY\AppData\Roaming\Typora\typora-user-images\image-20211115094309743.png)]

查看源码可以看到HashSet实现集合元素不重合本质上是使用HashMap的key—将加进来的元素都当作是map的key,value是一个固定的object,源码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1OtQsZUV-1636942816287)(C:\Users\HJY\AppData\Roaming\Typora\typora-user-images\image-20211115094443228.png)]

TreeSet

从名字上可以看出,此集合的实现和树结构有关。与HashSet集合类似,TreeSet也是基于Map来实现,具体实现TreeMap(后面讲解),其底层结构为红黑树(特殊的二叉查找树);

与HashSet不同的是,TreeSet具有排序功能,分为自然排序(123456)和自定义排序两类,默认是自然排序;在程序中,我们可以按照任意顺序将元素插入到集合中,等到遍历时TreeSet会按照一定顺序输出–倒序或者升序;

(1) 与HashSet类似,HashTree实现了Set接口故Set方法都有

TreeSet元素排序

(1)首先进行简单的对象比较,String Integer

import java.util.*;

import static java.util.Objects.hash;

public class practice {
    public static void main(String[] args) {
        TreeSet<String> treeSetString = new TreeSet<String>();
        treeSetString.add("a");
        treeSetString.add("z");
        treeSetString.add("d");
        treeSetString.add("b");
        System.out.println("字母顺序:" + treeSetString.toString());

        TreeSet<Integer> treeSetInteger = new TreeSet<Integer>();
        treeSetInteger.add(1);
        treeSetInteger.add(24);
        treeSetInteger.add(23);
        treeSetInteger.add(6);
        System.out.println(treeSetInteger.toString());
        System.out.println("数字顺序:" + treeSetString.toString());
    }
}

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hLa5ddwl-1636942816288)(C:\Users\HJY\AppData\Roaming\Typora\typora-user-images\image-20211115100803032.png)]

(2)如果是自定义对象

public class App{

    private String name;

    private Integer age;

    public App(){}

    public App(String name,Integer age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public static void main(String[] args ){
        System.out.println( "Hello World!" );
    }
}

public class TreeSetTest {
    public static void main(String[] agrs){
        customSort();
    }

     //自定义排序顺序:升序
    public static void customSort(){
        TreeSet<App> treeSet = new TreeSet<App>();

        //排序对象:
        App app1 = new App("hello",10);
        App app2 = new App("world",20);
        App app3 = new App("my",15);
        App app4 = new App("name",25);

        //添加到集合:
        treeSet.add(app1);
        treeSet.add(app2);
        treeSet.add(app3);
        treeSet.add(app4);
        System.out.println("TreeSet集合顺序为:"+treeSet);
    }
}

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoTmIYK2-1636942816288)(C:\Users\HJY\AppData\Roaming\Typora\typora-user-images\image-20211115101104328.png)]

通过查看源码发现,在TreeSet调用add方法时,会调用到底层TreeMap的put方法,在put方法中会调用到compare(key, key)方法,进行key大小的比较;

在比较的时候,会将传入的key进行类型强转,所以当我们自定义的App类进行比较的时候,自然就会抛出异常,因为App类并没有实现Comparable接口;

将app实现conparable接口:

public class App implements Comparable<App>{
    private String name;
    private Integer age;
    public App(){}
    public App(String name,Integer age){
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    //自定义比较:先比较name的长度,在比较age的大小;
    public int compareTo(App app) {
        //比较name的长度:
        int num = this.name.length() - app.name.length();
        //如果name长度一样,则比较年龄的大小:
        return num == 0 ? this.age - app.age : num;
    }
    @Override
    public String toString() {
        return "App{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

关于实现compareTo方法的说明:

结果返回大于0时,方法前面的值大于方法中的值;

结果返回等于0时,方法前面的值等于方法中的值;

结果返回小于0时,方法前面的值小于方法中的值;

本文参考:Java集合–Set(基础) - 简书 (jianshu.com)

;
}
}


关于实现compareTo方法的说明:

```undefined
结果返回大于0时,方法前面的值大于方法中的值;

结果返回等于0时,方法前面的值等于方法中的值;

结果返回小于0时,方法前面的值小于方法中的值;

本文参考:Java集合–Set(基础) - 简书 (jianshu.com)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值