TreeSet:

1.特点

TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列

2.使用方式

a.自然顺序(Comparable)

TreeSet类的add()方法中会把存入的对象提升为Comparable类型

调用对象的compareTo()方法和集合中的对象比较(当前存入的是谁,谁就会调用compareTo方法)

根据compareTo()方法返回的结果进行存储

b.比较器顺序(Comparator)

创建TreeSet的时候可以制定 一个Comparator

如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序

add()方法内部会自动调用Comparator接口中compare()方法排序

调用的对象(就是当前存入的对象)是compare方法的第一个参数,集合中的对象(已经添加进去的对象)是compare方法的第二个参数

c.两种方式的区别

TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)

TreeSet如果传入Comparator, 就优先按照Comparator

1. TreeSet存储Integer类型的元素

package online.msym.set;
import java.util.Comparator;
import java.util.TreeSet;
import online.msym.bean.Person;
public class Demo3_TreeSet {
/**
* @param args
* TreeSet集合是用来对象元素进行排序的,同样他也可以保证元素的唯一
*/
public static void main(String[] args) {
demo1();
}
public static void demo1() {
TreeSet<Integer> ts = new TreeSet<>();
ts.add(3);
ts.add(1);
ts.add(1);
ts.add(2);
ts.add(2);
ts.add(3);
ts.add(3);
System.out.println("TreeSet存储Integer类型的元素: " + ts);
}
}

2. TreeSet存储自定义对象

package online.msym.set;
import java.util.Comparator;
import java.util.TreeSet;
import online.msym.bean.Person;
public class Demo3_TreeSet {
/**
* @param args
* TreeSet集合是用来对象元素进行排序的,同样他也可以保证元素的唯一
* 当compareTo方法返回0的时候集合中只有一个元素
* 当compareTo方法返回正数的时候集合会怎么存就怎么取
* 当compareTo方法返回负数的时候集合会倒序存储
*/
public static void main(String[] args) {
demo2();
}
public static void demo2() {
//因为TreeSet要对元素进行排序,那你排序的依据是什么,姓名还是年龄还是其它的,得告诉它,怎么告诉?
//需要让Person类实现Comparable接口重写compareTo方法
TreeSet<Person> ts = new TreeSet<>();
ts.add(new Person("张三", 23));
ts.add(new Person("李四", 13));
ts.add(new Person("周七", 13));
ts.add(new Person("王五", 43));
ts.add(new Person("赵六", 33)); System.out.println(ts);
} }

注意上面的输出,跟添加的顺序相反,那是因为compareTo方法的返回值

Person实体类:

package online.msym.bean;
//为了简化代码,这里没有hashCode和equals方法,用的话可以直接将上面的Person类中的hashCode和equals复制过来
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() {
super(); }
public Person(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]\n";
}
public int compareTo(Person o) {
//return 0;
//return 1;
return -1
} }

TreeSet保证元素唯一和自然排序的原理和图解

TreeSet保证元素唯一和自然排序的原理和图解,小的放左侧,大的放右侧

按照Person类的年龄排序的话,Person类改写为:

//注意使用此类时要生成空参有参构造,set和get方法,hashCode和equals方法
package online.msym.bean;
public class Person implements Comparable<Person> {
private String name;
private int age;
@Override
//按照年龄排序
public int compareTo(Person o) {
       int num = this.age - o.age; //按照年龄比较 
return num;
     //return num == 0 ? this.name.compareTo(o.name) : num;//姓名是比较的次要条件
}
}

TreeSet保证元素唯一和比较器排序的原理:

定义比较器是实现Comparator接口,重写compare方法和equals方法,但是由于所有的类默认继承Object,而Object中有equals方法,

所以自定义比较器类时,不用重写equals方法,只需要重写compare方法

字符串长度比较器图解:

下面采用了两种方式:匿名的内部类的比较器对象,自定义的比较器对象,

package online.msym.test;
import java.util.Comparator;
import java.util.TreeSet;
import online.msym.bean.Person;
public class Demo3_TreeSet {
public static void main(String[] args) {
//demo1();
demo2();
}
private static void demo2() {
// 需求:将字符串按照长度排序, (利用匿名内部类对象, 长度从大到小, 长度相同按照字母倒序)
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
int num = s2.length() - s1.length(); // 长度为主要条件
return num == 0 ? s2.compareTo(s1) : num; // 内容为次要条件
}
});
ts.add("aaaaaaaa");
ts.add("z");
ts.add("wc");
ts.add("nba");
ts.add("cba");
System.out.println(ts);
}
private static void demo1() {
// 需求:将字符串按照长度排序,(传递一个自定义的比较器对象)
TreeSet<String> ts = new TreeSet<>(new CompareByLen()); // Comparator c = new CompareByLen();
ts.add("aaaaaaaa");
ts.add("z");
ts.add("wc");
ts.add("nba");
ts.add("cba");
System.out.println(ts);
}
}
class CompareByLen /* extends Object */implements Comparator<String> {//实现一个比较器类
@Override
public int compare(String s1, String s2) { // 按照字符串的长度比较
int num = s1.length() - s2.length(); // 长度为主要条件
return num == 0 ? s1.compareTo(s2) : num; // 内容为次要条件
}
}

