• Java Set集合


    1 Set集合

    一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。

    public interface Set<E> extends Collection<E>
    

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

    2 常用方法

    3 实现类

    3.1 HashSet[重点]

    • 基于HashCode、equals实现元素不重复
    • 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入
    • 存入的元素要重写hashCode和equals方法

    基本用法

    /**
     * HashSet的使用
     *      存储结构:哈希表(数组+链表+红黑树)
     */
    public class Set1 {
        public static void main(String[] args) {
    
            //创建集合
            Set<String> stringSet = new HashSet<>();
            //添加元素
            stringSet.add("小米");
            stringSet.add("华为");
            stringSet.add("苹果");
            stringSet.add("苹果");//只能保存一个相同的元素
            stringSet.add(null);
            stringSet.add(null);//可以存放一个null
            System.out.println(stringSet);//打印无序
            //删除
            stringSet.remove("苹果");
            System.out.println(stringSet);
    
            /**
             * 遍历
             */
            System.out.println("****增强for****");
    
            for (String s : stringSet) {
                System.out.println(s);
            }
            System.out.println("****迭代器****");
            Iterator<String> stringIterator = stringSet.iterator();
            while (stringIterator.hasNext()){
                System.out.println(stringIterator.next());
            }
    
            //判断
            boolean containsXiaoMi = stringSet.contains("小米");
            System.out.println(containsXiaoMi);
            System.out.println("集合大小:"+stringSet.size());
    
        }
    }
    

    运行结果

    [null, 苹果, 华为, 小米]
    [null, 华为, 小米]
    ****增强for****
    null
    华为
    小米
    ****迭代器****
    null
    华为
    小米
    true
    集合大小:3
    

    存放对象

    public class Person {
    
        private String name;
        private int age;
    
       
        //getter、setter、构造器、toString
    
        /**
         * 重写hashCode和equals方法
         */
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return age == person.age &&
                    Objects.equals(name, person.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
    
    }
    
    
    
    /**
     * HashSet的使用
     *      存储结构:哈希表(数组+链表+红黑树)
     *      存储过程:
     *          1、根据hashCode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步
     *          2、再执行equals方法,如果equals方法为true,则认为时重复,否则,形成链表
     */
    public class Set2 {
        public static void main(String[] args) {
            HashSet<Person> personHashSet = new HashSet<>();
            Person p1 = new Person("婉儿",18);
            Person p2 = new Person("公孙离",18);
            Person p3 = new Person("妲己",18);
            personHashSet.add(p1);
            personHashSet.add(p2);
            personHashSet.add(p3);
            personHashSet.add(null);
    
            /**
             * 因为Person重写了hashCode和equals方法,不能再重复添加了
             *
             */
            personHashSet.add(new Person("妲己",18));
            System.out.println(personHashSet);
        }
    }
    

    运行结果:

    [null, Person{name='婉儿', age=18}, Person{name='妲己', age=18}, Person{name='公孙离', age=18}]
    

    3.2 TreeSet

    • 基于排列顺序实现元素不重复
    • 实现了SortedSet接口,对集合元素自动排序
    • 元素对象的类型必须实现Comparable接口,指定排序规则
    • 通过CompareTo方法确定是否为重复元素

    基本用法

    
    /**
     * TreeSet的使用:
     *      存储结构:红黑树
     *      要求:元素必须实现Comparable接口,compareTo()方法返回值为0,认为是重复元素
     */
    public class Set3 {
        public static void main(String[] args) {
            //创建集合 String类已经实现了Comparable接口,可以直接添加
            Set<String> stringSet = new TreeSet<>();
            stringSet.add("hello");
            stringSet.add("abc");
            stringSet.add("xyz");
            stringSet.add("xyz");//重复元素不能添加
            //stringSet.add(null); //发现不能存放null
            System.out.println(stringSet);//发现集合已经排序了
    
            //Person类需要实现Comparable接口,实现compareTo方法
            Set<Person> personSet = new TreeSet<>();
            Person p1 = new Person("x婉儿",18);
            Person p2 = new Person("a公孙离",18);
            Person p3 = new Person("d妲己",18);
            Person p4 = new Person("d妲己",16);
            personSet.add(p1);
            personSet.add(p2);
            personSet.add(p3);
            personSet.add(p4);
            System.out.println(personSet);
    
            //查询某个元素是否存在
            boolean b = personSet.contains(new Person("d妲己", 16));
            System.out.println(b);
            //集合大小
            System.out.println("大小:"+personSet.size());
            //删除某个元素 comparedTo方法的返回值相同就认为元素存在,就可以删除
            System.out.println(personSet.remove(new Person("d妲己", 16)));
            //清空集合
            personSet.clear();
    
            //遍历
            //迭代器
            //增强for
    
        }
    }
    
    public class Person implements Comparable<Person>{
    
        private String name;
        private int age;
    
        //getter、setter、构造器、toString
    
        /**
         * 定义排序规则:名字,年龄
         */
        @Override
        public int compareTo(Person o) {
            int byName = this.name.compareTo(o.name);
            int byAge = this.age - o.age;
            return byName==0 ? byAge : byName;
        }
    
    }
    
    

    运行结果

    [abc, hello, xyz]
    [Person{name='a公孙离', age=18}, Person{name='d妲己', age=16}, Person{name='d妲己', age=18}, Person{name='x婉儿', age=18}]
    true
    大小:4
    true
    

    也可以通过TreeSet的构造方法传入Comparator指定比较规则,这样元素就可以不用实现Comparable接口了

    public class Set3 {
        public static void main(String[] args) {
    
            //通过TreeSet的构造方法传入Comparator指定比较规则
            
            //使用匿名内部类
            Set<Person> personSet2 = new TreeSet<>(new Comparator<Person>() {
                @Override
                public int compare(Person p1, Person p2) {
                    int byName = p1.getName().compareTo(p2.getName());
                    int byAge = p1.getAge()- p2.getAge();
                    return byName==0 ? byAge:byName;
                }
            });
                
            //使用Lambda表达式
            Set<Person> personSet = new TreeSet<>((p1,p2)->{
                int byName = p1.getName().compareTo(p2.getName());
                int byAge = p1.getAge()- p2.getAge();
                return byName==0 ? byAge:byName;
            });
    
            Person p1 = new Person("x婉儿",18);
            Person p2 = new Person("a公孙离",18);
            Person p3 = new Person("d妲己",18);
            Person p4 = new Person("d妲己",16);
            personSet.add(p1);
            personSet.add(p2);
            personSet.add(p3);
            personSet.add(p4);
            System.out.println(personSet);
    
        }
    }
    

    TreeSet练习 根据字符串长度排序

    4 HashSet和TreeSet区别

    HashSet
    不能保证元素的排列顺序,顺序有可能发生变化
    集合元素可以是null,但只能放入一个null
    HashSet底层是采用HashMap实现的
    HashSet底层是哈希表实现的

    TreeSet
    Treeset中的数据是排好序的,不允许放入null值。
    TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key。
    TreeSet的底层实现是采用二叉树(红-黑树)的数据结构

    --------------- 我每一次回头,都感觉自己不够努力,所以我不再回头。 ---------------
  • 相关阅读:
    Error #2044: 未处理的 NetStatusEvent:。 level=error, code=NetConnection.Call.BadVersion。
    Decode amf3 object using PHP
    Papervision3D Proximity Grid Example
    array容易混淆的几个有用的方法
    输出流实际上不写对象的值,而是对象吧自己本身写在流上
    OM Unit Selling Price 与 Price List Setup 不一致
    CoreApiHtml.sql 3< (INVItemCt115h.sql ) Note: 223702.1
    LOT NUMBER / PO / RECEIPT NO Relation.
    CoreApiHtml.sql 2< (INVItemCt115h.sql ) Note: 223702.1
    CoreApiHtml.sql 1< (INVItemCt115h.sql ) Note: 223702.1
  • 原文地址:https://www.cnblogs.com/zjw-blog/p/13789564.html
Copyright © 2020-2023  润新知