JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习…

释放双眼,带上耳机,听听看~!

JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习


我们继续说一下集合框架

  • Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复

Set集合的功能和Collection是一致的

我们重点关注的是子类对象

我们来聊聊

一.HashSet

HashSet底层结构是哈希表

什么是HashSet?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1package com.lgl.hellojava;
2
3//公共的   类   类名
4public class HelloJJAVA {
5    public static void main(String[] args) {
6        Demo d1 = new Demo();
7        Demo d2 = new Demo();
8
9        sop(d1);
10        sop(d2);
11    }
12
13    // 输出
14    public static void sop(Object obj) {
15        System.out.println(obj);
16
17    }
18
19}
20
21class Demo {
22
23}
24

我们这样输出的结果就是哈希值

当然,我们是来介绍HashSet的,我们演示一下


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1package com.lgl.hellojava;
2
3import java.util.HashSet;
4import java.util.Iterator;
5
6//公共的   类   类名
7public class HelloJJAVA {
8    public static void main(String[] args) {
9        HashSet h = new HashSet();
10        h.add("hello 01");
11        h.add("hello 02");
12        h.add("hello 03");
13        h.add("hello 04");
14
15        // set取出只有一种办法,迭代器
16        Iterator iterator = h.iterator();
17        while (iterator.hasNext()) {
18            sop(iterator.next());
19        }
20
21    }
22
23    // 输出
24    public static void sop(Object obj) {
25        System.out.println(obj);
26
27    }
28
29}
30
31

是不是很类似,但是输出,你们仔细看了

输出是无序的,我们还有一个现象,就是直接输出


1
2
3
1sop(h.add("lgl"));
2sop(h.add("lgl"));
3

相同的

因为他不能重复

二.自定义存储对象

我们可以存数据,那肯定可以自定义存储数据咯?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
1package com.lgl.hellojava;
2
3import java.util.HashSet;
4import java.util.Iterator;
5
6//公共的   类   类名
7public class HelloJJAVA {
8    public static void main(String[] args) {
9        HashSet h = new HashSet();
10        h.add(new Person("lgl1", 18));
11        h.add(new Person("lgl2", 19));
12        h.add(new Person("lgl3", 20));
13        h.add(new Person("lgl4", 21));
14
15        // set取出只有一种办法,迭代器
16        Iterator iterator = h.iterator();
17        while (iterator.hasNext()) {
18            Person p = (Person) iterator.next();
19            sop(p.getName() + ":" + p.getAge());
20        }
21
22    }
23
24    // 输出
25    public static void sop(Object obj) {
26        System.out.println(obj);
27
28    }
29
30}
31
32/**
33 * 存储对象
34 *
35 * @author LGL
36 *
37 */
38class Person {
39    private String name;
40    private int age;
41
42    public Person(String name, int age) {
43        this.setName(name);
44        this.setAge(age);
45    }
46
47    public String getName() {
48        return name;
49    }
50
51    public void setName(String name) {
52        this.name = name;
53    }
54
55    public int getAge() {
56        return age;
57    }
58
59    public void setAge(int age) {
60        this.age = age;
61    }
62}
63
64

这样就可以定下来了

  • HashSet是如何保证元素的唯一性呢?

  • 是通过元素的两个方法,hasCode和equals来完成的

    • 如果元素的hasCode相同。才会去判断equals是否为true
    • 如果元素的hasCode不同。不会调用equals

这里要注意一点的就是,对于判断元素是否存在的话,以及删除的操作,依赖的方法就是元素的hasCode和equals

三.TreeSet

hashSet说完,我们再来看一下TreeSet,我们用小例子来说明


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1package com.lgl.hellojava;
2
3import java.util.Iterator;
4import java.util.TreeSet;
5
6import org.omg.PortableInterceptor.Interceptor;
7
8//公共的   类   类名
9public class HelloJJAVA {
10    public static void main(String[] args) {
11        TreeSet s = new TreeSet();
12        s.add("abc");
13        s.add("acd");
14        s.add("age");
15        s.add("abf");
16
17        Iterator iterator = s.iterator();
18
19        while (iterator.hasNext()) {
20            sop(iterator.next());
21        }
22    }
23
24    // 输出
25    public static void sop(Object obj) {
26        System.out.println(obj);
27
28    }
29}
30
31

我们仔细看他的输出

他会排序,那我们就知道TreeSet的特性了

  • 可以对Set集合中的元素进行排序

如果你用自定义对象去村粗的话,你会发现他可以存一个对象,但是不能存储多个对象,为什么?因为他会强制进行排序,如果是对象的话,他没法排序,是不行的

对了我们没有讲TreeSet的数据结构呢,他的数据结构是二叉树,这是一个比较难的概念了

四.二叉树

二叉树其实通俗一点,就是树形图数据,比如

