Java小记——Set集合

目录

Set集合

HashSet

LinkedHashSet

TreeSet

自然排序:使用的是空参构造,那就是自然排序,自然排序对元素有要求

比较器排序


Set集合

不允许元素重复。

HashSet

1. 他的底层数据结构是哈希表,元素无序(存取顺序不一致),且唯一(没有重复元素)

2. 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对

的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。

3. HashSet 集合判断两个元素相等的标准:

要保证元素的唯一性,是靠元素重写hashCode()和equals()方法来保证的,如果元素不重

hashCode()和equals()方法则无法保证元素的唯一性。

目的是为了减少

        HashSet<Integer> set = new HashSet<>();
        set.add(20);
        set.add(20);
        set.add(1);
        set.add(600);
        set.add(80);
        set.add(80);
        set.add(14);
        set.add(5);

        System.out.println(set); //[80, 1, 20, 5, 600, 14]

哈希表的结构:JDK1.7 数组+链表  JDK1.8 之后优化了  数组+链表+红黑树。

        HashSet<String> set = new HashSet<>();
        set.add("张学友");
        set.add("刘德华");
        set.add("周润发");
        set.add("郭富城");
        set.add("周星驰");
        set.add("周润发");
        set.add("郭富城");
        set.add("周星驰");

        for (String s : set) {
            System.out.println(s); 
//周星驰
  郭富城
  张学友
  周润发
  刘德华

        }

       HashSet<Student> hashSet = new HashSet<>();
        hashSet.add(new Student("张三", 23));
        hashSet.add(new Student("张三", 23));
        hashSet.add(new Student("李四", 24));
        hashSet.add(new Student("王五", 25));
        hashSet.add(new Student("赵六", 26));
        hashSet.add(new Student("张三", 23));


        for (Student student : hashSet) {
            System.out.println(student);
        }

        //Student{name='李四',age=24}
          Student{name='赵六',age=26}
          Student{name='张三',age=23}
          Student{name='张三',age=23}
          Student{name='王五',age=25}
          Student{name='张三',age=23}

HashSet集合底层使用的是HashMap来存储的。

public class MyTest2 {
    public static void main(String[] args) {
        Student s1 = new Student("张三", 23);
        int hash = hash(s1);
        System.out.println(hash);
        int index = (16 - 1) & hash;
        System.out.println(index);
        //(p = tab[i = (n - 1) & hash]

    }

    public static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
}

LinkedHashSet

LinkedHashSet 底层数据结构是链表和哈希表,元素有序且唯一。链表保证了元素有序,哈希表保

证了元素唯一。

        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("aaa");
        linkedHashSet.add("aaa");
        linkedHashSet.add("bbb");
        linkedHashSet.add("ccc");
        linkedHashSet.add("ddd");
        linkedHashSet.add("ddd");

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

        //aaa
          bbb
          ccc
          ddd

ArrayList除去重复元素

        ArrayList<Integer> list = new ArrayList<>();
        list.add(100);
        list.add(100);
        list.add(100);
        list.add(100);
        list.add(200);
        list.add(300);
        list.add(200);

        LinkedHashSet<Integer> set = new LinkedHashSet<>(list);
        System.out.println(set);

TreeSet

层数据结构是二叉树,元素唯一,可以对元素进行排序。

排序,自然排序,比较器排序。
 

//存储下列元素:  20 , 18 , 23 , 22 , 17 , 24, 19 , 18 , 24

        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(20);
        treeSet.add(18);
        treeSet.add(23);
        treeSet.add(22);
        treeSet.add(17);
        treeSet.add(24);
        treeSet.add(19);
        treeSet.add(18);
        treeSet.add(24);

        System.out.println(treeSet);

自然排序:使用的是空参构造,那就是自然排序,自然排序对元素有要求

要求元素实现  Comparable 比较接口 重写 compareTo方法,根据此方法返回值的正负0 来决定元

素在树形结构中放置的左右顺序

        TreeSet<Student> treeSet = new TreeSet<>();
        treeSet.add(new Student("张三dddd", 23));
        treeSet.add(new Student("王菲as", 23));
        treeSet.add(new Student("刘德华", 21));
        treeSet.add(new Student("欧阳震华adfasdf", 28));
        treeSet.add(new Student("刘亦菲ddd", 13));
        treeSet.add(new Student("张曼玉ddd", 20));
        treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
        treeSet.add(new Student("张三asdfas", 23));

        for (Student student : treeSet) {
            System.out.println(student.getAge() + "===" + student.getName());

        }
    }


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 String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student student) {
        //按照年龄进行排序
        //System.out.println(this + "=====" + student);
        int num = this.age - student.age;
        //当年龄相同时,我们比较姓名是否相同。
        int num2 = num == 0 ? this.name.compareTo(student.name) : num;

        return num2; //正 负  0
    }
}

