Set·无序,不重复

HashSet

特点:没有重复数据,数据不按存入的顺序输出。

HashSet由Hash表结构支持。不支持set的迭代顺序,不保证顺序。
但是Hash表结构查询速度很快。

创建集合使用代码:

Set<String> s = new HashSet<>();

代码演示:常用方法和遍历输出

import java.util.*;
public class TestHashSet {public static void main(String[] args) {m010赋值And遍历();}public static void m010赋值And遍历() {System.out.println("=====赋值And遍历");Set<String> s = new HashSet<>();s.add("孙悟空");s.add("小白龙");s.add("猪八戒");s.add("沙悟净");s.add("孙悟空");System.out.println("是否为空:" + s.isEmpty());System.out.println("是否包含:" + s.contains("小白龙"));System.out.println("移除:" + s.remove("小白龙"));// (1)foreach:遍历setfor (String str : s) {System.out.println(str);}// (2)迭代器:遍历setIterator<String> it = s.iterator();while (it.hasNext()) {String str = it.next();System.out.println("Iterator : " + str);}// (3)*Java 8新增遍历方法s.forEach(elm -> System.out.println("Lambda:" + elm));}
}

Hash和Hash表

Hash

HashCode,是一个十进制整数,是对象的地址值(逻辑地址,不是物理地址)
Object类有一个方法,可以获取对象的Hash值。

public native int hashCode();

String重写了hashCode方法

    public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;}

以至于有些不同字符串的hashCode相等(字符串还是不等的,无论==还是equals):

        System.out.println("重地".hashCode());System.out.println("通话".hashCode());System.out.println("--------------");System.out.println("方面".hashCode());System.out.println("树人".hashCode());System.out.println("--------------");System.out.println("儿女".hashCode());System.out.println("农丰".hashCode());System.out.println("--------------");System.out.println("Ea".hashCode());System.out.println("FB".hashCode());

Hash表

Java8之前:Hash表使用数组+链表;
Java8之后加入了红黑树,查询速度加快。

Hash表结构的示意图如下所示:

数组里存储的是HashCode。
HashCode相同的元素加入相同链表;
如果链表长度超过8,就转为红黑树以提高查询速度。

怎么才算重复?

HashSet中,元素不重复指“equals方法比较为true,且hashCode不同”。

下列示例代码中,只有equals为true、且hashCode相同的对象未重复存入Set中。

import java.util.*;
class A_equalsT {public boolean equals(Object obj) {return true;}
}
class B_hash1 {public int hashCode() {return 1;}
}
class C_hash2_equalsT {public int hashCode() {return 2;}public boolean equals(Object obj) {return true;}
}
public class TestSet怎么才算重复 {public static void main(String[] args) {Set<Object> _set = new HashSet<Object>();_set.add(new A_equalsT());_set.add(new A_equalsT());_set.add(new B_hash1());_set.add(new B_hash1());_set.add(new C_hash2_equalsT());_set.add(new C_hash2_equalsT());for (Object object : _set) {System.out.println(object);}}
}

运行结果:(C_hash2_equalsT只存入一份,说明被看作重复对象)

B_hash1@1
B_hash1@1
C_hash2_equalsT@2
A_equalsT@15db9742
A_equalsT@6d06d69c

HashSet存储自定义元素时,需要重写hashCode和equals方法,才能保证集合中对象的唯一性。

练习:

创建Student类,至少需要包含id、name。创建多个Student对象加入HashSet,如果学号(id)相同则不重复加入。

TreeSet

TreeSet支持两种排序方式,自然排序和定制排序。默认为自然排序,和HashSet的输出顺序不一样。

TreeSet使用红黑树存储元素(示例和下一小节一起)。

LinkedHashSet

Set也可以有序,这个LinkedHashSet就能按照输入顺序输出结果。

