集合工具类之Set特点和实现类的详解
来源:互联网 发布:樱井知香的第一部片 编辑:程序博客网 时间:2024/05/12 01:35
Set是Collection子接口,模拟了数学上的集的概念。
HashSet是Set接口最常用的实现类,顾名思义,底层是用了哈希表(散列/hash)算法。其底层其实也是一个数组,存在的意义是提供查询速度,插入的速度也是比较快,但是适用于少量数据的插入操作。
在HashSet中如何判断两个对象是否相同问题:(二者缺一不可)
1、两个对象的equals比较相等,返回true,这说明是相同对象。
2、两个对象的hashCode方法返回值相等。
对象的hashCode值决定了在哈希表中的存储位置。
当往hashCode集合中添加新的对象的时候,会先判断该对象和集合对象中的hashCode值:
1)不等:直接把该新的对象存储到hashCode指定的位置。
2)相等:再继续判断新对象和集合对象中的equals作比较。
1>:hashCode相同,equals为true,则视为是同一个对象,则不会保存在哈希表中;
2>:hashCode相同,equals为false,非常麻烦,存储在之前对象同槽位的链表上。
所以存储在哈希表中的对象,都应该覆盖equals方法和hashCode方法,并且保证equals相等的时候,hashCode也应该相等。
当向hashSet集合中存入一个新的元素时,hashSet会先调用该对象的hashCode方法来得到该对象的hashCode值,然后决定该对象在HashSet中的存储位置;
如果两个元素通过equals方法比较返回true,但是他们的hashCode值不等,HashSet会把两个元素存储在不同的位置。
Eclipse可以自动生成hashCode和equals方法。
List接口:允许元素重复,记录先后添加顺序。
LinkedHashSet:底层才有哈希表和链表算法。
哈希表:保证唯一性,此时就是HashSet,在哈希表中元素没有先后顺序;
链表:来记录元素的先后添加顺序。
注意:必须保证TreeSet集合中的元素对象是相同的数据类型,否则报错。
TreeSet的排序规则:(自然排序)
TreeSet调用集合元素的compareTo方法来比较元素的大小关系,然后将集合元素按照升序排列(从小到大)
要求TreeSet集合中元素得实现java.util.Comparable接口。
java.util.Comparable接口:可比较的
覆盖public int compareTo(Object o)方法,在该方法中编写比较规则;在该方法中,比较当前对象(this)和参数对象o作比较(严格上来说比较的事对象中的数据,比如按照对象的年龄排序)
this > 0: //返回正整数
this < 0: //返回负整数
this == 0: //返回零,此时认为两个对象是同一个对象。
在TreeSet的自然排序中,认为如果两个对象比较的compareTo方法返回的是0,则认为是同一个对象。
定制排序(从大到小,按照名字长度排序):
在TreeSet构造器中传递java.lang.Comparator对象,并覆盖public int compare(Person o1, Person o2)方法,在覆写比较规则。
对于TreeSet集合来说,要么使用自然排序,要么使用定制排序:(判断两个对象是否相等的规则)
自然排序:compareTo方法返回0;
定制排序:compare方法返回0。
运行结果:
1、都不允许元素重复;
2、都不是线程安全的类。
1、equals比较为true;
2、hashCode值相同。
要求:要求存在在哈希表中的对象元素都得覆盖equals和hashCode方法。
LinkedHashSet:HashSet的子类,底层也采用的是哈希表算法,但是也使用了链表算法来维持元素的先后添加顺序,判断两个对象是否相等的规则和HashSet相同。
因为需要多使用一个链表来记录元素的顺序,所以性能相对于HashSet较低;一般少用,如果要求一个集合急要保证元素不重复,也需要记录元素的先后添加顺序,才选择使用LinkedHashSet。
运行结果:
Set集合存储特点:
1) 不允许元素重复。
2) 不会记录元素的先后添加顺序。
Set只包含从Collection继承的方法,不过Set无法记住添加的顺序,不允许包含重复的元素。当试图添加两个相同元素进Set集合,添加操作失败,add()方法返回false;
Set判断两个对象是否相等用equals,而不是使用==。也就是说两个对象equals比较返回true,Set集合是不会接受这两个对象的。HashSet是Set接口最常用的实现类,顾名思义,底层是用了哈希表(散列/hash)算法。其底层其实也是一个数组,存在的意义是提供查询速度,插入的速度也是比较快,但是适用于少量数据的插入操作。
在HashSet中如何判断两个对象是否相同问题:(二者缺一不可)
1、两个对象的equals比较相等,返回true,这说明是相同对象。
2、两个对象的hashCode方法返回值相等。
对象的hashCode值决定了在哈希表中的存储位置。
当往hashCode集合中添加新的对象的时候,会先判断该对象和集合对象中的hashCode值:
1)不等:直接把该新的对象存储到hashCode指定的位置。
2)相等:再继续判断新对象和集合对象中的equals作比较。
1>:hashCode相同,equals为true,则视为是同一个对象,则不会保存在哈希表中;
2>:hashCode相同,equals为false,非常麻烦,存储在之前对象同槽位的链表上。
所以存储在哈希表中的对象,都应该覆盖equals方法和hashCode方法,并且保证equals相等的时候,hashCode也应该相等。
当向hashSet集合中存入一个新的元素时,hashSet会先调用该对象的hashCode方法来得到该对象的hashCode值,然后决定该对象在HashSet中的存储位置;
如果两个元素通过equals方法比较返回true,但是他们的hashCode值不等,HashSet会把两个元素存储在不同的位置。
Eclipse可以自动生成hashCode和equals方法。
List接口:允许元素重复,记录先后添加顺序。
Set接口:不允许元素重复,不记录先后添加顺序。
LinkedHashSet:底层才有哈希表和链表算法。
哈希表:保证唯一性,此时就是HashSet,在哈希表中元素没有先后顺序;
链表:来记录元素的先后添加顺序。
注意:必须保证TreeSet集合中的元素对象是相同的数据类型,否则报错。
TreeSet的排序规则:(自然排序)
TreeSet调用集合元素的compareTo方法来比较元素的大小关系,然后将集合元素按照升序排列(从小到大)
要求TreeSet集合中元素得实现java.util.Comparable接口。
java.util.Comparable接口:可比较的
覆盖public int compareTo(Object o)方法,在该方法中编写比较规则;在该方法中,比较当前对象(this)和参数对象o作比较(严格上来说比较的事对象中的数据,比如按照对象的年龄排序)
this > 0: //返回正整数
this < 0: //返回负整数
this == 0: //返回零,此时认为两个对象是同一个对象。
在TreeSet的自然排序中,认为如果两个对象比较的compareTo方法返回的是0,则认为是同一个对象。
定制排序(从大到小,按照名字长度排序):
在TreeSet构造器中传递java.lang.Comparator对象,并覆盖public int compare(Person o1, Person o2)方法,在覆写比较规则。
对于TreeSet集合来说,要么使用自然排序,要么使用定制排序:(判断两个对象是否相等的规则)
自然排序:compareTo方法返回0;
定制排序:compare方法返回0。
自然排序和定制排序的基本使用:
class Person implements Comparable<Person> {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}@Overridepublic int compareTo(Person other) {if (this.age > other.age) {return 1;} else if (this.age < other.age) {return -1;}return 0;}}// 名字长度比较器class NameLengthComparator implements Comparator<Person> {@Overridepublic int compare(Person o1, Person o2) {if (o1.name.length() > o2.name.length()) {return 1;} else if (o1.name.length() < o2.name.length()) {return -1;}return 0;}}public class TreeSetDemo {public static void main(String[] args) {Set<Person> set = new TreeSet<>();set.add(new Person("倩儿", 32));set.add(new Person("西门吹雪", 52));set.add(new Person("叶孤城", 62));set.add(new Person("霞", 18));System.out.println(set);System.out.println("----------------------------------");Set<Person> set1 = new TreeSet<>(new NameLengthComparator());set1.add(new Person("倩儿", 32));set1.add(new Person("西门吹雪", 52));set1.add(new Person("叶孤城", 62));set1.add(new Person("霞", 18));System.out.println(set1);}}
运行结果:
1、都不允许元素重复;
2、都不是线程安全的类。
解决方案:Set set = Collections.sysnchronizedSet(Set对象);
Set的家族:
1、equals比较为true;
2、hashCode值相同。
要求:要求存在在哈希表中的对象元素都得覆盖equals和hashCode方法。
LinkedHashSet:HashSet的子类,底层也采用的是哈希表算法,但是也使用了链表算法来维持元素的先后添加顺序,判断两个对象是否相等的规则和HashSet相同。
因为需要多使用一个链表来记录元素的顺序,所以性能相对于HashSet较低;一般少用,如果要求一个集合急要保证元素不重复,也需要记录元素的先后添加顺序,才选择使用LinkedHashSet。
HashSet和LinkedHashSet的排序效果:
public class SetDemo {public static void main(String[] args) {Set<String> set = new HashSet<>();set.add("Z");set.add("O");set.add("B");set.add("1");set.add("2");System.out.println(set);Set<String> set1 = new LinkedHashSet<>();set1.add("Z");set1.add("O");set1.add("B");set1.add("1");set1.add("2");System.out.println(set1);}}
运行结果:
阅读全文
0 0
- 集合工具类之Set特点和实现类的详解
- 集合工具类之List特点和实现类的详解
- 集合工具类之Map特点和实现类的详解
- 集合框架--List和Set的特点
- set集合特点级子类的特点
- 常用对象API(集合框架-List和Set的特点)
- java 集合(list、set、map)的特点 集合相关的类有一大堆
- java集合框架之Set集合实现类性能对比
- java的集合中的Set以及set的实现类HashSet和TreeSet
- 多重集合set 的list实现详解
- Java知识(Set接口和集合工具类)
- 常用集合类的特点
- List集合的子实现类及其特点
- 集合类collection类详解和set map简介
- JavaSE入门学习36:Java集合框架之Set接口及其实现类HashSet和TreeSet
- 浅谈Set集合特点
- 集合,Set实现类笔记
- 集合:Set实现类HashSet
- Android-Studio多个项目添加依赖同一个模块
- 如何防止头文件被重复包含、嵌套包含
- SpringBoot看书笔记(1)
- View的事件分发
- C++接口实现总结(Interface)
- 集合工具类之Set特点和实现类的详解
- 动态规划题目整合
- APP生产线构建------ErrorProne实施
- MAC 改变硬盘大小
- 【MySQL】(1)mysql-5.6.22-winx64数据库的安装、配置、简单使用
- 数据结构之查找
- Eclipse Maven创建Java Web项目
- js常用方法总结
- xpath contains