JAVA学习笔记——Set集合及其子类
2021/5/21 20:29:03
本文主要是介绍JAVA学习笔记——Set集合及其子类,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Java学习笔记——Set集合及其子类
对Set集合的阐述
Set集合类似于一个罐子,我们可以依次把多个对象丢入Set集合,但是Set集合通常不记住元素的添加顺序。
Set集合与Colletcion基本相同,只不过Set集合不允许出现相同的元素,如果使用add方法添加是出现相同元素,则会返回false值并且该相同元素不会被加入。
Set集合就只有这些东西,我们主要讲的还是Set集合的三个实现类:HashSet、LinkedHashSet、TreSet。
一.HashSet类
HashSet类作为Set集合的一个实现类,主要是以Hash算法来存储集合中的元素,因此具有很好的存储以及查询性能。
主要原理是,在向HashSet集合中添加一个元素时,它会调用该对象的hashCode( )方法来得到该对象的哈希值,然后通过该对象的哈希值判断在HashSet集合中的存储位置。在后续添加中,如果两个元素如果equals( )方法比较成功,同时hashCode( )方法返回值也相等,则说明他们是相同内容的东西,因此无法添加成功。
但是如果equal( )方法返回值相等,hashCode( )返回值不相等,则该元素还是会被添加到集合中,这个会非常麻烦,在后面会讲到对于此类的解决方法。
public class HashSetDemo1 { public static void main(String[] args) { //正常情况 Set<String> set=new HashSet<String>(); set.add("Tempestissimo 11.50"); set.add("Tempestissimo 11.50"); set.add("Grievous Lady 11.30"); set.add("Feacture Ray 11.20"); set.add("Feacture Ray 11.20"); set.add("SAIKYO STRONGER 11.00"); set.add("Aegleseeker 11.00"); for(String a:set){ System.out.println(a); } } }
HashSet类的特点
- 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
- HashSet不是同步的,如果多个线程同时访问一个HashSet,假设有两个或者两个以上线程同时修改了HashSet集合时,就必须通过代码来保证其同步。
- 集合元素值可以是null
对于使用HashSet集合时判断的标准
在判断时,若没有重写equals( )和hashCode( )方法,则会直接调用Object类中的这两个方法,而这样子做相当于没有比较,因此若我们要重写该对象对应类比较方法时,必须两个方法都要同时重写,即如果重写了equals( )方法,就必须重写hashCode( )方法,反之亦然
如果两个对象的equals( )方法返回的都是true,而hashCode( )方法返回值不相等,则会把这两个相同的对象存储在两个不同的位置。这样子与Set集合的规则 冲突;若如果hashCode( )方法返回的是true但是equals( )方法返回的值是false,则会导致性能下降。
其实很简单,把equals( )方法和hashCode方法( )都重写了就得了
要注意的一点是,在可变对象添加到了HashSet集合之后,不要再去修改集合中参与计算的hashCode( ),equals( )的实例变量,否则会导致HashSet( )无法正确 操作这一些元素。
public class HashSetDemo2 { public static void main(String[] args) { Set<SongInfo> set=new HashSet<SongInfo>(); SongInfo song1=new SongInfo("Tempestissimo",11.50f); SongInfo song2=new SongInfo("Tempestissimo",11.50f); SongInfo song3=new SongInfo("Grievous Lady",11.30f); SongInfo song4=new SongInfo("Feacture Ray",11.20f); SongInfo song5=new SongInfo("SAIKYO STRONGER",11.00f); SongInfo song6=new SongInfo("SAIKYO STRONGER",11.00f); SongInfo song7=new SongInfo("Aegleseeker",11.00f); set.add(song1); set.add(song2); set.add(song3); set.add(song4); set.add(song5); set.add(song6); set.add(song7); for(SongInfo a:set){ String songname=a.getSongname(); float rating=a.getRating(); System.out.println(songname+"-----"+rating); } } } //Songinfo类 public class SongInfo { private String songname; private float rating; public SongInfo() { } public SongInfo(String songname, float rating) { this.songname = songname; this.rating = rating; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SongInfo songInfo = (SongInfo) o; return Float.compare(songInfo.rating, rating) == 0 && songname.equals(songInfo.songname); } @Override public int hashCode() { return Objects.hash(songname, rating); } } //这里重写了equals方法和hashCode方法
二,LinkedSet类
和HashSet差不多,最主要的是底层数据结构有个链表,因此记录了插入顺序,同时使用Hash算法来维护这个链表
public class LinkedSetDemo { public static void main(String[] args) { Set<String> set=new LinkedHashSet<String>(); set.add("Hello"); set.add("World"); set.add("World"); set.add("Java"); for(String a:set){ System.out.println(a); } } } 输出结果 Hello World Java
三.TreeSet类
底层数据结构为红黑树,储存的数据有有序性。其排序有两种方式:自然排序和定制排序
1. 自然排序
自然排序是指利用集合元素的 compareTo( )方法来比较元素之间的大小关系,然后将集合元素按升序排序
注意,实现compareTo方法必须先实现Comparable接口
public class TreeSetDemo1 { public static void main(String[] args) { Set<SongInfo> set=new TreeSet<SongInfo>(); SongInfo song1=new SongInfo("Tempestissimo",11.50f); SongInfo song2=new SongInfo("Tempestissimo",11.50f); SongInfo song3=new SongInfo("Grievous Lady",11.30f); SongInfo song4=new SongInfo("Feacture Ray",11.20f); SongInfo song5=new SongInfo("SAIKYO STRONGER",11.00f); SongInfo song6=new SongInfo("SAIKYO STRONGER",11.00f); SongInfo song7=new SongInfo("Aegleseeker",11.00f); set.add(song1); set.add(song2); set.add(song3); set.add(song4); set.add(song5); set.add(song6); set.add(song7); for(SongInfo a:set){ String songname=a.getSongname(); float rating=a.getRating(); System.out.println(songname+"-----"+rating); } } } //输出结果 Tempestissimo-----11.5 Grievous Lady-----11.3 Feacture Ray-----11.2 SAIKYO STRONGER-----11.0 Aegleseeker-----11.0
SongInfo类
public class SongInfo implements Comparable{ public String songname; public float rating; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SongInfo songInfo = (SongInfo) o; return Float.compare(songInfo.rating, rating) == 0 && songname.equals(songInfo.songname); } @Override public int hashCode() { return Objects.hash(songname, rating); } @Override //这里重写了compareTo方法 public int compareTo(Object o) { SongInfo a = (SongInfo) o; if (a.rating > this.rating) { return 1; } else if(a.rating==this.rating&&a.songname!=this.songname){ return 1; } else return 0; } }
2. 比较器排序
如果想实现定制排序可以通过Comparator接口的帮助,提供一个Comparator对象与该TreeSet集合关联,由该对象来负责该集合元素的排序逻辑
例如下面的代码
public class TreeSetDemo { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { int num = s1.getName().length() - s2.getName().length(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; return num3; } }); Student s1 = new Student("linqingxia", 27); Student s2 = new Student("zhangguorong", 29); Student s3 = new Student("wanglihong", 23); Student s4 = new Student("linqingxia", 27); Student s5 = new Student("liushishi", 22); Student s6 = new Student("wuqilong", 40); Student s7 = new Student("fengqingy", 22); Student s8 = new Student("linqingxia", 29); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); ts.add(s8); for (Student s : ts) { System.out.println(s.getName() + "---" + s.getAge()); } } } //输出结果
总结
- Set和Collection实际上没有区别,只不过Set集合不记住元素的添加的顺序
- Set有三个子类:HashSet,LinkedSet和TreeSet
- HashSet的核心就是利用hash算法来存储元素的内容以及在判断相同的时候回引用指定类的equals和hashCode方法来判断是否为同一元素,因此要记住在实现自定义类的时候记得要重写equals和hashCode方法
- LinkedSet类唯一区别就是它会记录元素的添加顺序
- TreeSet利用红黑树作为存储结构,进行有序的存储,并且能进行自然排序和定制(比较器)排序
这篇关于JAVA学习笔记——Set集合及其子类的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25Java创意资料:新手入门的创意学习指南
- 2024-11-25JAVA对接阿里云智能语音服务资料详解:新手入门指南
- 2024-11-25Java对接阿里云智能语音服务资料详解
- 2024-11-25Java对接阿里云智能语音服务资料详解
- 2024-11-25JAVA副业资料:新手入门及初级提升指南
- 2024-11-25Java副业资料:入门到实践的全面指南
- 2024-11-25Springboot应用的多环境打包项目实战
- 2024-11-25SpringBoot应用的生产发布项目实战入门教程
- 2024-11-25Viite多环境配置项目实战:新手入门教程
- 2024-11-25Vite多环境配置项目实战入门教程