treeset,TreeSet是集合,但还有序;那不就在功能上和List一样了吗?
treeset,TreeSet是集合,但还有序;那不就在功能上和List一样了吗?详细介绍
本文目录一览: java中的treeset是实现了sortedset接口的set,但为什么要叫treeset呢?
TreeSet是依靠TreeMap来实现的。
TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,意味着TreeSet中的元素要实现Comparable接口。或者有一个自定义的比较器。
算法可以看JDK的源代码。
因为TreeSet中的对象是要排序的(即你ADD新对象后与SET中原有对象进行比较后,以有序方式存放),所以放入TREESET中的对象的类要实现Comparable接口,你有Address类可能没有实现该接口.
下面是TreeSet实现代码 这个类也似只能通过迭代器迭代元素
*/ import java.util.*;
class Test {
private static TreeSet
ts=new TreeSet
() ; //静态变量 jdk1.5以后 引入范式 public static void main(String []args) {
ts.add(new Point(2,3));
ts.add(new Point(1,7));
ts.add(new Point(8,8));
ts.add(new Point(1,3));
ts.add(new Point(0,4));
Iterator i=ts.iterator(); //迭代器
while(i.hasNext())
{
System.out.println(i.next());
} } }
class Point implements Comparable //实现 Comparable 接口 插入到TreeSet集合中的必须实现的
{ int x,y; Point(int x,int y)
{ this.x=x; this.y=y; }
下面是TreeSet实现代码 这个类也似只能通过迭代器迭代元素 */
import java.util.*; class Test {
private static TreeSet
ts=new TreeSet
() ; //静态变量 jdk1.5以后 引入范式 public static void main(String []args) {
ts.add(new Point(2,3));
ts.add(new Point(1,7));
ts.add(new Point(8,8));
ts.add(new Point(1,3));
ts.add(new Point(0,4));
Iterator i=ts.iterator(); //迭代器
while(i.hasNext()) { System.out.println(i.next()); } } } class Point implements Comparable //实现 Comparable 接口 插入到TreeSet集合中的必须实现的 { int x,y; Point(int x,int y) { this.x=x; this.y=y; }
算法好像用的hashcode吧
treeset实现了sortedset接口,也就是重写了里面的方法,但具体实现的方式由实现的子类自己编写,所以treeset在实现set集合采用的算法是树型算法。
TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,意味着TreeSet中的元素要实现Comparable接口。或者有一个自定义的比较器。Treeset算法:
构造一个新的空TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。package test.treeset;import java.util.Comparator;import java.util.Iterator;import java.util.TreeSet;public class TreeSetTest { @SuppressWarnings("unchecked") public static void main(String[] args) { TreeSet ts = new TreeSet(new Teacher2.TeacherCompare()); ts.add(new Teacher2("zhangsan", 2)); ts.add(new Teacher2("lisi", 1)); ts.add(new Teacher2("wangmazi", 3)); ts.add(new Teacher2("mazi", 3)); Iterator it = ts.iterator(); while (it.hasNext()) { System.out.println(it.next()); } }}class Teacher2 { int num; String name; Teacher2(String name, int num) { this.num = num; this.name = name; } public String toString() { return "学号:" + num + " 姓名:" + name; } static class TeacherCompare implements Comparator {// 老师自带的一个比较器 //o1中存放的事目标节点 //o2中存放时的红黑二叉树中的节点,从根节点开始比较 public int compare(Object o1, Object o2) { Teacher2 s1 = (Teacher2) o1;// 转型 Teacher2 s2 = (Teacher2) o2;// 转型 int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1); if (result == 0) { result = s1.name.compareTo(s2.name); } return result; } }}
TreeSet是集合,但还有序;那不就在功能上和List一样了吗?
对于一般的 List 而言,是有序、可重复。
而 TreeSet 是有序、不可重复。
且 TreeSet 和 List 的有序不是一个概念。List 的有序,指保持元素的添加顺序。而 TreeSet 的有序,是指会调用 Comparable 接口的 compareTo 方法来比较元素大小进行排序,元素可以通过实现 Comparable 接口,重写 compareTo 方法来实现自定义的排序。
比如Integer 实现了Comparable 接口,如果按以下顺序添加,会按数值大小进行排序,而不是按元素添加的顺序:treeSet.add(1); treeSet.add(3); treeSet.add(2);
那么在遍历 treeSet 的时候,会发现它的顺序是 123,而不是 132。
而且 TreeSet 不能像 List 那样能通过索引进行操作。没有 get(i) 之类的方法。
HashSet和TreeSet的区别
==========================他们的区别===========================
1. HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key
2. Map的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是多了一个排序的功能.
3. hashCode和equal()是HashMap用的, 因为无需排序所以只需要关注定位和唯一性即可.
a. hashCode是用来计算hash值的,hash值是用来确定hash表索引的.
b. hash表中的一个索引处存放的是一张链表, 所以还要通过equal方法循环比较链上的每一个对象
才可以真正定位到键值对应的Entry.
c. put时,如果hash表中没定位到,就在链表前加一个Entry,如果定位到了,则更换Entry中的value,并返回旧value
4. 由于TreeMap需要排序,所以需要一个Comparator为键值进行大小比较.当然也是用Comparator定位的.
a. Comparator可以在创建TreeMap时指定
b. 如果创建时没有确定,那么就会使用key.compareTo()方法,这就要求key必须实现Comparable接口.
c. TreeMap是使用Tree数据结构实现的,所以使用compare接口就可以完成定位了.
=====================================他们的用法======================
HashSet的使用
import java.util.HashSet;
import java.util.Iterator;
public class WpsklHashSet
{
//java 中Set的使用(不允许有重复的对象):
public static void main(String[] args)
{
HashSet hashSet=new HashSet();
String a=new String("A");
String b=new String("B");
String c=new String("B");
hashSet.add(a);
hashSet.add(b);
System.out.println(hashSet.size());
String cz=hashSet.add(c)?"此对象不存在":"已经存在";
System.out.println("测试是否可以添加对象 "+cz);
System.out.println(hashSet.isEmpty());
//测试其中是否已经包含某个对象
System.out.println(hashSet.contains("A"));
Iterator ir=hashSet.iterator();
while(ir.hasNext())
{
System.out.println(ir.next());
}
//测试某个对象是否可以删除
System.out.println(hashSet.remove("a"));
System.out.println(hashSet.remove("A"));
//经过测试,如果你想再次使用ir变量,必须重新更新以下
ir=hashSet.iterator();
while(ir.hasNext())
{
System.out.println(ir.next());
}
}
}
/**
* 通过这个程序,还可以测试树集的添加元素的无序性与输出的有序性
*/
import java.util.TreeSet;
import java.util.Iterator;
public class TreeSetTest
{
public static void main(String[] args)
{
TreeSet tree = new TreeSet();
tree.add("China");
tree.add("America");
tree.add("Japan");
tree.add("Chinese");
Iterator iter = tree.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}
}
}
以上就是他们的区别和用法,重在理解,多用,祝你成功
1、TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值
2、HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束
3、HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例
视频讲解的是Java面向对象编程语言中关于集合框架的知识,重点讲解了TreeSet和HashSet的区别,前者是有序的,后者是无序的。前者是通过比较规则返回的结果是否为0来去判断是否是同一个元素,后者则不是。
HashSet无序
TreeSet有序
二者里边不能有重复的对象
hashset没有顺序
Treeset是有序的
如果要加入对象
此对象类需要实现一个排序接口
两者主要在实现方式、数据是否有序以及是否可以放入null值等三方面存在区别。
一、实现方式
HashSet:HashSet是哈希表实现的。
TreeSet:TreeSet是二差树实现的。
二、数据是否有序
HashSet:HashSet中的数据是无序的。
TreeSet:Treeset中的数据是自动排好序的。
三、是否可以放入null值
HashSet:可以放入null,但只能放入一个null。
TreeSet:不允许放入null值。
扩展资料
HashSet是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成,应该为保存到HashSet中的对象覆盖hashCode()和equals()。
1、已知实现接口有:
Serializable, Cloneable, Iterable
, Collection
, Set
。
2、直接已知子类:
JobStateReasons, LinkedHashSet。
参考资料来源:百度百科-HashSet
HashSet,TreeSet和LinkedHashSet的区别
HashSet
HashSet有以下特点
不能保证元素的排列顺序,顺序有可能发生变化
不是同步的
集合元素可以是null,但只能放入一个null
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。
TreeSet类
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0
java TreeSet 倒序是怎么实现的?
Arrays, Collections, Tree字辈都有实现Comparator的排序方式,还有Comparable接口的方式
覆盖里面的compare方法,返回1,-1,0来进行比较
如果第一个参数大于第二个,返回1;小于返回-1,等于返回0,表示升序
小于,返回1,大于返回-1,等于返回0,表示降序
你去看看compareTo的源码,比较数字还可以,字符串的数字类型就不行了
TreeSet是一个有序的集合。
第一:构造、增加、遍历、删除和判断是否包含某个元素同HashSet是一致的。、
第二:证明TreeSet是一个有序的集合。
TreeSet hashSet = new TreeSet();
hashSet.add("a"); //向集合中添加一个字符串
hashSet.add("e");
hashSet.add("b");
hashSet.add("d");
hashSet.add("c");
Iterator it = hashSet.iterator();
while(it.hasNext()){
System.out.println(it.next()+",");
}
输出结果是:
a,
b,
c,
d,
e,
注意:(1)从结果中可以看出元素被排序了,但是这个用默认的排序方法。如何自定义排序呢?可以实现Comparator接口来自定义排序。例如:
import java.util.Comparator;
import ws.wph.android.util.StringUtils;
public class MyCmp implements Comparator {
public int compare(Object element1, Object element2) {
int x = element2.toString().compareTo(element1.toString());
return x;
}
}
然后将该类的对象作为TreeSet构造方法的实参,即TreeSet hashSet = new TreeSet(new
MyCmp());。原理是:向TreeSet增加元素时,自动调用MyCmp类的compare(Object element1, Object
element2)方法,根据方法返回值决定element1和element2的顺序。(此时的输出结果是:e,
d,
c,
b,
a,)
(2)当element1 == element2时返回0,element1 > element2 返回正数,element1 < element2返回负数。
第三:按照学生成绩排序,当成绩相同时按照学号排序
public int compare(Object element1, Object element2) {
int x=0;
Stuendt s1 = (Stuendt)element1;
Stuendt s2 = (Stuendt)element2;
if(s1.getScore() > s2.getScore()){
x=-1;
}else if(s1.getScore() < s2.getScore()){
x=1;
}else{
x = s1.getSno().compareTo(s2.getSno());
}
return x;
}
(3)将汉字转换成拼音
public static String getPingYin(String src){
char[] t1 = null;
t1=src.toCharArray();
String[] t2 = new String[t1.length];
HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();
t3.setCaseType(HanyuPinyinCaseType.LOWERCASE);
t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
t3.setVCharType(HanyuPinyinVCharType.WITH_V);
String t4="";
int t0=t1.length;
try {
for (int i=0;i
<t0;i++)
{
//判断是否为汉字字符
if(java.lang.Character.toString(t1[i]).matches("[\\u4E00-\\u9FA5]+"))
{
t2 = PinyinHelper.toHanyuPinyinStringArray(t1[i], t3);
t4+=t2[0];
}
else
t4+=java.lang.Character.toString(t1[i]).toLowerCase();
}
return t4;
}catch (BadHanyuPinyinOutputFormatCombination e1) {
e1.printStackTrace();
}
return t4;
}
但是需要导入一个包
java TreeSet能存放两个相同的元素吗?
可以存放重复的,关键是看的比较器,只是一般不这么做而已,保留重复就失去set集合无重复的特点。
TreeSet
ts = new TreeSet<>(new Comparator
() { @Override public int compare(String s1, String s2) { int num = s1.compareTo(s2); //比较内容为主要条件 return num == 0 ? 1 : num; //保留重复 }});ts.add("lp");System.out.println(ts);ts.add("lp");System.out.println(ts);输出结果:
[lp]
[lp, lp]
一个有趣的例子,TreeMap的键值,如果按照上面那样,是否也会重复,那key重复,又如何查询到对应的value,其实所谓的“重复”,按照比较器的定义,即使是相同的也认为是“不同”了。 感兴趣可以看下TreeMap 里面 get方法的源码,从源码可以分析到,“重复的key”用get方法获取的值肯定是null。
TreeSet 是set的子类,Set具有元素不可重复性,所以TreeSet也是,不可方2个相同的元素。
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,这种方式就是自然排序。(比较的前提:两个对象的类型相同),也就是说TreeSet是不能存放两个相同的元素的。
TreeSet继承于Set,而Set这个集合本身是不能存放两个相同的元素的。
java中treeset定制排序和自然排序的区别
* TreeSet:
* 1.向TreeSet中添加的元素必须是同一个类的。
* 2.可以按照添加进集合中的元素的指定的顺序遍历。像String、包装类等默认按照从小到大的顺序遍历。
* 3.自然排序:当向TreeSet中添加自定义类的对象时,有两种排序方法:①自然排序 ②定制排序
* 4.自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)
* 在此方法中,指明按照自定义类的哪个属性来排序。
*
* 5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的
* 此属性值相同,但是程序会认为这两个对象是相同的,进而后一个对象就不能添加进来。
*
* >compareTo()与hashCode()以及equals()三者保持一致!
*
treeset为什么需要重写compareto
price是基本数据类型,没有可以调用的方法,要比较两个int值,可以这样做Integer.compare(x, y)
collection(集合)下有两大子接口,List(存储有序的)和Set(存储无序的)
TreeSet是Set接口下的一种实现类,你把元素给添加进去的时候遍历出来的时候是有一定的顺序的,但需要注意的是储存的还是无序的且不可存入相同的元素。这个顺序是由大到小或由小到大A到Z,0到9或反过来。
排序和不存储相同元素的依据是什么呢?TreeSet的话就是先用compareto来比较两个元素是否相同和两个元素谁大谁小,大多少,小多少。如果是0的话当然就不会再添加了。然后按照谁大谁小给你遍历出来。
如果不写compareto 那么第二步就做不了,编译的时候就会出错的。当然还有hashCode();方法和equlas();方法也会对这个存储产生影响。所以自定义类像toString和这几个方法最好还是要根据自己的需要来进行重写的,不然后面会造成一定的麻烦!
补充一下我讲的是以java为基础的。
HashSet,TreeSet和LinkedHashSet的区别
HashSet 与TreeSet和LinkedHashSet的区别
Set接口
Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会接受这两个对象。
HashSet与TreeSet都是基于Set接口的实现类。其中TreeSet是Set的子接口SortedSet的实现类。Set接口及其子接口、实现类的结构如下所示:
|——SortedSet接口——TreeSet实现类
Set接口——|——HashSet实现类
|——LinkedHashSet实现类
“java set”集合的值可以排序吗?
Set集合的排序\x0d\x0a我们知道,Set集合是无序的,\x0d\x0a可以使用TreeSet类,那么TreeSet进行排序的规则是怎样的呢?\x0d\x0a1 TreeSet支持两种排序方式,自然排序和定制排序,在默认情况下,TreeSet采用自然排序.\x0d\x0a自然排序:\x0d\x0aTreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合的元素按升序排列,这种方式就是自然排序.\x0d\x0a为什么集合元素有compareTo方法,因为集合元素对象实现了Comparable接口,该方法返回一个整数值,当一个对象调用该方法与另一个对象进行比较,例如:\x0d\x0aobj1.compareTo(obj2)如果返回0,表示这两个对象相等,如果该方法返回一个正整数,表示obj1大于obj2如果该方法返回一个负整数,表示obj1小于obj2\x0d\x0a所以需要使用TreeSet集合进行自然排序,元素必须实现Comparable接口,但是Java一些常用的类已经实现了该接口,例如:String Character Boolean Date Time\x0d\x0aBigDecimal BigInteger等\x0d\x0a如:\x0d\x0aTreeSet ts = new TreeSet(); \x0d\x0ats.add("b"); \x0d\x0ats.add("c"); \x0d\x0ats.add("a"); \x0d\x0aSystem.out.println(ts);\x0d\x0a结果:a b c