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 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...
 
随机推荐
- 中国移动推出NB-IoT/eMTC/GSM多模通信模组Qualcomm调制解调器支持
			
亚洲电子消费展(CES Asia)在上海举行.期间,中国移动正式推出NB-IoT/eMTC/GSM三模通信模组A9500.该通信模组采用Qualcomm MDM9206 LTE IoT调制解调器,具有 ...
 - OSP 与 Session
			
大家都知道,OSP是不支持session的,换句话说,登录有效期是永久的.一般网站,如果你不操作一段时间以后,必须重新登录.osp不是这样的,你一旦登录后,即便服务器重启了,你依然能访问服务器并不需要 ...
 - UVaLive 4727 Jump (递推)
			
题意:约瑟夫环,求最后三个数. 析:f[i] = (f[i-1] + k) % i 这是求最后一个数时候,我们倒着推到第一个数时,只有一个数,所以当只有两个数时,就是另一数, 同理,我们可以求得第三个 ...
 - Jodd发送邮件
			
public static void main(String[] args) { Email email = Email.create().from("xxx") .to(&quo ...
 - Halcon - 数据类型
			
这里给大家分享 Halcon 的数据类型结构图,方便初学者认知 Halcon 图1 Halcon Datatype
 - PHP中GD库是做什么用的? PHP GD库介绍11111111
			
什么是gd库? gd库是php处理图形的扩展库,gd库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片. 在网站上GD库通常用来生成缩略图或者用来对图片加水印或者对网站数据 ...
 - [poj百练]2754:八皇后 回溯
			
描述 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后 ...
 - 719D(树形dp)
			
题目链接:http://codeforces.com/contest/791/problem/D 题意:给出一棵树,每两个点之间的距离为1,一步最多可以走距离 k,问要将任意两个点之间的路径都走一遍, ...
 - nginx 初了解
			
随着现代web开发的发展,restful,前后端分离,前端js框架的应用越来越普遍.很多web应用请求的接口可能根本就存在于不同的服务器,类似于微信,支付宝等等.这其中就会存在跨域的问题.简单来说,跨 ...
 - 洛谷P2647 最大收益
			
P2647 最大收益 题目描述 现在你面前有n个物品,编号分别为1,2,3,……,n.你可以在这当中任意选择任意多个物品.其中第i个物品有两个属性Wi和Ri,当你选择了第i个物品后,你就可以获得Wi的 ...