Bootstrap

Java之Set集合详解

Set集合

Set是无序(无下标),不重复的

HashSet

添加字符串:
        // 创建一个HashSet
        HashSet<String> set = new HashSet<>(); 
        // 添加
        boolean add = set.add("d");
        boolean add2 = set.add("d");
        set.add("a");
        set.add("a");
        set.add("b");
        set.add("c");
        System.out.println(add);
        System.out.println(add2);
        System.out.println(set);
使用HashSet 主要用来 去重
去重:
        // 创建一个HashSet 添加6个人  
        HashSet<Person> set = new HashSet<>();
        set.add(new Person("dp", 17));
        set.add(new Person("dp", 17));
        set.add(new Person("ygs", 18));
        set.add(new Person("ygs", 18));
        set.add(new Person("sxm", 19));
        set.add(new Person("sxm", 19));
        Iterator<Person> iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

通过重写对象类的 equals 和 hashCode 去重:

当Set集合在进行存储的时候,hashCode值相同时,会调用equals方法进行对比是同一个对象就不存;当hashCode值不相同时 不用调用equals方法,可以直接存

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj) // 如果两个对象地址一样 返回true
                return true;
            if (obj == null)// 如果传进来的对象是空 返回false
                return false;
            if (getClass() != obj.getClass())  // 如果两个对象不是一个类创建出来的
                return false;                  // 就返回 false
            Person other = (Person) obj;            // 向下转型(准备调用特有方法)
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }

LinkedHashSet

LinkedHashSet 特点:有序 怎么存就怎么取出来
添加字符串:
        LinkedHashSet<String> set = new LinkedHashSet<>();
        set.add("l");
        set.add("w");
        set.add("w");
        set.add("a");
        set.add("n");
        set.add("g");
        System.out.println(set);

输入一个字符串,去掉其中重复字符

        Scanner scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        LinkedHashSet<Character> set = new LinkedHashSet<>();
        char[] charArray = string.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            set.add(charArray[i]);
        }
        System.out.println(set);

利用set集合 去除ArrayList集合中的重复元素(操作原ArrayList)

        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("a");
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("c");
        LinkedHashSet<String> set = new LinkedHashSet<>();
        // 将list所有元素 扔到set中去重
        set.addAll(arrayList);
        // 清空原arrayList
        arrayList.clear();
        arrayList.addAll(set);
        System.out.println(arrayList);

TreeSet

TreeSet(内部实现二叉树)
特点:无序 不重复
主要作用:排序

代码示例:
        // 创建一个TreeSet
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(1);
        treeSet.add(13);
        treeSet.add(1);
        treeSet.add(3);
        treeSet.add(2);
        for (Integer integer : treeSet) {
            System.out.println(integer);
        }

TreeSet 排序,需要实现Comparable这个接口,编写排序规则,系统就会按规则来排序

compareTo方法:
        返回0时  set中只有一个元素
        返回1时  按存进去的顺序 正序打印
        返回-1时 按存进去的顺序 倒序打印

TreeSet 按二叉树保存的:
        要保存的数比根小  放在我的左边
        要保存的数比根大  放在我的右边
        要保存的数与根一样大  不存
        打印 按从小到大输出  (升序)

使用TreeSet排序的步骤:
        1.让TreeSet集合中保存的对象 实现Comparable接口
        2.实现compareTo方法
        3.在compareTo方法中实现你要排序的规则

        // 创建TreeSet集合
        TreeSet<Worker> treeSet = new TreeSet<>();
        treeSet.add(new Worker("sxm0", 11));
        treeSet.add(new Worker("sxm01", 11));
        treeSet.add(new Worker("sxm5", 12));
        treeSet.add(new Worker("sxm4", 12));
        treeSet.add(new Worker("sxm2", 15));
        treeSet.add(new Worker("sxm3", 14));
        for (Worker worker : treeSet) {
            System.out.println(worker);
        }

        // 实现Comparable接口
        public class Worker extends Person implements Comparable<Worker>{

            public Worker() {
                super();
            }

            public Worker(String name, int age) {
                super(name, age);
            }

            // 实现接口中的唯一方法
            // 按年龄比较
            @Override
            public int compareTo(Worker o) {
                return this.getAge() - o.getAge();
            }

            // 按姓名比较
            @Override
            public int compareTo(Worker o) {
                return this.getName().compareTo(o.getName());
            }

            // 主要条件 按年龄 次要条件 姓名
            @Override
            public int compareTo(Worker o) {
                if(this.getAge() == o.getAge()) {
                    return this.getName().compareTo(o.getName());
                }
                return this.getAge() - o.getAge();
            }

            // 主要比字符串长度 然后比年龄 最后比字符串
            @Override
            public int compareTo(Worker o) {
                if (this.getName().length() == o.getName().length()) {
                    if(this.getAge() == o.getAge()) {
                        return this.getName().compareTo(o.getName());
                    }
                    return this.getAge() - o.getAge();
                }
                return this.getName().length() - o.getName().length();
            }
        }   

Comparator比较器

使用比较器来排序步骤:
        1.创建一个类 实现Comparator
        2.实现接口中的方法 并编写 比较的规则
        3.把该类的对象 传入 TreeSet集合中

比较字符串长度:
        TreeSet<String> set = new TreeSet<>(new StringLengthCompareImpl());
        set.add("asd");
        set.add("asde");
        set.add("asdef");
        set.add("a");
        set.add("asa");
        System.out.println(set);

        // 创建一个比较器类 专门来做字符串的长度比较
        class StringLengthCompareImpl implements Comparator<String>{
            // 比较规则
            // 主要比 字符串长度
            // 次要比 字符串
            @Override
            public int compare(String o1, String o2) {
                int num = o1.length() - o2.length();
                return num == 0 ? o1.compareTo(o2) : num;
            }
        }

保留重复的字符串:
        TreeSet<String> set = new TreeSet<>(new KeepStringImpl());
        set.add("asd");
        set.add("asde");
        set.add("asdef");
        set.add("a");
        set.add("asd");
        System.out.println(set);

        // 保留重复的字符串 比较器
        class KeepStringImpl implements Comparator<String> {
            @Override
            public int compare(String o1, String o2) {
                int length = o1.length() - o2.length();
                int num = length == 0 ? o1.compareTo(o2) : length;
                // 返回 1 或 -1 
                return num == 0 ? 1 : num;
            }   
        }
;