一、HashSet简介
- HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
- HashSet 允许有 null 值。
- HashSet 是无序的,即不会记录插入的顺序。
- HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
- HashSet 实现了 Set 接口。
set容器的特点是不包含重复元素,也就是说
自动去重
,算法题中经常应用的特点。
HashSet 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。
基本类型对应的包装类表如下:
基本类型 | 引用类型 |
---|---|
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
HashSet 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.HashSet; // 引入 HashSet 类
创建一个 HashSet 对象 sites,用于保存字符串元素:
HashSet<String> sites = new HashSet<String>();
输出HashSet 对象 sites的全部元素,是无序的。
System.out.println(sites);
而输出
TreeSet
对象的全部元素是有序的。
二、
HashSet VS TreeSet
1、相同点
二者都继承于Collections的Set接口,set集合的元素是
不能重复
的。都具有Set集合的基本特性。
1、不同之处
1、TreeSet 是
二叉树
实现的,Treeset中的数据是自动排好序的,不允许放入null值。2、HashSet 是
哈希表
实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。3、HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。
2、HashSet与TreeSet的常用方法
add
(E e)// 如果不存在,则添加。
clear()//清空
contains(Object o)//查询指定元素是否存在,存在返回true
isEmpty()// 判空
iterator()//返回此容器的迭代器
remove// 如果指定元素在此set中则移除
size()//返回元素数量
三、
HashSet
例题
第十届蓝桥杯大赛软件类省赛 Java 大学B 组 试题B: 不同子串 本题总分:5 分
【问题描述】
一个字符串的非空子串是指字符串中长度至少为1 的连续的一段字符组成的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共7 个。注意在计算时,只算本质不同的串的个数。请问,字符串0100110001010001 有多少个不同的非空子串?
【答案提交】这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路:因为题目要求的是不同的非空子串,所以正好可以利用
HashSet
自动去重
的特点,向里面添加字符串,最后输出HashSet的容量大小就好了。
package javaB省赛2019;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class B不同子串 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s="0100110001010001";
Set<String> sub = new HashSet<String>();
for (int i = 0; i < 16; i++) {
for (int j = 1; j <=16-i; j++) {
sub.add(s.substring(i,i+j));//字符串截取
}
}
System.out.println(sub.size());
}
}
答案:100
如果暴力+手数。。。。一共136个,重复的有:14+11+7+3+1=36。注意不要漏掉字符串长度为5的一个重复的。
package javaB省赛2019;
// 01001
// 10001
// 010001
import java.util.Scanner;
public class B不同子串暴力手数法 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s="0100110001010001";
String[] tmp=new String[200];
int n=0;
for(int i=0;i<16;i++) {
for(int j=1;j<=16-i;j++) {
tmp[n]=s.substring(i, i+j);
System.out.println(n+":"+tmp[n]);
n++;
}
}
System.out.println(n);
int cnt=0;
for(int i=0;i<n;i++) {
if(tmp[i].length()==1) {
System.out.print(tmp[i]);
cnt++;
}
}
System.out.println(" "+cnt);
cnt=0;
for(int i=0;i<n;i++) {
if(tmp[i].length()==2) {
System.out.print(tmp[i]+" ");
cnt++;
}
}
System.out.println(cnt);
cnt=0;
for(int i=1;i<n;i++) {
if(tmp[i].length()==3) {
System.out.print(tmp[i]+" ");
cnt++;
}
}
System.out.println(cnt);
cnt=0;
for(int i=1;i<n;i++) {
if(tmp[i].length()==4) {
System.out.print(tmp[i]+" ");
cnt++;
}
}
System.out.println(cnt);
for(int i=1;i<n;i++) {
if(tmp[i].length()==5)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==6)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==7)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==8)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==9)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==10)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==11)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==12)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==13)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==14)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==15)System.out.println(tmp[i]);
}
for(int i=1;i<n;i++) {
if(tmp[i].length()==16)System.out.println(tmp[i]);
}
}
}