黑马程序员——Java集合框架(2)
来源:互联网 发布:软件腰带剑开刃报价 编辑:程序博客网 时间:2024/06/05 13:49
Set的特点是元素无序,元素不可以重复,它有两个实现类:HashSet和TreeSet。
(1)HashSet:底层数据机构是哈希表,线程非同步
HashSet常用方法:
add(E e)添加元素成功则返回true,前提是之前未包含此元素,否则返回false。
contains(Object o)判断是否包含元素。
isEmpty()判断是否为空,是返回true,否则返回false
iterator()迭代器,用来遍历元素,是HashSet类唯一的获取元素的方法
size()返回元素数量
HashSet特性演示:
import java.util.*;public class hashset {public static void main(String[] args) {HashSet<String> hs=new HashSet<String>();hs.add("a");hs.add("b");hs.add("c");hs.add("d");System.out.println("add():"+hs.add("e"));System.out.println("hs集合:"+hs);System.out.println("contains():"+hs.contains("b"));System.out.println("isEmpty():"+hs.isEmpty());System.out.println("size():"+hs.size());Iterator hsit=hs.iterator();while(hsit.hasNext()){System.out.println(hsit.next());}}}输出结果:
add():true
hs集合:[a, b, c, d, e]
contains():true
isEmpty():false
size():5
a
b
c
d
e
在这个输出结果中,集合中元素是按照被放入的顺序输出的,那HashSet是真正无序的吗?其实在元素不多且没有其他对象冲突的情况下,HashSet中的元素会根据其散列值排序。所以使用HashSet必须是顺序对应用没有影响时才选用。HashSet为了保证存储的元素不会重复,底层都会在每个元素进行存储时和之前的元素进行比较,至于什么样的两个元素算是重复的元素,就必须要说equals()和hashCode()两个方法。当往HashSet中增加元素的时候,HashSet的add方法会调用被添加对象的equals()和hashCode()两个方法,先调用hashCode()方法,看两个对象的哈希值是否相同,一旦相同,会继续调用equals()方法,判断两个对象的内容是否相同。一旦两个方法返回的都是相等,则HashSet判断两个对象是同一个对象。
这对于HashSet来说是非常重要的一点,当HashSet在存储自定义对象的时候需要在自定义类中复写equals()和hashCode()方法,说明在什么情况下,两个对象是相同的,不然HashSet可能会违背意愿的存入相同的对象。
没有复写equals()和hashCode()之前
import java.util.*;class Person{private String name;private String sex;public Person(String name,String sex){this.name=name;this.sex=sex;}public String toString(){return name+"..."+sex;}}public class hashset_hashcode {public static void main(String[] args) {HashSet<Person> hs=new HashSet<Person>();hs.add(new Person("张三","男"));hs.add(new Person("张三","男"));hs.add(new Person("张三","男"));hs.add(new Person("张三","男"));System.out.println(hs);}}输出结果:
[张三...男, 张三...男, 张三...男, 张三...男]
很显然,“张三”,“男”被存储了4遍,对Person类来讲,一旦name和sex属性都相同,应该是同一个对象,不应该被存储4遍,这里出现问题的原因就是没有复写equals()和hashCode()方法。
复写equals()和hashCode()以后,看看结果是什么样的:
<span style="font-size:12px;">import java.util.*;class Person{private String name;private String sex;public Person(String name,String sex){this.name=name;this.sex=sex;}public int hashCode(){return name.hashCode()+10;}public boolean equals(Object o){if(!(o instanceof Person))return false;Person p=(Person)o;return this.name.equals(p.name) && this.sex == p.sex;}public String toString(){return name+"..."+sex;}}public class hashset_hashcode {public static void main(String[] args) {HashSet<Person> hs=new HashSet<Person>();hs.add(new Person("张三","男"));hs.add(new Person("张三1","男"));hs.add(new Person("张三2","男"));hs.add(new Person("张三","男"));System.out.println(hs);}}</span>输出结果:
[张三...男, 张三1...男, 张三2...男]
从上面的结果可以看出,最后一个“张三”,“男”没有存进去。同理,在HashSet中,判断是否包含一个元素,和删除的元素在集合中是否存在,也会调用equals()和hashCode()方法。
(2)TreeSet:可以对Set集合中的元素进行排序
import java.util.*;public class treeset { public static void main(String[] args) {TreeSet<String> ts=new TreeSet<String>();ts.add("c");ts.add("b");ts.add("a");ts.add("d");System.out.println(ts);}}输出结果:
[a, b, c, d]
可见无论添加元素的顺序怎样,TreeSet都将元素进行了排序。那么TreeSet是按照什么规则进行排序的呢?下面就来分析这个问题。
先定义一个自定义的Person类,之后再TreeSet中添加这个类,看看什么结果。
import java.util.*;class Student{private String name;private int age;public Student(String name,int age){this.name=name;this.age=age;}public String toString(){return name+"..."+age;}}public class treeset_compareto {public static void main(String[] args) {TreeSet<person> ts=new TreeSet<person>();ts.add(new Student("张三",18));ts.add(new Student("张三",16));ts.add(new Student("张三",20));ts.add(new Student("张三",26));System.out.println(ts);}}输出结果:
Exception in thread "main" java.lang.ClassCastException: collection.person cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(Unknown Source)
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at collection.treeset_compareto.main(treeset_compareto.java:20)
这里报出了ClassCastException异常,说是Student没有实现Comparable接口。来看看这个接口是干什么的?查API发现,此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
看来要实现TreeSet的还要实现这个接口,并且重写这个compareTo方法才行,看看这个方法的要求:比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
按照要求重新写下Student类,现在看看打印结果
import java.util.*;class Student implements Comparable{private String name;private int age;public Student(String name,int age){this.name=name;this.age=age;}@Overridepublic int compareTo(Object o) { if(!(o instanceof Student)){ throw new RuntimeException(); } Student s = (Student) o; if(this.age > s.age){ return 1; } if(this.age < s.age){ return -1; } return 0; } public String toString(){return name+"..."+age;}}public class treeset_compareto {public static void main(String[] args) {TreeSet<Student> ts=new TreeSet<Student>();ts.add(new Student("张三",18));ts.add(new Student("张三",16));ts.add(new Student("张三",20));ts.add(new Student("张三",26));System.out.println(ts);}}输出结果:
[张三...16, 张三...18, 张三...20, 张三...26]
排序成功,TreeSet根据compareTo方法的定义,用年龄对Student类的对象进行了排序。
- 黑马程序员——Java集合框架(2)
- 黑马程序员——Java基础--集合框架(2)
- 黑马程序员—集合框架(2)
- 黑马程序员——Java集合框架
- 黑马程序员——Java集合框架
- 黑马程序员——java集合框架
- 黑马程序员——java-集合框架
- 黑马程序员——JAVA集合框架
- 黑马程序员——java集合框架
- 黑马程序员——Java集合框架
- 黑马程序员——Java集合框架
- 黑马程序员—java集合框架应用
- 黑马程序员—java集合框架
- 黑马程序员—Java集合框架(LinkedList)
- 黑马程序员—java集合框架整理
- 黑马程序员—Java集合框架
- “黑马程序员”Java集合框架(2)
- 黑马程序员——JAVA——集合框架2
- Topcoder SRM 148 Div2 1000(dfs搜索+hash判重)
- hive的配置与使用
- python学习笔记(三)
- cocos2dx-2.x 打包APK(学习笔记 Python + JDK + ADT + NDK )
- ignore 用法
- 黑马程序员——Java集合框架(2)
- 位运算--一个整数的二进制表示中1的个数
- 删除一个服务
- 搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
- LeetCode: Search in Rotated Sorted Array
- Set中equals()和hashCode()
- DB2 v10.5 EXPLAIN TABLES
- 数据结构之链栈
- TCP/IP详解--TCP的分段和IP的分片