若姓名长度不一致

        TreeSet<Student> treeSet = new TreeSet<>();
        treeSet.add(new Student("张三dddd", 23));
        treeSet.add(new Student("王菲", 23));
        treeSet.add(new Student("王菲", 23));
        treeSet.add(new Student("王菲", 25));
        treeSet.add(new Student("王静", 23));
        treeSet.add(new Student("刘德华", 21));
        treeSet.add(new Student("欧阳震华adfasdf", 28));
        treeSet.add(new Student("刘亦菲ddd", 13));
        treeSet.add(new Student("张曼玉ddd", 20));
        treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
        treeSet.add(new Student("张三asdfas", 23));

        for (Student student : treeSet) {
            System.out.println(student.getAge() + "===" + student.getName());

        }





        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 String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student student) {
        int num = this.name.length() - student.name.length();
        //姓名长度一样,并不能说明是同一个对象,还得判断姓名的内容是否一样
        int num2 = num == 0 ? this.name.compareTo(student.name) : num;
        //姓名长度一样,内容一样,也不能说明是同一个对象,还得比较年龄是否一样。
        int num3 = num2 == 0 ? this.age - student.age : num2;
        return num3; // 正负0
    }
}

// Ctrl+i 重写方法

比较器排序

采用有参构造

public class MyComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        //System.out.println(s1 + "====" + s2);
        int num = s1.getAge() - s2.getAge();

        int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;

        return num2; //根据此方法返回的正负0决定元素排列的左右顺序
    }



public class MyTest {
    public static void main(String[] args) {
        //自然排序:采用空参构造,那就是自然排序。
        //比较器排序:采用有参构造

      /*  TreeSet(Comparator < ? super E > comparator)
        构造一个新的空 TreeSet,它根据指定比较器进行排序。*/

        MyComparator myComparator = new MyComparator();
        TreeSet<Student> treeSet = new TreeSet<>(myComparator);
        treeSet.add(new Student("张三dddd", 23));
        treeSet.add(new Student("王菲", 23));
        treeSet.add(new Student("王菲", 23));
        treeSet.add(new Student("王菲", 25));
        treeSet.add(new Student("王静", 23));
        treeSet.add(new Student("刘德华", 21));
        treeSet.add(new Student("欧阳震华adfasdf", 28));
        treeSet.add(new Student("刘亦菲ddd", 13));
        treeSet.add(new Student("张曼玉ddd", 20));
        treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
        treeSet.add(new Student("张三asdfas", 23));

        for (Student student : treeSet) {
            System.out.println(student.getAge() + "===" + student.getName());

        }


    }
}
public class MyTest2 {
    public static void main(String[] args) {
        //直接使用匿名内部类传入这个比较器的对象。
        TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num = s1.getName().length() - s2.getName().length();
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
                return num3;
            }
        });
        treeSet.add(new Student("张三dddd", 23));
        treeSet.add(new Student("王菲", 23));
        treeSet.add(new Student("王菲", 23));
        treeSet.add(new Student("王菲", 25));
        treeSet.add(new Student("王静", 23));
        treeSet.add(new Student("刘德华", 21));
        treeSet.add(new Student("欧阳震华adfasdf", 28));
        treeSet.add(new Student("刘亦菲ddd", 13));
        treeSet.add(new Student("张曼玉ddd", 20));
        treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
        treeSet.add(new Student("张三asdfas", 23));

        for (Student student : treeSet) {
            System.out.println(student.getAge() + "===" + student.getName());

        }
    }
}
public class MyTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(20);
        list.add(1);
        list.add(2);
        list.add(5);
        list.add(3);
        list.add(4);

        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer x, Integer y) {
                return x - y;
            }
        });

        System.out.println(list);


        System.out.println("==============================");
        int[] arr = {2, 9, 3, 7, 8, 4, 1};

        Arrays.sort(arr);

        System.out.println(Arrays.toString(arr));


        //从大到小排序
        Integer[] arr2 = {2, 9, 3, 7, 8, 4, 1};
        Arrays.sort(arr2, new Comparator<Integer>() {

            @Override
            public int compare(Integer a, Integer b) {
                return b - a;
            }
        });

        System.out.println(Arrays.toString(arr2));
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jmh-Ethereal

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值