Set接口(HashSet,TreeSet和LinkedHashSet)
Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不 会接受这两个对象。
事实1:set就是就是相当于Map的kay。
事实2:hashSet是为快速查找而设计的set,存入hashSet的元素必须定义hashCode。而treeSet是保持次序的set,使用treeSet可以从set中提取有序的序列,元素必须实现conparable接口。而
linkedHashSet具有hashSet的查询速度,且内部是链表结构,因此遍历linkedHashSet时,结果会按照插入顺序显示!
HashSet
HashSet有以下特点
不能保证元素的排列顺序,顺序有可能发生变化
不是同步的
集合元素可以是null,但只能放入一个null
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。
demo1:
用户自定义类型放进set容器里面,必须要重写equals和hashCode方法,否则会被认为是两个不同的元素。 import java.util.HashSet; import java.util.Set; public class overwriteHahcodeAndEquals { public static void main(String[] args) { Set<Object> set = new HashSet<Object>(); set.add(new Student("lopez",23)); set.add(new Student("lopez",23)); set.add(new Student("shengliang",33)); set.add(new Student("weikun",23)); set.add(new Student("chencheng",28)); System.out.println(set); //output:[set.Student@1420a8f4, set.Student@9b725c34, set.Student@c2ce75cf, set.Student@8d6b816e] //一共4个对象 } } class Student{//内部类 String name; int age; public Student(String name , int age){ this.name = name; this.age = age; } public int hashCode(){//重写hsahCode方法 return age*name.hashCode(); } public boolean equals(Object o){//重写equals方法 Student s = (Student)o; return s.age == this.age && s.name.equals(this.name); } }1.分别在hashCode和equals打断点debug,发现在往Set中插入新的对象时,首先会用该对象的hashCode()与已经存在对象的hashCode()做比较,如果相等,那就不能插入,如果不等,才会调用equals()方法,如果equals结果为true,说明已经存在, 就不能再插入,如果为false,可以插入。
set.add(new String("asd"));
set.add(new String("asd"));
//set只得到一个asd,因为内容相同的String,即使不重写hashCode方法,得到的hashCode都是相同的。
package set; import java.util.HashSet; import java.util.Set; public class overwriteHahcodeAndEquals { public static void main(String[] args) { Set<Object> set = new HashSet<Object>(); set.add(new Student("lopez",23)); set.add(new Student("lopez",23)); set.add(new Student("shengliang",33)); set.add(new Student("weikun",23)); set.add(new Student("chencheng",28)); System.out.println(set); //output:[set.Student@c2ea3f, set.Student@1d5550d, set.Student@c21495, set.Student@1186fab, set.Student@14b7453] //一共5个对象 } } class Student{//内部类 String name; int age; public Student(String name , int age){ this.name = name; this.age = age; } }针对demo2,做了个小测试:
package set; import java.util.HashSet; import java.util.Set; public class overwriteHahcodeAndEquals { public static void main(String[] args) { Set<Object> set = new HashSet<Object>(); Student stu = new Student("lopez",23); Student stu1 = new Student("lopez",23); System.out.println("stu的hashCode值为:" + stu.hashCode()); System.out.println("stu1的hashCode值为:" + stu1.hashCode()); System.out.println("stu和stu1 equals比较" + stu.equals(stu1)); set.add(stu); set.add(stu1); set.add(new Student("shengliang",33)); set.add(new Student("weikun",23)); set.add(new Student("chencheng",28)); System.out.println(set); } } class Student{//内部类 String name; int age; public Student(String name , int age){ this.name = name; this.age = age; } /*public int hashCode(){ return age*name.hashCode(); } public boolean equals(Object o){ Student s = (Student)o; return s.age == this.age && s.name.equals(this.name);//int类型的比较和String类型的比较 }*/ }由以下输出可得知:
LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好(链表结构),但是插入时性能稍微逊色于HashSet,因为插入时linkedHashSet需要维护链表结构。
package set; import java.util.HashSet; import java.util.LinkedHashSet; public class CompareHashSetAndLinkedHashSet { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub HashSet set = new LinkedHashSet(); set.add("lopez1"); set.add("lopez2"); set.add("lopez3"); set.add("lopez4"); for (Object obj : set) { System.out.println(obj.toString()); } //output: //lopez1 //lopez2 //lopez3 //lopez4 HashSet set1 = new HashSet(); set1.add("lopez1"); set1.add("lopez2"); set1.add("lopez3"); set1.add("lopez4"); for (Object obj : set1) { System.out.println(obj.toString()); } //lopez1 //lopez4 //lopez3 //lopez2 } }
TreeSet类
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0
自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。
obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是 负数,则表明obj1小于obj2。
如果我们将两个对象的equals方法总是返回true,则这两个对象的compareTo方法返回应该返回0
定制排序
自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法
按自然顺序demo1:
package set; import java.util.TreeSet; import java.util.Iterator; public class TestTreeSet { public static void main(String[] args) { TreeSet tree = new TreeSet(); tree.add("China"); tree.add("America"); tree.add("England"); tree.add("Japan"); tree.add("Chinese"); tree.add("lapez"); tree.add("lopez"); tree.add("lopez1"); Iterator iter = tree.iterator(); while(iter.hasNext()) { System.out.println(iter.next()); } } //output: America //China //Chinese //England //Japan //lapez //lopez //lopez1 }
定制排序
package set; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; public class TestTreeSet { /** *//** * @param args */ public static void main(String[] args) { MyComparator<String> myComparator = new MyComparator<String>(); // /////////////////////不添加自定义排序 TreeSet<String> treeSet1 = new TreeSet<String>(); treeSet1.add("c"); treeSet1.add("a"); treeSet1.add("b"); Iterator<String> iterator1 = treeSet1.iterator(); while (iterator1.hasNext()) { System.out.println(iterator1.next()); } // /////////////////////添加自定义排序 TreeSet<String> treeSet2 = new TreeSet<String>(myComparator); treeSet2.add("c"); treeSet2.add("a"); treeSet2.add("b"); Iterator<String> iterator2 = treeSet2.iterator(); while (iterator2.hasNext()) { System.out.println(iterator2.next()); } } } class MyComparator<T> implements Comparator<T> { public int compare(T arg0, T arg1) { if (arg0.equals(arg1)) { return 0; } return ((Comparable<T>) arg0).compareTo(arg1) * -1; } }
相关推荐
Set接口的实现类包括HashSet、LinkedHashSet和TreeSet。 HashSet是基于哈希表实现的Set集合,它不保证集合中元素的顺序。由于哈希表的实现机制,HashSet的添加、删除和查找操作都具有很好的性能,时间复杂度为O(1)。...
Set集合类似于一个容器,程序把很多对象保存到Set集合中,Set集合对添加顺序不记录,当有重复的对象保存到Set集合时,不会新增后加的重复对象。 Set集合的特点 Set集合无重复元素,add()方法添加相同元素时,...
java集合在日常开发中经常用到,对基础的掌握尤其重要,其中List,Set,Map的作用以及使用的场景和分类描述,其中Arraylist 与 LinkedList 区别,HashSet与TreeSet与LinkedHashSet对⽐,LinkedHashMap和HashMap,...
java8 源码 学习笔记(持续更新中) 所有文章均同步发布到微信公众号...LinkedHashSet TreeSet HashSet Concurrent源码系列 待完善 JVM(Java虚拟机) 类加载 垃圾回收算法 JavaConcurrent(Java并发系列) 【Java并发系列】
AbstractSet 抽象类SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象类LinkedList ...
Java容器讲解PPT,Collection Map(HashMap TreeMap LinkedHashMap) List (ArrayList LinkedList Vector) Set (HashSet TreeSet LinkedHashSet)
Java数据结构--13.Java8数据结构TreeSet 前⾔ ,上⼀篇中对 Set 接⼝最终实现类 HashSet 与 LinkedHashSet 做了介绍与分析,本篇将对另⼀种 Set 接⼝的最终实现类 TreeSet 进⾏ 介绍与分析。 先来看下 TreeSet 完整...
如果是不能存放重复的元素,用Set接口下的实现类 HashSet:如果没有任何排序要求,用HashSet,因为效率高 TreeSet: 如果有排序要求用TreeSet, 如果是自然排序,需要元素实现Comparable接口,重写compareTo方法 ...
以循环1000000万次为标准! 定义如下数组 public static char[] chars = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q'} ;...JobStateReasons , LinkedHashSet , TreeSet Map接口 …….
所有数据结构都通过以下方法实现容器接口: type Container interface { Empty () bool Size () int Clear () Values () [] interface {} } 容器是有序的还是无序的。 所有有序的容器都提供,其中一些允许。 ...
- 常见实现类有HashSet、TreeSet和LinkedHashSet等。 3. Queue(队列): - 以队列的方式存储元素,遵循先进先出(FIFO)的原则。 - 可以在队列的两端进行操作,即添加元素到队尾或移除队首元素。 - 常见实现类有...
- Set 接口 - AbstractSet 抽象类 - SortedSet 接口 - HashSet - LinkedHashSet - TreeSet - List 接口 - AbstractList 和 AbstractSequentialList - Vector - Stack - ArrayList - LinkedList - Queue...
文章目录1List接口1.1 Array List1.2LInkedList2.collections类2.1是一个集合工具类,内部保存的是静态方法2.2可变参数3.set接口3.1set接口的特点3.2hashSet3.3LinkedHashSet3.4TreeSet. 1List接口 List接口继承...
接下来我们来说说Collection的另一个子接口Set。和List一样,Set也可以用来存放多个元素。我们主要来学习Set的三个实现类。 HashSet TreeSet LinkedHashSet 同样,它们之间的相同点有: 都是Set的实现类 存入的元素...
HashSet (done) TreeSet (done) LinkedHashSet (done) BitSet (done) Map HashMap (done) Hashtable (done) Properties (done) LinkedHashMap (done) IdentityHashMap (done) TreeMap (done) WeakHashMap (done) ...
Set li1 = new HashSet(); // 用TreeSet查询 Set li2 = new TreeSet(); // 用LinkedHashSet查询 Set li3 = new LinkedHashSet(); try { String sql = "select t_fl.f_name,t_fl.f_remark,t_sp.s_name...
从图上我们可以看到Collection接口下有三个儿子,分别是Set,List,Queue;下面我来逐个介绍。 Set Set集合看重的是独一无二,就是没有重复的值。 HashSet:基于哈希表实现,支持快速查找,但是不支持有序,就是插入...
ArrayList 类(数组)② Vector 类(数组、线程同步)③ LinkedList 类(链表)④ CopyOnWriteArrayList 类(线程安全且高效的List)1.2 Set 集合① HashSet 类(HashCode)② LinkedHashSet 类(记录插入顺序)③ ...
java8 集合源码分析 java基础复习 [TOC] 一、集合 1.Iterator 2.Collection 2.1 List--->...---LinkedHashSet: 有序,是HashSet的子类 2.TreeSet: 底层是二叉树,可对元素进行排序,默认是自然顺序
14.6.5 SortedSet接口与TreeSet类 292 14.6.6 自定义满足Sorted集合的类 293 14.6.7 定制SortedSet的排序规则 296 14.6.8 集合的遍历 298 14.6.9 使用for-each循环遍历集合 300 14.7 映射集 301 14.7.1...