就是比较,一直分支,很大的节约了计算方式,我们比较,大的话,开一个分支,小的话,再开一个分支,就这样一直比较!

那TreeSet保证元素唯一性的是compareTo方法return 0;

  • TreeSet排序的第一种方式,让元素自身具备比较性,元素需要实现Comparable 接口,覆盖compareTo方法,这种也称为元素的自然顺序!

五.实现Comparator方式排序

当元素不具备比较性时,或者具备的元素的比较性不是所需要的,这时就需要让集合自身具备比较性,那就是在集合一初始化时就有了比较方式.这么说有点绕啊,我们还是用代码来说明吧,原理都是二叉树


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
1package com.lgl.hellojava;
2
3import java.util.Comparator;
4import java.util.Iterator;
5import java.util.TreeSet;
6
7//公共的   类   类名
8public class HelloJJAVA {
9    public static void main(String[] args) {
10        /**
11         * 当元素自身不具备比较性或者具备的比较性不是所需要的,这时需要让容器自生具备比较性,定义一个比较器,
12         * 将比较器对象作为参数传递给TreeSet集合的构造函数
13         */
14        TreeSet s = new TreeSet(new MyCompare());
15        s.add(new Student("lgl1", 22));
16        s.add(new Student("lgl2", 26));
17        s.add(new Student("lgl3", 10));
18        s.add(new Student("lgl4", 19));
19
20        Iterator iterator = s.iterator();
21        while (iterator.hasNext()) {
22            Student student = (Student) iterator.next();
23            sop(student.getName() + ":" + student.getAge());
24        }
25
26    }
27
28    // 输出
29    public static void sop(Object obj) {
30        System.out.println(obj);
31
32    }
33}
34
35class Student {
36    private String name;
37    private int age;
38
39    public Student(String name, int age) {
40        this.name = name;
41        this.age = age;
42    }
43
44    // 比较
45    public int compareTo(Object obj) {
46        if (!(obj instanceof Student)) {
47            throw new RuntimeException("不是学生对象");
48        }
49        Student s = (Student) obj;
50        if (this.age > s.age) {
51            return 1;
52        } else if (this.age == s.age) {
53            return this.name.compareTo(s.name);
54        }
55        return -1;
56    }
57
58    public String getName() {
59        return name;
60    }
61
62    public void setName(String name) {
63        this.name = name;
64    }
65
66    public int getAge() {
67        return age;
68    }
69
70    public void setAge(int age) {
71        this.age = age;
72    }
73
74}
75
76// 定义比较器
77class MyCompare implements Comparator {
78
79    public int compare(Object o1, Object o2) {
80        Student s1 = (Student) o1;
81        Student s2 = (Student) o2;
82
83        return s1.getName().compareTo(s2.getName());
84    }
85
86}
87
88

六.TreeSet小练习

我们到这里,就用一个小练习来结束吧,毕竟在后面就需要讲泛型了,我们的需求就是按照字符串長度排序


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
1package com.lgl.hellojava;
2
3import java.util.Comparator;
4import java.util.Iterator;
5import java.util.TreeSet;
6
7//公共的   类   类名
8public class HelloJJAVA {
9    public static void main(String[] args) {
10        /**
11         * 按照字符串長度排序
12         */
13        TreeSet s = new TreeSet(new StringLengthComparator());
14        s.add("ffffffff");
15        s.add("fffff");
16        s.add("ff");
17        s.add("ffffff");
18
19        Iterator iterator = s.iterator();
20        while (iterator.hasNext()) {
21            sop(iterator.next());
22        }
23
24    }
25
26    // 输出
27    public static void sop(Object obj) {
28        System.out.println(obj);
29
30    }
31}
32
33// 定义比较性
34class StringLengthComparator implements Comparator {
35
36    @Override
37    public int compare(Object o1, Object o2) {
38
39        String s1 = (String) o1;
40        String s2 = (String) o2;
41
42        if (s1.length() > s2.length())
43            return 1;
44        if (s1.length() == s2.length())
45            return 0;
46        return -1;
47
48    }
49
50}
51
52

这样就OK了,输出的结果

这样就O了,好的,但是我们重复元素也会被干掉的,这时候我们就要处理了


1
2
3
4
5
6
7
8
9
10
11
12
13
14
1    @Override
2    public int compare(Object o1, Object o2) {
3
4        String s1 = (String) o1;
5        String s2 = (String) o2;
6
7        int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
8        if (num == 0) {
9            return s1.compareTo(s2);
10        }
11        return -num;
12
13    }
14

到这里,就基本上都搞定了,我们的博文到这里也结束了,如果有机会

可以加群讨论:555974449

给TA打赏
共{{data.count}}人
人已打赏
安全技术

详解Node.js API系列 Http模块(2) CNodejs爬虫实现

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索