LinkedHashSet也是根据元素的hashCode值决定元素的存储位置,但是加了一条链表记录元素的存储顺序,这使得元素有序。

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
public class TestTree{public static void main(String[] args) {m020各种Set();}private static void m020各种Set() {System.out.println("|-HashSet:");Set<String> _set;_set = new HashSet<String>();_set.add("B");_set.add("A");_set.add("1");_set.add("2");_set.add(null);printSet(_set);System.out.println("|-TreeSet不接受空值:");_set = new TreeSet<String>();_set.add("B");_set.add("A");_set.add("1");_set.add("2");// _set.add(null);printSet(_set);System.out.println("|-LinkedHashSet:有序");_set = new LinkedHashSet<String>();_set.add("B");_set.add("A");_set.add("1");_set.add("2");_set.add(null);printSet(_set);}private static void printSet(Set<String> _set) {for (String str : _set) {System.out.print(str + " ");}System.out.println();}
}

|-HashSet:
null A 1 B 2
|-TreeSet不接受空值:
1 2 A B
|-LinkedHashSet:有序
B A 1 2 null

Set的性能

HashSet综合效率最高,LinkedHashSet因为有链表,遍历时会更快一些。TreeSet因为要维护红黑树,效率较低。

转载于:https://www.cnblogs.com/tigerlion/p/11179209.html

Java基础教程——Set相关推荐

  1. Java基础教程:反射基础

    Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...

  2. Java基础教程:多线程基础(3)——阻塞队列

    Java基础教程:多线程基础(3)--阻塞队列 快速开始 引入问题 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据. 模 ...

  3. Java基础教程:面向对象编程[2]

    Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...

  4. Java基础教程(12)--深入理解类

    一.方法的返回值   当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...

  5. Java基础教程:Lambda表达式

    Java基础教程:Lambda表达式 引入Lambda Java 是一流的面向对象语言,除了部分简单数据类型,Java 中的一切都是对象,即使数组也是一种对象,每个类创建的实例也是对象.在 Java ...

  6. Java基础教程:注解

    Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...

  7. Java基础教程-刘刚-专题视频课程

    Java基础教程-2704人已学习 课程介绍         Java基础教程是一套入门Java开发语言的课程,它是由浅入深的介绍Java基础内容,包括Java介绍.基本类型及运算符.控制执行流程.字 ...

  8. java基础教程(一)

    Java 开发环境配置 在进行Java开发之前,需要先安装Java开发工具包(JDK)和集成开发环境(IDE).以下是Java开发环境的配置和搭建步骤: 下载JDK:访问Oracle官方网站,选择适合 ...

  9. java基础教程之实现一键分享朋友圈

     java最新技术,实现一键分享朋友圈,下面给大家演示一下 作为十余年java老司机,根据多年经验,自己录制的学习视频,我往对你们有所帮助, 有技术问题或者面试方面交流的可以加我微信renlliang ...

  10. Java基础教程-10-多线程

    Java基础教程-10-多线程 1. 多线程 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计? 要解决上述问题,咱们得使用多进程或 ...

最新文章

  1. 渐变显示渐变消失的BackgroundView
  2. python实现cc攻击_运维纪录:遭遇CC攻击,防御与查水表
  3. php算出明天的日期,PHP获取昨天、今天及明天日期的方法
  4. 【转】流言终结者:Windows系统与Linux系统之间的8个流言
  5. 从C语言的角度重构数据结构系列(九)-数据结构哈希表分糖果
  6. 专栏 | 基于 Jupyter 的特征工程手册:特征选择(二)
  7. eclipse导入Java文件后出现中文乱码
  8. Scala声明变量、常用类型、条件表达式、块表达式、循环
  9. 二叉树的基本理论知识
  10. PlateSpin 完全复制由于LVM没有可用空闲空间导致失败
  11. Base PyQt4, Simple Web APP Framwork
  12. java类作用域标识符_java入门 (二) 标识符、数据类型、类型转换、变量、常量、作用域...
  13. 【Elasticsearch】 Elasticsearch Suggester 自动纠错 详解
  14. SQL Server中的数据层应用程序简介
  15. 【C/C++】BOOST 线程完全攻略 - 基础篇
  16. WP 手机Lumia 820 锁屏密码的POJI研究
  17. iPhone 快捷指令 文本朗读
  18. 关于BFS和dijkstra(2019.04.20)
  19. 软件及系统开发项目可行性分析报告-样例
  20. DATEDIF函数:

热门文章

  1. Java注解--Java深度历险(转)
  2. TiDB 源码阅读系列文章(十六)INSERT 语句详解
  3. Redis大乱探------哨兵(二)
  4. OD逆向调试程序的笔记
  5. 打通两台机器的ssh功能
  6. postfix本机测试本机时,telnet连接出错
  7. 1月第4周中美五大顶级域名总量涨幅相近 均有5.4万个
  8. TortoiseHg使用(hg mercurial repository management)
  9. Failed to install UTRUST.apk on device 'ZTE_SP920': Too many open files
  10. AndroidStudio Refreshing Gradle Project编译更新Gradle卡住问题