JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习
JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习
我们继续说一下集合框架
- Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复
Set集合的功能和Collection是一致的
我们重点关注的是子类对象
我们来聊聊
一.HashSet
HashSet底层结构是哈希表
什么是HashSet?
package com.lgl.hellojava;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
sop(d1);
sop(d2);
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
class Demo {
}
我们这样输出的结果就是哈希值
当然,我们是来介绍HashSet的,我们演示一下
package com.lgl.hellojava;
import java.util.HashSet;
import java.util.Iterator;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
HashSet h = new HashSet();
h.add("hello 01");
h.add("hello 02");
h.add("hello 03");
h.add("hello 04");
// set取出只有一种办法,迭代器
Iterator iterator = h.iterator();
while (iterator.hasNext()) {
sop(iterator.next());
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
是不是很类似,但是输出,你们仔细看了
输出是无序的,我们还有一个现象,就是直接输出
sop(h.add("lgl"));
sop(h.add("lgl"));
相同的
因为他不能重复
二.自定义存储对象
我们可以存数据,那肯定可以自定义存储数据咯?
package com.lgl.hellojava;
import java.util.HashSet;
import java.util.Iterator;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
HashSet h = new HashSet();
h.add(new Person("lgl1", 18));
h.add(new Person("lgl2", 19));
h.add(new Person("lgl3", 20));
h.add(new Person("lgl4", 21));
// set取出只有一种办法,迭代器
Iterator iterator = h.iterator();
while (iterator.hasNext()) {
Person p = (Person) iterator.next();
sop(p.getName() + ":" + p.getAge());
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
/**
* 存储对象
*
* @author LGL
*
*/
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.setName(name);
this.setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
这样就可以定下来了
- HashSet是如何保证元素的唯一性呢?
- 是通过元素的两个方法,hasCode和equals来完成的
- 如果元素的hasCode相同。才会去判断equals是否为true
- 如果元素的hasCode不同。不会调用equals
这里要注意一点的就是,对于判断元素是否存在的话,以及删除的操作,依赖的方法就是元素的hasCode和equals
三.TreeSet
hashSet说完,我们再来看一下TreeSet,我们用小例子来说明
package com.lgl.hellojava;
import java.util.Iterator;
import java.util.TreeSet;
import org.omg.PortableInterceptor.Interceptor;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
TreeSet s = new TreeSet();
s.add("abc");
s.add("acd");
s.add("age");
s.add("abf");
Iterator iterator = s.iterator();
while (iterator.hasNext()) {
sop(iterator.next());
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
我们仔细看他的输出
他会排序,那我们就知道TreeSet的特性了
- 可以对Set集合中的元素进行排序
如果你用自定义对象去村粗的话,你会发现他可以存一个对象,但是不能存储多个对象,为什么?因为他会强制进行排序,如果是对象的话,他没法排序,是不行的
对了我们没有讲TreeSet的数据结构呢,他的数据结构是二叉树,这是一个比较难的概念了
四.二叉树
二叉树其实通俗一点,就是树形图数据,比如
就是比较,一直分支,很大的节约了计算方式,我们比较,大的话,开一个分支,小的话,再开一个分支,就这样一直比较!
那TreeSet保证元素唯一性的是compareTo方法return 0;
- TreeSet排序的第一种方式,让元素自身具备比较性,元素需要实现Comparable 接口,覆盖compareTo方法,这种也称为元素的自然顺序!
五.实现Comparator方式排序
当元素不具备比较性时,或者具备的元素的比较性不是所需要的,这时就需要让集合自身具备比较性,那就是在集合一初始化时就有了比较方式.这么说有点绕啊,我们还是用代码来说明吧,原理都是二叉树
package com.lgl.hellojava;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
/**
* 当元素自身不具备比较性或者具备的比较性不是所需要的,这时需要让容器自生具备比较性,定义一个比较器,
* 将比较器对象作为参数传递给TreeSet集合的构造函数
*/
TreeSet s = new TreeSet(new MyCompare());
s.add(new Student("lgl1", 22));
s.add(new Student("lgl2", 26));
s.add(new Student("lgl3", 10));
s.add(new Student("lgl4", 19));
Iterator iterator = s.iterator();
while (iterator.hasNext()) {
Student student = (Student) iterator.next();
sop(student.getName() + ":" + student.getAge());
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 比较
public int compareTo(Object obj) {
if (!(obj instanceof Student)) {
throw new RuntimeException("不是学生对象");
}
Student s = (Student) obj;
if (this.age > s.age) {
return 1;
} else if (this.age == s.age) {
return this.name.compareTo(s.name);
}
return -1;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// 定义比较器
class MyCompare implements Comparator {
public int compare(Object o1, Object o2) {
Student s1 = (Student) o1;
Student s2 = (Student) o2;
return s1.getName().compareTo(s2.getName());
}
}
六.TreeSet小练习
我们到这里,就用一个小练习来结束吧,毕竟在后面就需要讲泛型了,我们的需求就是按照字符串長度排序
package com.lgl.hellojava;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
/**
* 按照字符串長度排序
*/
TreeSet s = new TreeSet(new StringLengthComparator());
s.add("ffffffff");
s.add("fffff");
s.add("ff");
s.add("ffffff");
Iterator iterator = s.iterator();
while (iterator.hasNext()) {
sop(iterator.next());
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
// 定义比较性
class StringLengthComparator 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 0;
return -1;
}
}
这样就OK了,输出的结果
这样就O了,好的,但是我们重复元素也会被干掉的,这时候我们就要处理了
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if (num == 0) {
return s1.compareTo(s2);
}
return -num;
}
到这里,就基本上都搞定了,我们的博文到这里也结束了,如果有机会
可以加群讨论:555974449
JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习的更多相关文章
- JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口
JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一. ...
- JAVA之旅(十八)——基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用
JAVA之旅(十八)--基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用 JAVA把完事万物都定义为对象,而我们想使用数据 ...
- JAVA之旅(十)——异常的概述,Try-Catch,异常声明Throws,多异常处理,自定义异常,Throw和Throws的区别
JAVA之旅(十)--异常的概述,Try-Catch,异常声明Throws,多异常处理,自定义异常,Throw和Throws的区别 不知不觉,JAVA之旅这个系列已经更新到第十篇了,感觉如梦如幻,时间 ...
- JAVA之旅(十九)——ListIterator列表迭代器,List的三个子类对象,Vector的枚举,LinkedList,ArrayList和LinkedList的小练习
JAVA之旅(十九)--ListIterator列表迭代器,List的三个子类对象,Vector的枚举,LinkedList,ArrayList和LinkedList的小练习 关于数据结构,所讲的知识 ...
- JAVA之旅(十六)——String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较
JAVA之旅(十六)--String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较 过节耽误了几天,我们继续JAVA之旅 一.String概述 String时 ...
- JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止
JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
- 使用Typescript重构axios(二十八)——自定义序列化请求参数
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- Java IO(二十) PrintStream 和 DataOutputStream 异同
Java IO(二十) PrintStream 和 DataOutputStream 异同 一.相同点 都是继承与FileOutputStream,用于包装其它输出流. 二.不同点 (一).Print ...
随机推荐
- linux 删除命令
rm * 文件名rm -r */ 文件夹rm -rf * 文件夹或文件名 -r 代表文件夹之下的都删除掉 -f 代表暴力删除,无需确认直接删完
- joomla网站内插入doc文档
最近我的网站又出了问题,之前用joomla做的网站,由于要放doc文档,后来想尽办法终于用iframe的办法,先把文档传到scribd网,然后把文档嵌到网站里去,但是狗血的,去年五月份的时候我们伟大的 ...
- .NET中的各种池
在.NET中,常用到的池有四个:字符串拘留池.线程池 .应用程序池.数据库连接池. 字符串拘留池 在.NET中字符串是不可变对象,修改字符串变量的值会产生新的对象.为降低性能消耗及减小程序集大小,.N ...
- python中的函数(定义、多个返回值、默认参数、参数组)
函数定义 在python中函数的定义以及调用如下代码所示: def test(x): y = x+1 return y result = test(2) print(result) 多个返回值的情况 ...
- ng-book札记——表单
Angular表单的基本对象为FormControl与FormGroup. FormControl FormControl代表单个input表单字段(field),即Angular表单的最小单元. F ...
- Go 语言常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量. 常量中的数据类型只可以是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: const identifier [type] ...
- OBJ文件格式分析工具: objdump, nm,ar
首先简要阐述关于gcc.glibc和 binutils模块之间的关系 一.关于gcc.glibc和binutils模块之间的关系 1.gcc(gnu collect compiler)是一组编译工具的 ...
- android ActionBarActivity设置全屏无标题
新建的Activity继承自ActionBarActivity,设置全屏无标题本来很简单的事,但是没想到app竟然无缘无故的挂,要么就是白屏一片,要么就是黑屏.坑了我一个多小时!!! 原因是Actio ...
- ObjectOutputStream 和 ObjectInputStream的使用
一.看一下API文档 ObjectOutputStream : ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream.可以使用 ObjectInp ...
- 在 Mac OS X 10.10 安装 pyenv 的一个小坑
小记一下. 因为全面转向 Python 3.4 作为主力开发版本,但是手上的 Mac OS X 和服务器上用的都是 Python 2.7,所以需要安装 pyenv. 按其 github 页面的说明,使 ...