Collection子接口:其二 Set 组接口

- Set接口是Collection的子接口,Set没有提供额外的方法

- Set集合中不允许包含重复的元素,如果重复添加,只保留最新添加的那一个

- Set判断两个元素是否相同不是 == 判断,而是取equals()方法

Set主要实现类:

HashSet、LinkedHashSet、TreeSet

- HashSet  Set主要接口实现类、线程不安全的、可存储Null值

- LinkedHashSet  继承了HashSet、遍历内部数据,可按照添加时的顺序遍历

- TreeSet  底层存储结构是红黑树【二叉树】,按照指定属性进行排序

Set底层的说明,红康老师讲的还是不解,决定留在数据结构篇再来细谈

https://www.bilibili.com/video/BV1Kb411W75N?p=537

底层算法的哈希码

https://www.cnblogs.com/mindzone/p/12736516.html

 1 public class CollectionTest {
2 public static void main(String[] args) {
3 Set set = new HashSet();
4
5 set.add("阿伟");
6 set.add("杰哥");
7 set.add("1376");
8 set.add("先辈");
9 set.add("Van");
10 set.add("佟大为");
11 set.add("1376");
12 set.add(new Student("小明",12));
13 set.add(new Student("小明",12));
14
15 Iterator iterator = set.iterator();
16
17 while(iterator.hasNext()){
18 Object next = iterator.next();
19 System.out.println(next);
20 }
21 // 阿伟 Van 1376 佟大为 杰哥 先辈
22 // 无序性不是遍历的结果没有顺序(不是随机性) 存储的数据不是按照索引顺序排列的,根据数据的Hash值添加
23 // 不可重复性 这里添加了同一字符串1376,从哈希码可以判断是一样,set集合只会保留其中一个
24
25 // 如果是对象就不一样了,这里依然会保留两个同属性对象,底层哈希码是不一样的
26 // 再重写equals & hashCode 之后只保留一个对象了, 调用add方法时,set会调用对象的equals方法判断,为true将不会添加
27 }
28 }
29
30
31 class Student{
32 private String name;
33 private Integer age;
34
35 public String getName() {
36 return name;
37 }
38
39 public void setName(String name) {
40 this.name = name;
41 }
42
43 public Student(String name, Integer age) {
44 this.name = name;
45 this.age = age;
46 }
47
48 public Integer getAge() {
49 return age;
50 }
51
52 public void setAge(Integer age) {
53 this.age = age;
54 }
55
56 @Override
57 public String toString() {
58 return "Student{" +
59 "name='" + name + '\'' +
60 ", age=" + age +
61 '}';
62 }
63
64 @Override
65 public boolean equals(Object o) {
66 if (this == o) return true;
67 if (!(o instanceof Student)) return false;
68 Student student = (Student) o;
69 return Objects.equals(getName(), student.getName()) &&
70 Objects.equals(getAge(), student.getAge());
71 }
72
73 @Override
74 public int hashCode() {
75 return Objects.hash(getName(), getAge());
76 }
77 }

LinkedHashSet,是HashSet的子类

添加数据的同时每个数据维护了两个引用,记录前一个数据和后一个数据

对于频繁的遍历操作,LinkedHashSet效率高于HashSet

