Java集合框架(Set接口)

Set接口

  • 特点:无序,无下标,元素不可重复
  • 方法:全部继承自Collection中的方法

Set实现类

HashSet

    public static void main(String[] args) {
        //创建集合
        HashSet<String> set = new HashSet<>();
        set.add("apple");
        set.add("melon");
        set.add("oriange");
        set.add("apple");
        System.out.println(set);//oriange,apple,melon
//        set.remove("apple");
//        System.out.println(set);
        //遍历:增强for
        for (String s : set) {
            System.out.println(s);
        }
        //迭代器
        Iterator<String> ite = set.iterator();
        while(ite.hasNext()){
            System.out.println(ite.next());
        }
        //判断
        System.out.println(set.contains("apple"));
        System.out.println(set.isEmpty());
    }
  • HashSet的使用:
    1. 根据hashcode计算保存的位置,如果此位置为空则直接保存,否则执行第2步
    2. 执行equals方法,如为true,则认为是重复,否则,形成链表
  • 只重写hashcode(),属性相同的对象仍可以添加到HashSet中,因为执行了第2步
  • 只重写equals(),Set 进行去重操作时,会先判断两个对象的 hashCode 是否相同,此时因为没有重写 hashCode 方法,所以会直接执行 Object 中的 hashCode 方法,而 Object 中的 hashCode 方法对比的是两个不同引用地址的对象,所以结果是 false,那么 equals 方法就不用执行了,直接返回的结果就是 false:两个对象不是相等的,于是就在 Set 集合中插入了两个相同的对象。​
  • 不同对象的 hashCode 可能相同;但 hashCode 不同的对象一定不相等

TreeSet

  • 存储结构:红黑树,红黑树是一种平衡二叉查找树的变体
  • 基于排列顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo()方法确定是否为重复元素
public class Person implements Comparable<Person> {
    //先按姓名比,再按年龄比
    @Override
    public int compareTo(Person o) {
        int n1 = name.compareTo(o.getName());
        int n2 = age-o.getAge();//返回负数,从小到大
        //int n2 = o.getAge()-age;//返回正数,从大到小
        return n1==0?n2:n1;
    }
    public static void main(String[] args) {
        TreeSet<Person> strings = new TreeSet<>();
        Person s1 = new Person("su", 16);
        Person s2 = new Person("li", 33);
        Person s3 = new Person("gu", 45);
        strings.add(s1);
        strings.add(s2);
        strings.add(s3);
        System.out.println(strings);
        //[Person{name='gu', age=45}, Person{name='li', age=33}, Person{name='su', age=16}]
    }

Comparator

  • 实现定制比较(比较器)
  • Comparator和Comparable区别:
    • Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
    • 两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。

匿名内部类

    public static void main(String[] args) {
        //创建集合,并指定比较规则
        TreeSet<Person> strings = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int n1 = o1.getAge()-o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1;
            }
        });

        Person s1 = new Person("li", 45);
        Person s2 = new Person("li", 33);
        Person s3 = new Person("su", 16);

        strings.add(s1);
        strings.add(s2);
        strings.add(s3);
        System.out.println(strings);
        //[Person{name='gu', age=45}, Person{name='li', age=33}, Person{name='su', age=16}]
    }
    public static void main(String[] args) {
        Comparator<Person> comparator = new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int n1 = o1.getAge()-o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1;
            }

            @Override
            public boolean equals(Object obj) {
                return false;
            }
        };
        TreeSet<Person> strings = new TreeSet<>(comparator);
        Person s1 = new Person("li", 45);
        Person s2 = new Person("li", 33);
        Person s3 = new Person("su", 16);
        strings.add(s1);
        strings.add(s2);
        strings.add(s3);
        System.out.println(strings);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值