TreeSet 是sortedSet的唯一实现类,正如SortedSet名字暗示,TreeSet可以让集合元素处在排好序的状态。

与HashSet相比,TreeSet还额外提供了以下的方法(列出来,混个脸熟:)

SortedSet subSet(Object  fromElement,Object toElement) :返回这个Set的子集合,范围从fromElement(包含)到toElement(不包含)

SortedSet headSet(Object toElement):返回这个Set的子集合,范围小于toElement的子集合 

SortedSet tailSet(Object fromElement):返回这个Set的子集合,范围大于或等于fromElement的子集合 

Object first(): 返回这个Set第一个元素 

Object last():返回这个Set最后一个元素

Object lower(Object e):返回小于指定元素的集合里最大的那个元素 

Object higher(Object e):返回大于指定元素的集合里最小的那个元素     

【以上参考元素都不需要是集合里的

 总结一下,最后四个方法就是找到集合里的第一个,前一个,后一个,最后一个元素。同时前三个就是返回该集合的符合条件的子集合。

package Test01;

import java.util.TreeSet;

public class TestTreeSet {

  public static void main(String[] args) {
TreeSet num =new TreeSet();
num.add(2);
num.add(-2);
num.add(10);
num.add(9);
System.out.println(num); //看出:不是按照添加的顺序来,是数字由小到大排序
System.out.println(num.first()); //看出:数字由小到大排序的第一个
System.out.println("9到12 之间的"+num.subSet(9, 12));
System.out.println("比8小的"+num.headSet(8));
System.out.println("比8大的"+num.tailSet(8));
}
}

与hashset采用hash算法决定元素的存储位置,TreeSet采用红黑树的数据结构(待跟进)来存储集合元素。那么他的排序规则是怎么的呢?

自然排序(默认情况)。

       调用TreeSet的无参的构造器,并实现Comparable接口,实现里的 compareTo(Object obj)方法,来比较集合元素的大小,然后按照compareTo里的排序。

     该种方法注意:

向TreeSet里添加元素时,只有第一个无须实现Comparable接口,后面的必须实现。(第二个及后面的会调用compareTo方法,与集合里的其他元素比较,要求了比较的两个元素都是一个类的实例,否则会ClassCastException)

package Test01;
import java.util.TreeSet;
public class Foo implements Comparable{
int num;
public Foo(int num) {
this.num =num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "foo:"+this.getNum();
}
@Override
public int compareTo(Object obj) {
// TODO Auto-generated method stub
if(obj instanceof Foo) {
Foo f = (Foo) obj;
if(this.num > f.getNum()) {
return 1;
}
if(this.num == f.getNum()) {
return 0;
}
else
return -1; }
else return 0; }
public static void main(String[] args) {
TreeSet<Foo> test = new TreeSet<>();
test.add(new Foo(8)); test.add(new Foo(3));
System.out.println(test);
} } 

下面的一些常用的类已经实现了Comparable接口,提供了比较大小的标准:

BigDecimal

character

Boolean

String

Date Time

对于TreeSet集合来说,判断两个对象是否相等的唯一标准 是compareTo(Object obj)返回0,是0 就相等,不是0就不等。就不会让相等的对象进入集合。

举例

(正确的结果)能够插入两个compare 不等于0但是equals为true的对象

package Test01;

import java.util.Comparator;
import java.util.TreeSet; public class Comp implements Comparator<Foo>{ @Override
public int compare(Foo o1, Foo o2) {
return 1;
} @Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return true;
} public static void main(String[] args) {
TreeSet<Foo> t = new TreeSet<>(new Comp());
Foo f = new Foo(0);
t.add(f);
t.add(f);
System.out.println(t);
t.first().num =9;
System.out.println(t); }
}

留意下注释的差别,(问题已解决)

package Test01;

import java.util.TreeSet;

