Java集合框架—Set
集合框架 Set的特点:无序,不可以重复元素。
(1)HashSet:数据结构是哈希表。线程是非同步的。
保证元素唯一性的原理:判断元素的hashCode值是否相同。
如果相同,还会继续判断元素的equals方法,是否为true。
(2)TreeSet:可以对Set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据:compareTo方法return 0。
一、HashSet相关知识
HashSet中的元素不可以重复,如果重复添加,则只会显示一个。
原理如下:
HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
HashSet是如何保证元素唯一性的呢?
答:是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashcode值不同,不会调用equals。
*******对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法**********
代码1:
package com.package2; import java.util.*; public class HashSet222
{ public static void main(String[] args)
{ HashSet hs = new HashSet(); hs.add("java01");
hs.add("java01");
hs.add("java02");
hs.add("java03");
hs.add("java03");
hs.add("java04"); Iterator it = hs.iterator(); while(it.hasNext())
{
System.out.println(it.next());
}
}
}
此demo将String类型的字符串添加进去,并且没有重复,结果如下:
java04
java02
java03
java01
由此我们可以断定,String类已经实现了hashcode()方法和equals()方法。打开,帮助文档,确实(这不是废话么^_^)
但是,如果我们要将自定义的元素add进HashSet中,则必须定义其自己的hashcode()方法和equals()方法。如下所示:
代码2:
package com.package2;
import java.util.*;
public class HashSet3
{
public static void main(String[] args)
{
HashSet hs = new HashSet(); hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a2",12));
hs.add(new Person("a4",14)); Iterator it = hs.iterator(); while(it.hasNext())
{
Person p = (Person)it.next();
System.out.println(p.getName()+"::"+p.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
} public int hashCode()
{
System.out.println(this.name+"....hashCode");
return name.hashCode()+age*37; //保证此元素的返回值尽量不一致。
} public boolean equals(Object obj)
{ if(!(obj instanceof Person))
return false; Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name); return this.name.equals(p.name) && this.age == p.age;
} public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
输出结果如下:
a1....hashCode
a2....hashCode
a3....hashCode
a2....hashCode
a2...equals..a2
a4....hashCode
a1::11
a3::13
a2::12
a4::14
由此可以看出,将元素add时,会首先调用元素的hashcode()方法,当返回值重复时,会调用其equals方法。缺少任何一种方法都构不成一个HashSet集合。
二、TreeSet相关知识
TreeSet有俩种排序方式。
TreeSet排序的第一种方式:让元素自身具备比较性。
步骤:将add进TreeSet中的元素实现Comparable接口,并且覆盖compareTo方法。这种顺序也是元素的自然顺序,或者叫做默认顺序。
TreeSet的第二种排序方式。当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性(即利用其另一种构造函数建立对象)。在集合初始化时,就有了比较方式。
步骤:利用某个指定类实现Comparator接口,并且覆盖compare()方法,则此类会成为一个具备比较方法的类。在建立TreeSet的时候,将此类对象传入其中。
则此时,添加进TreeSet中的元素可按照指定比较方法进行排序。
下边举例演示俩种排序方式。
排序方式一:代码1:
package com.package1;
import java.util.*;
public class TreeSettest {
public static void main(String[] args) {
//创建对象
TreeSet ts=new TreeSet();
//添加元素
ts.add("abcjjj");
ts.add("abb");
ts.add("daccc");
ts.add("gfg");
ts.add("geee");
ts.add("r");
//进行迭代
Iterator it=ts.iterator();
//循环取出元素
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
输出结果如下:
abb
abcjjj
daccc
geee
gfg
r
由此可见,此时元素具备可比性,即按照其自然顺序进行排序。打开帮助文档,我们可以清晰的发现String已经实现了Comparable接口,并且已经覆盖了compareTo(),“这不是废话么^_^”,如图所示:
ps……如果我们要往TreeSet里添加的元素是自己刚刚定义的,我们也可以自己定义该元素的类实现Comparator接口,并且覆盖compareTo()方法,如下所示:代码2:
package com.package1; import java.util.*; class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age; Student(String name,int age)
{
this.name = name;
this.age = age;
} public int compareTo(Object obj)
{ //return 0; if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj; //System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
/**/
} public String getName()
{
return name; }
public int getAge()
{
return age;
}
}
public class TreeSet2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(); ts.add(new Student("lisi02",22));
ts.add(new Student("lisi02",21));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi007",29));
//ts.add(new Student("lisi007",20));
//ts.add(new Student("lisi01",40)); Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
结果如下:
lisi06...18
lisi09...19
lisi007...20
lisi02...21
lisi02...22
lisi007...29
此例子将学生元素,强行按照年龄来排序,这就是我们想要的排序方式。
第二种排序如下:
还是刚刚代码1的例子,我们使用第二种排序方式,使得String类型的元素按照长度来排序。
代码3:
/*
* 使元素按照长度来排序,若长度相同,则按照自然排序。
*/
public class TreeSettest { public static void main(String[] args) {
//创建对象
TreeSet ts=new TreeSet(new MyCompare()); //添加元素
ts.add("abc");
ts.add("bcc");
ts.add("das");
ts.add("bcde");
ts.add("asdfg");
ts.add("befqfca"); //进行迭代
Iterator it=ts.iterator(); //循环取出元素
while(it.hasNext())
{
System.out.println(it.next());
} } } //定义一个类实现Comparator接口,并且覆盖compare()方法。
class MyCompare implements Comparator
{ @Override
public int compare(Object o1, Object o2) {
//进行强制类型转换
String s1=(String) o1;
String s2=(String) o2; //进行比较
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
if(s1.length()==s2.length())
{
return s1.compareTo(s2);
}
return 0;
}
}
结果如下:
abc
bcc
das
bcde
asdfg
befqfca
此种情况下,我们不方便修改源代码,而只需要修改比较方法时,我们就可以自己创建一个比较器。在建立TreeSet时,将比较器传入即可使元素按照特定比较方式输出。
总结:
Comparable(方式一)接口和Compartor(方式二)接口的比较:
两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但
是需要修改源代码。
用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把
比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其
可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
Java集合框架—Set的更多相关文章
- Java集合框架List,Map,Set等全面介绍
Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I] +--java.util.ArrayList [C] +- ...
- Java集合框架练习-计算表达式的值
最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...
- 【集合框架】Java集合框架综述
一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...
- Java 集合框架
Java集合框架大致可以分为五个部分:List列表,Set集合.Map映射.迭代器.工具类 List 接口通常表示一个列表(数组.队列.链表 栈),其中的元素 可以重复 的是:ArrayList 和L ...
- Java集合框架之map
Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...
- 22章、Java集合框架习题
1.描述Java集合框架.列出接口.便利抽象类和具体类. Java集合框架支持2种容器:(1) 集合(Collection),存储元素集合 (2)图(Map),存储键值对.
- Java集合框架实现自定义排序
Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...
- (转)Java集合框架:HashMap
来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...
- Java集合框架
集合框架体系如图所示 Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包. Map接口的常用方法 Map接口提 ...
- Java集合框架(常用类) JCF
Java集合框架(常用类) JCF 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...
随机推荐
- thymeleaf控制view的返回格式
package com.ailk.dd1.jike.web.config; import nz.net.ultraq.thymeleaf.LayoutDialect; import org.sprin ...
- [hiho1586]Minimum
题意:区间内乘积最小值,带修改.解题关键:线段树裸题,考场上以为x y必须不等,还维护了次小值,尼玛嗨尼玛嗨,划水一整场,心态爆炸. 注意坐标需要+1 #include<cstdio> # ...
- YOLO3训练widerface数据集
因为YOLO3速度精度都很棒,所以想训练一下人脸模型,废话不多,进入正题 1写所有的配置文件 1.1 YOLO3-face.cfg 个人感觉YOLO的配置文件骑士和caffe差不多 在cfg/YOLO ...
- day6 面向对象(2)
static关键字 1:如果没有static会怎样? 1:定义Person类 1:姓名.年龄.国籍,说话行为 2:多个构造,重载形式体现 2:中国人的国籍都是确定的 1:国籍可以进行显示初始化 cla ...
- ASP.NET Core会议管理平台实战_4、参数校验、操作结果封装,注册参数配置
登陆和注册之前,需要封装 前端参数的校验,ajax的封装 参数校验,创建公共的类 ,它是一个静态类 这样在调用的时候,直接一句话就可以了,这就是封装的好处 空字符串的校验 调用方式 EF的源码里面有这 ...
- 一、初识mybatis
orm框架 1.配置文件(配置别名.mapper xml文件.数据库连接.事务) 2.创建SqlSessionFactory,创建SqlSession 3.创建model,创建Mapper xml文件 ...
- 编译出arm Android环境下的C++可执行文件
要想编译出arm环境的C++可执行文件主要就是利用交叉编译器进行编译.编译过程本身都大同小异. 1.安装交叉编译器,交叉编译器的安装方法大致有下面几种: A.debian/ubuntu 系统可以直接输 ...
- Elastic-job使用及原理
一.原理 elastic-job有lite版和cloud版,最大的区别是有无调度中心,笔者采用的是lite版本,无中心化. tips: 第一台服务器上线触发主服务器选举.主服务器一旦下线,则重新触发选 ...
- pgpool-ii 安装手册 基于Centos7.3
http://www.bkjia.com/jQuery/1173582.html地址被占用pgpool启动失败 Nov 15 02:33:56 node3 pgpool: 2016-11-15 02: ...
- JavaWeb之用户数据回显