【点击此处回到主页】

TreeSet集合如何保证元素唯一的更多相关文章

  1. HashSet保证元素唯一原理以及HashMap扩容机制

    一.HashSet保证元素唯一原理: 依赖于hashCode()和equals()方法1.唯一原理: 1.1 当HashSet集合要存储元素的时候,会调用该元素的hashCode()方法计算哈希值 1 ...

  2. Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?

    首先将源码逐级找出来1.HashSet<String> hs=new HashSet<String>();         hs.add("hello"); ...

  3. java中TreeSet集合如何实现元素的判重

    /* 看一下部分的TreeSet源码.... public class TreeSet<E> extends AbstractSet<E> implements Navigab ...

  4. java-Set集合、HashSet集合、LinkedHashSet集合和TreeSet集合

    1.Set集合,无索引,不可以重复,无序(存取不一致) public class Demo { public static void main(String[] args) { //demo1(); ...

  5. TreeSet集合的自然排序与比较器排序、Comparable接口的compareTo()方法

    [自然排序] package com.hxl; public class Student implements Comparable<Student> { private String n ...

  6. java基础33 Set集合下的HashSet集合和TreeSet集合

    单例集合体系: ---------| collection  单例集合的根接口--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合 ...

  7. Java基础知识强化之集合框架笔记47:Set集合之TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序:Comparator)

    1. 比较器排序(定制排序) 前面我们说到的TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列. 但是如果需要实现定制排序,比如实现降序排序,则要通过比较器排序(定制排序)实 ...

  8. Java基础知识强化之集合框架笔记44:Set集合之TreeSet保证元素唯一性和自然排序的原理和图解

    1. TreeSet保证元素唯一性和自然排序的原理和图解 2. TreeSet唯一性以及有序性底层剖析: 通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法. 跟踪 ...

  9. 集合框架(HashSet存储自定义对象保证元素唯一性)

    HashSet如何保证元素唯一性的原理 1.HashSet原理 a. 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降 ...

随机推荐

  1. SQL 增删改查45道题

    create database School use School go create table Student --1.学生表 ( Sno ) not null primary key,--学号( ...

  2. github在windows下的安装和基本使用

    1.在win下安装github时花费的时间是非常长的,有时还会出现因各种原因安装不成功.离线包本地安装方便的解决了此问题.点击http://pan.baidu.com/s/1boGrNLP可下载,解压 ...

  3. React库

    一.React概述 React是一个是一个开源的js库,用来为数据渲染视图的,由facebook,Instagram社区维护的.(例如美团.阿里.airbnb都在使用React开发) 为什么会出现Re ...

  4. React 国际化

    前言 React 做国际化,我推荐使用 React-intl , 这个库提供了 React 组件和Api两种方式来格式化日期,数字和字符串等.知道这个库了,那让我们开始使用它 组件用法 为了和Reac ...

  5. Java排序小算法(冒泡和选择)

    package MyTest; import java.util.Scanner; public class BubbleSort { public void Init(int array[]) { ...

  6. Ancient Cipher UVa1339

    这题就真的想刘汝佳说的那样,真的需要想象力,一开始还不明白一一映射是什么意思,到底是有顺序的映射?还是没顺序的映射? 答案是没顺序的映射,只要与26个字母一一映射就行 下面给出代码 //Uva1339 ...

  7. ABP Zero 单部署,单数据库,多租户架构

    首先,我们应该定义多租户系统中的两个条目: 租主(Host):租主是单例的(只有一个租主).租主会对创建和管理租户负责.因此,一个“租主用户”比所有的租户等级更高,并独立于所有租户,同时还能控制他们. ...

  8. 使用grunt完成requirejs的合并压缩和js文件的版本控制

    最近有一个项目使用了 requirejs 来解决前端的模块化,但是随着页面和模块的越来越多,我发现我快要hold不住这些可爱的js文件了,具体表现在每个页面都要设置一堆 requirejs 的配置( ...

  9. RAC之常用方法-----新手入门

    年后换工作新入职,公司开发在使用RAC,之前居然一直没有了解过,独立开发的弊端,信息闭塞,而且自己也懒,这几天看了下RAC,确实很强大有木有. 什么是ARC 简单的说,RAC就是一个第三方库,他可以大 ...

  10. iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列“惨案”

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...