public class Test implements Comparable{
int num;
public Test(int num) {
this.num=num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return true;
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 1;
}
public static void main(String[] args) {
TreeSet t = new TreeSet();
Test f = new Test(0);
t.add(f); System.out.println("会把同一个对象但是compareTo返回1添加进TreeSet吗?"+ t.add(f)); //equals不是评价对象相等的标准,compareTo返回0才相等。返回true
System.out.println(t);
((Test)(t.first())).num=9; //修改第一个元素,下面一行发现最后一个元素也被改成了9 System.out.println( ((Test)(t.last())).num);
} }
 

由正确的结果注意:TreeSet也是Set,equals结果注意保持和compareTo结果一致。因为如果compareTo 等于0,但是equals发现false,就和Set冲突。

和hashset同样,讨论下,可变对象插入删除问题(留意注释部分)

package Test01;

import java.util.Iterator;
import java.util.TreeSet; class mutClass implements Comparable{
public int count;
public mutClass(int count) {
this.count =count;
}
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj != null && obj.getClass() == mutClass.class) {
mutClass m =(mutClass) obj;
return this.count == m.count;
}
return false;
}
public int hashcode() {
return this.count;
}
public String toString() {
return "试试mutClass[count=" + count + "]";
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
mutClass m = (mutClass) o;
return count>m.count?1 :count<m.count?-1 :0;
} }
public class TestTreeSet {
@SuppressWarnings("unchecked")
public static void main(String[] args){
TreeSet testHashSet =new TreeSet();
mutClass a = new mutClass(3);
mutClass b = new mutClass(1);
mutClass c = new mutClass(-9);
mutClass d = new mutClass(9);
testHashSet.add(a);
testHashSet.add(b);
testHashSet.add(c);
testHashSet.add(d);
System.out.println("第一次"+testHashSet);
((mutClass)testHashSet.first()).count =20;
System.out.println("第二次"+testHashSet); //修改可变对象的实例变量,不会调整顺序
((mutClass)testHashSet.last()).count =1; //修改可变对象的实例变量,不会调整顺序,且可能出现重复对象的情况
System.out.println("第三次"+testHashSet);
System.out.println(testHashSet.remove(new mutClass(1))); //删除实例变量被修改的元素,应该删除失败,但是我删除成功了?
System.out.println("第四次"+testHashSet); }
}

 定制排序。

自己写个比较器的类,传入TreeSet的有参数的构造器,这样往集合里add元素就能按照定制的顺序排序了。

package Test01;

import java.util.Comparator;
import java.util.TreeSet; public class Comp implements Comparator<Foo>{ @Override
public int compare(Foo o1, Foo o2) {
// TODO Auto-generated method stub
if(o1.getNum()>o2.getNum()) {
return 1;
}
if (o1.getNum() == o2.getNum()) {
return 0;
}
else return -1;
}
public static void main(String[] args) {
TreeSet<Foo> t = new TreeSet<>(new Comp());
t.add(new Foo(0));
t.add(new Foo(-9));
System.out.println(t);
}
}