public class CollectionTest {
public static void main(String[] args) {
Set set = new LinkedHashSet(); set.add("阿伟");
set.add("杰哥");
set.add("1376");
set.add("先辈");
set.add("Van");
set.add("佟大为");
set.add("1376"); Iterator iterator = set.iterator(); while(iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}

TreeSet存储的数据只能是同一个类型的数据

自定义数据类型或者其他的基本类型封装类

TreeSet方式的判断是以Comparable接口实现的compareTo方法操作的【自然排序方式】

0 表示相同 TreeSet将会认为是重复,不再添加重复的元素

 1 public class CollectionTest {
2 public static void main(String[] args) {
3 Set set = new TreeSet();
4
5 set.add(new Person("Jimmy",17));
6 set.add(new Person("Mike",13));
7 set.add(new Person("Jim",15));
8 set.add(new Person("Jack",12));
9 set.add(new Person("Jerry",18));
10 set.add(new Person("Jack",56));
11
12 Iterator iterator = set.iterator();
13
14 while(iterator.hasNext()){
15 Object next = iterator.next();
16 System.out.println(next);
17 }
18 }
19 }
20
21
22 // 需要实现Comparable接口
23 class Person implements Comparable{
24 private String name;
25 private Integer age;
26
27 public Person(String name, Integer age) {
28 this.name = name;
29 this.age = age;
30 }
31
32 public String getName() {
33 return name;
34 }
35
36 public void setName(String name) {
37 this.name = name;
38 }
39
40 public Integer getAge() {
41 return age;
42 }
43
44 public void setAge(Integer age) {
45 this.age = age;
46 }
47
48 @Override
49 public String toString() {
50 return "Person{" +
51 "name='" + name + '\'' +
52 ", age=" + age +
53 '}';
54 }
55
56 // 重写此方法
57 @Override
58 public int compareTo(Object o) {
59 if (o instanceof Person){
60 Person p = (Person)o;
61 int compare = this.name.compareTo(p.name); // 掉用String的compareTo方法,不是本地的
62 if (compare != 0) return compare;
63 else return Integer.compare(this.age,p.age); // 如果相同,再compare第二属性
64 }else throw new RuntimeException("装入的类型不匹配!");
65 }
66 }

详细红黑树可以参考自视频里面的这篇链接,作者博客已经搬迁了啊

https://www.yycoding.xyz/post/2014/3/27/introduce-red-black-tree

除了上面的自然排序,也支持定制排序

 1 public class CollectionTest {
2 public static void main(String[] args) {
3 Comparator comparator = new Comparator() {
4 // 按照年龄从小到大排列,一样剔除
5 @Override
6 public int compare(Object o1, Object o2) {
7 if (o1 instanceof Person && o2 instanceof Person){
8 Person p1 = (Person)o1;
9 Person p2 = (Person)o2;
10 return Integer.compare(p1.getAge(),p2.getAge());
11 }else throw new RuntimeException("类型不匹配!");
12 }
13 };
14
15 // 如果定义了定制排序,创建Set集合初始化时,注入定制比较器,TreeSet就会默认使用此比较
16 Set set = new TreeSet(comparator);
17
18 set.add(new Person("Jimmy",17));
19 set.add(new Person("Mike",13));
20 set.add(new Person("Jim",15));
21 set.add(new Person("Jack",12));
22 set.add(new Person("Jerry",18));
23 set.add(new Person("Jack",56));
24
25 Iterator iterator = set.iterator();
26
27 while(iterator.hasNext()){
28 Object next = iterator.next();
29 System.out.println(next);
30 }
31 }
32 }
33
34
35 // 需要实现Comparable接口
36 class Person implements Comparable{
37 private String name;
38 private Integer age;
39
40 public Person(String name, Integer age) {
41 this.name = name;
42 this.age = age;
43 }
44
45 public String getName() {
46 return name;
47 }
48
49 public void setName(String name) {
50 this.name = name;
51 }
52
53 public Integer getAge() {
54 return age;
55 }
56
57 public void setAge(Integer age) {
58 this.age = age;
59 }
60
61 @Override
62 public String toString() {
63 return "Person{" +
64 "name='" + name + '\'' +
65 ", age=" + age +
66 '}';
67 }
68
69 // 重写此方法
70 @Override
71 public int compareTo(Object o) {
72 if (o instanceof Person){
73 Person p = (Person)o;
74 int compare = this.name.compareTo(p.name); // 掉用String的compareTo方法,不是本地的
75 if (compare != 0) return compare;
76 else return Integer.compare(this.age,p.age); // 如果相同,再compare第二属性
77 }else throw new RuntimeException("装入的类型不匹配!");
78 }
79 }

没有写定制排序才会按照equals方法排序

【Java】Collection子接口:其二 Set 组接口的更多相关文章

  1. Java基础-Collection子接口之Set接口

    Java基础-Collection子接口之Set接口 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 学习Collection接口时,记得Collection中可以存放重复元素,也可 ...

  2. Java基础-Collection子接口之List接口

    Java基础-Collection子接口之List接口 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们掌握了Collection接口的使用后,再来看看Collection接口中 ...

  3. Java学习关于集合框架的基础接口--Collection接口

     集合框架(Collection  Framework)是Java最强大的子系统之一,位于java.util 包中.集合框架是一个复杂的接口与和类层次,提供了管理对象组的最新技术.Java集合框架标准 ...

  4. java Collection接口

    Collection 1——————Set子接口:无序,不允许重复. 2——————List子接口:有序,允许重复. Set和List对比: 1.set:检索元素的效率比较低,删除和插入效率比较高,删 ...

  5. Collection子接口(List/Set/Queue/SortedSet)

    Collection基本的子接口: List:能够存放反复内容 Set:不能存放反复内容,全部反复的内容靠hashCode()和equals()两个方法区分 Queue:队列接口 SortedSet: ...

  6. Java面向对象之 接口: [修饰符] interface 接口名 {...};子接口:[修饰符] interface 接口名 extends 父接口,父接口2...{...}

    1.什么是接口? 类比抽象类,把功能或者特性类似的一类 抽象的更彻底,可以提炼出更加特殊的"抽象类"----接口 2.如何定义接口 语法:  [修饰符] interface 接口名 ...

  7. Effective Java 第三版——41.使用标记接口定义类型

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. 自顶向下理解Java集合框架(三)Map接口

    Map基本概念 数据结构中Map是一种重要的形式.Map接口定义的是查询表,或称查找表,其用于储存所谓的键/值对(key-value pair),其中key是映射表的索引. JDK结构中还存在实现Ma ...

  9. 数据结构-List接口-LinkedList类-Set接口-HashSet类-Collection总结

    一.数据结构:4种--<需补充> 1.堆栈结构:     特点:LIFO(后进先出);栈的入口/出口都在顶端位置;压栈就是存元素/弹栈就是取元素;     代表类:Stack;     其 ...

  10. Java基础知识笔记(七:接口、变量作用域和参数传递)

    一.接口 Java语言不允许一个子类拥有多个直接父类,即任何子类只能有一个直接父类.但允许一个类实现多个接口,即在定义类的接口名称列表中可以包含1个或多个接口名称,从而实现多重继承的特性.接口的定义格 ...

随机推荐

  1. 大数据平台搭建手册——hadoop

    从0开始 超详细搭建hadoop平台手册 创建三台使用centos7操作系统的虚拟机 基础环境配置 ps:不建议使用DHCP,因为ip地址会变动 配置ip 1.master [root@master ...

  2. 自用电脑+外网开放+SSL认证(纯免费)

    背景: 本文的目的主要是为了方便大家测试,不过有条件的情况下没必要学习了.主要是给那些没有服务器,公司也不给ssl认证的开发测试人员的一种方案:就像题目所说的那样. 纯免费,纯免费的话是有学习成本的, ...

  3. Linux扩展篇-shell编程(九)-shell 异常处理

    1.异常退出 ${0}:获取当前脚本的名称 $?:获取函数返回值或者上一个命令的退出状态 set -x:开启debug调试功能 按照目前个人理解,异常分为以下几种情况: 程序处理的异常退出 程序员判断 ...

  4. # android studio启动虚拟机长时间无响应,无法启动

    问题 虚拟设备长时间不响应,无法启动设备 方案 根据 android studio启动虚拟器失败 尝试删除锁文件 失败,.android 目录下不存在锁文件 电脑内存或计算配置不足 查看了模拟器需要的 ...

  5. golang 所有关键字的列表及释义归类

    golang 所有关键字的列表及释义归类,截至1.18版本. [控制结构] if  : 条件语句,基于布尔表达式的值决定是否执行特定的代码块. else. else if     : 用在 if 语句 ...

  6. 支撑阻力指标,庄家成本价是可靠的支撑位(无未来,DLL加密)

    本指标依据庄家的成本价设计的,庄家成本价是可靠的支撑位.底层逻辑:庄家是有内幕的, 庄家能在价格低位时抄底,庄家控股时,庄家不会让散户获取低价的筹码,所以当股价到达到支撑位时,会有比较大的反弹.庄家也 ...

  7. java的ConCurrentHashMap

    一般的应用的编程,用到ConCurrentHashMap的机会很少,就象大家调侃的一样:只有面试的时候才用得着. 但还是有. 网上关于这个的资料,多如牛毛,大部分是原理分析和简单例子. 原理的核心就一 ...

  8. Springcloud开发之OpenFeign调用和认证

    SpringCloud开发cloud具有巨大的灵活性. 在调用其它服务的时候有多种方式,虽然本质一样,但是细节还是有所差异. 一.概述 当a服务调用b服务的时候有多种方式进行: 1.通过openFei ...

  9. ecnuoj 5042 龟速飞行棋

    5042. 龟速飞行棋 题目链接:5042. 龟速飞行棋 赛中没过,赛后补题时由于题解有些抽象,自己写个题解. 可以发现每次转移的结果只跟后面两个点的胜负状态有关. 不妨设 \(f_{u,a,b}\) ...

  10. Vim的移动大法

    Vim的移动大法 移动光标的按键 "h" 向左移动 "j"向下移动 "k"向上移动 "l"向右移动 在单词之间移动 注: ...