Java学习——Set使用方法以及HashSet和TreeSet的区别,深入理解HashSet如何判断元素是否重复
java学习——Set使用方法以及HashSet和TreeSet的区别
Set为无序集合(无序是指存入元素的先后顺序与输出元素的先后顺序不一致),不允许添加重复元素。Set是个接口,不能直接实例化对象,即Set s=new Set()是错误的。
Set的实现类常用的有:HashSet和TreeSet。
1.HashSet和TreeSet的区别:
(1)HashSet是用哈希表(散列表结构)实现的。
HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,根据该值来找到对象的存储位置。然后和该位置上所有的元素进行equals比较,如果该位置没有其他元素或者比较的结果都为false就存进去,否则就不存。即元素是按照哈希值来找存储位置,所有无序,而且可以保证无重复元素
注意:若向HashSet中存储自定义对象时,需要重写hashCode()和equals()方法(不重写的话不会报错,但运行结果和想象不一样,见下面代码)。
深入理解HashSet集合对象如何判断数据元素是否重复:
判断待存对象hashCode值是否与集合中已有元素对象hashCode值相同,如果hashCode不同则表示不重复,不用执行equals()方法; 如果相同则再调用equals方法进行检查,equals返回false表示不重复,否则表示重复。
注意:Java中的hashCode值是由对象的地址所确定的,每一个地址对应一个值。Object类中的equals方法中比较的也是对象的地址值。
(2)TreeSet是用二叉树实现的。
TreeSet可以对Set集合中的元素进行排序,TreeSet中数据是自动排好序的。
TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。
若元素自身不具备比较功能,则需要实现Comparator接口,并覆盖其compare方法。
2.Set示例代码(使用HashSet实现)
下面代码中,集合中存放的不是自定义的存储对象,所以不需要重写HashCode()和equals()。
package demo; import java.util.Date; import java.util.HashSet; import java.util.Set; public class SetTest { public static void main(String[] args) { //声明一个Set集合对象sd,里面存放的全是Date类型的对象, Set<Date> sd; sd=new HashSet<Date>(); //输出当前的时间,运行结果为1565836065039 System.out.println(new Date().getTime()); //创建几个时间对象 Date a=new Date(1565836065039L); Date b=new Date(1565835065039L); Date c=new Date(1565834065039L); //向集合中添加元素,add()方法返回值为boolean类型,若添加成功,返回true;否则为false sd.add(a); sd.add(b); sd.add(c); //Set中元素不能重复,从下面b1的值以及遍历的输出结果中可以看出。 boolean b1=sd.add(a); System.out.println(b1); //输出false //遍历输出集合中的对象,输出3次。 for(Date dt:sd) { System.out.println(dt); } } }
3.使用HashSet完成自定义类型存储
下面代码中SetStudent类为自定义存储类型,需要重写HashCode()和equals()方法。
若不重写重写HashCode()和equals()方法,不会报错,但结果和想象中不太一样。如下代码所示
(注意下面代码中,用迭代器遍历自定义类型时,取值的使用方法)
package demo; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetStudent { public String name; //姓名 public String xuehao; //学号 public int age; //年龄 public SetStudent(String name,String xuehao,int age) { this.name=name; this.xuehao=xuehao; this.age=age; } public static void main(String[] args) { Set<SetStudent> s=new HashSet(); SetStudent s1=new SetStudent("王","B15",18); SetStudent s2=new SetStudent("李","B16",19); SetStudent s3=new SetStudent("王","B17",18); SetStudent s4=new SetStudent("王","B17",18); SetStudent s5=new SetStudent("王","B15",18); SetStudent s6=new SetStudent("张","B15",20); s.add(s1); s.add(s2); s.add(s3); s.add(s4); s.add(s5); s.add(s6); Iterator it=s.iterator(); while(it.hasNext()) { SetStudent st=(SetStudent)it.next(); System.out.println(st.name+"、"+st.xuehao+"、"+st.age); } } }
运行结果为:
王、B17、18
张、B15、20
王、B15、18
王、B15、18
李、B16、19
王、B17、18
从上面的运行结果可以看出,s4,s5,s6 也存入了集合中,而实际应该是学号是唯一的,s4,s5,s6不应该被存入集合中。
重写HashCode()和equals()方法后代码示例如下:
注意:两个方法都要重写。若SetStudent不重写equals()方法,则会调用父类Objcet中的equals()方法,而Object类中的equals方法中比较的是对象的地址值。
package demo; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetStudent { public String name; //姓名 public String xuehao; //学号 public int age; //年龄 public SetStudent(String name,String xuehao,int age) { this.name=name; this.xuehao=xuehao; this.age=age; } //重写HashCode()方法 @Override public int hashCode() { return xuehao.hashCode(); } //重写equals方法 @Override public boolean equals(Object obj) { SetStudent s=(SetStudent)obj; return this.xuehao.equals(s.xuehao); } public static void main(String[] args) { Set<SetStudent> s=new HashSet(); SetStudent s1=new SetStudent("王","B15",18); SetStudent s2=new SetStudent("李","B16",19); SetStudent s3=new SetStudent("王","B17",18); SetStudent s4=new SetStudent("王","B17",18); SetStudent s5=new SetStudent("王","B15",18); SetStudent s6=new SetStudent("张","B15",20); s.add(s1); s.add(s2); s.add(s3); s.add(s4); s.add(s5); s.add(s6); Iterator it=s.iterator(); while(it.hasNext()) { SetStudent st=(SetStudent)it.next();//注意:此处不能直接 it.next().name,这种写法错误 System.out.println(st.name+"、"+st.xuehao+"、"+st.age); } } }
运行结果为:
王、B15、18
李、B16、19
王、B17、18
3.Set示例代码(使用TreeSet实现)
package demo; import java.util.Set; import java.util.TreeSet; public class TreeSetTest { public static void main(String[] args) { Set<Integer> s=new TreeSet(); //注意此处Integer不能换成int s.add(2); s.add(4); s.add(3); s.add(1); s.add(2); //插入失败,由运行结果也可看出 //使用for-each语句进行遍历 for(int i:s) { System.out.println(i); } } }
运行结果:
1
2
3
4
- java怎么判断两个Set 里的对象的值是否相同【两个set中的值是否相等】、java treeset和hashset如何判断元素是否相同【即对象是否完全相同;利用一个set去除重复元素】
- JAVA基础之——HashSet中是如何判断元素是否重复的
- Java中的Set接口,了解如何判断是否重复元素。
- 深入学习理解java:ExecutorService invokeAll 任务的批量提交invokeAll两种方法的区别
- HashSet中是如何判断元素是否重复的
- HashSet中是如何判断元素是否重复的
- javascript如何判断数组内元素是否重复的方法集锦
- hashCode方法的作用----java判断来年各个元素是否重复的机制
- Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashset类,hashcode()与Lin
- javaAPI深入理解(1)如何截断一个List以及List.subList()方法的坑
- 【Java学习笔记】Hashset判断自定义对象是否重复
- HashSet中是如何判断元素是否重复的
- Java面试题:用什么方法来区分Set里的元素是否重复
- 【Java面试题】39 Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
- Java——HashSet存储元素不重复的原理?以及如何保证存储对象内容也不重复?
- java中equals和==之间的区别?clone方法的作用,及其为什么要使用clone方法?如何使用clone复制对象?以及深克隆浅克隆
- 判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示
- 【Java_集合框架Set】HashSet、LinkedHashSet、TreeSet使用区别
- Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashset类,hashcode()与LinkedHashSet类))
- javaAPI深入理解(1)如何截短一个List以及List.subList()方法的坑