java set TreeSet详解的更多相关文章

  1. TreeSet()详解

    TreeSet()详解   1.TreeSet原理:   /* * TreeSet存储对象的时候, 可以排序, 但是需要指定排序的算法 *  * Integer能排序(有默认顺序), String能排 ...

  2. java集合框架详解

    java集合框架详解 一.Collection和Collections直接的区别 Collection是在java.util包下面的接口,是集合框架层次的父接口.常用的继承该接口的有list和set. ...

  3. Java集合类的详解与应用

    Java集合类的详解与应用 集合简介: 1.定义:可以同时存储不同类型的数据 他的存储空间会随着数据的增大而增大 2.缺点:只能存储引用数据类型 3.优点:更加合理的利用空间,封装了更多的方法,用起来 ...

  4. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  5. Java 序列化Serializable详解

    Java 序列化Serializable详解(附详细例子) Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连 ...

  6. Java String类详解

    Java String类详解 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 类结构: public final ...

  7. 最新java数组的详解

    java中HashMap详解 http://alex09.iteye.com/blog/539545 总结: 1.就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java ...

  8. JAVA IO 类库详解

    JAVA IO类库详解 一.InputStream类 1.表示字节输入流的所有类的超类,是一个抽象类. 2.类的方法 方法 参数 功能详述 InputStream 构造方法 available 如果用 ...

  9. 转:Java HashMap实现详解

    Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1.    HashMap概述:    HashMap是基于哈希表的M ...

  10. 淘宝JAVA中间件Diamond详解(2)-原理介绍

    淘宝JAVA中间件Diamond详解(二)---原理介绍 大家好,通过第一篇的快速使用,大家已经对diamond有了一个基本的了解.本次为大家带来的是diamond核心原理的介绍,主要包括server ...

随机推荐

  1. 二分查找--java进阶day06

    1.二分查找 https://kdocs.cn/l/ciMkwngvaWfz?linkname=150996908 二分查找:每一次查找都从中间的元素查起,根据比较的大小来折半,以此类推,直到最后找到 ...

  2. 【软件】Rhythmbox播放器调节音量

    Rhythmbox播放器调节音量 零.起因 最近换了Ubuntu系统,在写代码时想听歌,故使用Rhythmbox播放器播放一些mp3文件,但同时又要看教程,希望音乐声音小一点,但是找来找去都没有发现R ...

  3. while(bug)

    while(bug) { // 加了班也不一定写的完代码 // 写完了代码也不一定编译的过 // 编译过了也不一定没bug // 有了bug也不一定找的到 // 找到bug也不一定改的了 // 改了这 ...

  4. SLAM与AI的强强联合

    SLAM与AI的强强联合 本文默认大家已经熟知SLAM.导航.常见AI算法(比如深度学习.强化学习.卷积神经网络.监督学习)等基本概念,不熟的小伙伴可以从我已经出版的书籍<机器人SLAM导航核心 ...

  5. tomghost打靶学习笔记(3)

    主要内容 信息收集:ajp漏洞 横向提权:在没有办法立刻提升到管理员权限时,可以试试通过横向的权限提升切换到其他用户再做提权尝试 涉及尝试了前两台靶机没有用过的枚举方法,比如SUID 使用john解码 ...

  6. .NET 原生驾驭 AI 新基建实战系列(二):Semantic Kernel 整合对向量数据库的统一支持

    1. 引言 在人工智能(AI)应用开发迅猛发展的今天,向量数据库作为存储和检索高维数据的重要工具,已经成为许多场景(如自然语言处理.推荐系统和语义搜索)的核心组件. 对于.NET生态系统的开发者而言, ...

  7. 智能驾驶致死、AI聊天自杀,安全成最大的奢侈

    提供AI咨询+AI项目陪跑服务,有需要回复1 前几天<高层论坛:实现汽车产业高质量发展>才刚召开,因为汽车行业卷得不行,现在大家都想在智能驾驶上发力,其中有句话令我影响深刻: 对智能驾驶来 ...

  8. 求水仙花数和敲桌子小游戏(C++版)

    求水仙花数 for循环书写水仙花数 #include<iostream> using namespace std; int main() { int num = 0; int a=0, b ...

  9. AutoFac(三)——装配扫描(批量注册之扫描模块)

    RegisterAssemblyModules() 模块扫描使用RegisterAssemblyModules()注册方法执行,该方法完全按照其名称执行.它扫描提供的Autofac模块的程序集,创建模 ...

  10. 【深入解析AQS】从设计模式到ReentrantLock实现再到自定义锁

    深入解析AQS:设计模式.ReentrantLock实现与自定义锁开发 一.模板方法模式:AQS的架构基石 1.1 模式核心思想 模板方法模式通过固定算法骨架+可变实现细节的设计,实现了代码复用与扩展 ...