Java学习笔记31(集合框架五:set接口、哈希表的介绍)
2018-01-13 12:19
656 查看
set接口的特点:
1.不包含重复元素
2.set集合没有索引,只能用迭代器或增强for循环遍历
3.set的底层是map集合
方法和Collection的方法基本一样
set接口的实现类HashSet:
1.无序集合
2.可以存入空(null)
3.不可以存在重复元素
示例:
set底层数据结构是哈希表:
特点:存储取出都比较快
原理:具体省略,简单说就是链表数组结合体
对象的哈希值:普通的一个整数
可以理解为身份证号,是hashset存储的依据
哈希表存储过程:
1.调用对象的哈希值
2.集合在容器内搜索有没有重复的哈希值,如果没有,存入新元素,记录哈希值
3.再次存储,重复上边的过程
4.如果有重复的哈希值,调用后来者的equals方法,参数为前来者,结果得到true,集合判断为重复元素,不存入
相同的字符串如果存进去,哈希值相同,equals方法为true,不会存入相同的
只要哈希值相同或者equals方法为true都成立才不会存入,只要其中一条不满足,都会储存
哈希表存储自定义对象:
自己重写:
eclipse可以帮助我们写:
LinkedHashSet集合:基于链表的哈希表实现,继承HashSet,它具有顺序
示例:
关于hashcode和equals的一些问题,在面试中会问道:
1.两个对象哈希值相同,那么equals方法一定返回true吗?不一定
取决于如何重写equals,如果重写固定了它返回false,结果就一定是false
2.equals方法返回true,那么哈希值一定相同吗?一定
如果类中定义一个静态变量(static int a = 1),然后重写hashcode返回a+1,那么每一个对象的哈希值都不一样
不过java中规定:对象相等,必须具有相同的哈希码值,所以这里是一定的
1.不包含重复元素
2.set集合没有索引,只能用迭代器或增强for循环遍历
3.set的底层是map集合
方法和Collection的方法基本一样
set接口的实现类HashSet:
1.无序集合
2.可以存入空(null)
3.不可以存在重复元素
示例:
package demo; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class HashSetDemo { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("abc1"); set.add("abc1"); set.add("abc2"); set.add("abc3"); set.add("abc4"); Iterator<String> i1 = set.iterator(); while(i1.hasNext()){ System.out.println(i1.next()); } } } /* 输出: 注意:这里的输出特点是无序的 abc1 abc4 abc2 abc3 */
set底层数据结构是哈希表:
特点:存储取出都比较快
原理:具体省略,简单说就是链表数组结合体
对象的哈希值:普通的一个整数
可以理解为身份证号,是hashset存储的依据
package demo; public class Person {}
package demo; public class HashDemo { public static void main(String[] args) { Person p = new Person(); int i = p.hashCode(); System.out.println(i); //每次运行都会输出不同的整数,比如1191201656 String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.hashCode());//96354 System.out.println(s2.hashCode());//96354 //这里Stirng重写hashcode方法,有对应的计算公式 //当字符串的内容相同时候,运算结果就相同,因此s1和s2的哈希值相同 } }
哈希表存储过程:
1.调用对象的哈希值
2.集合在容器内搜索有没有重复的哈希值,如果没有,存入新元素,记录哈希值
3.再次存储,重复上边的过程
4.如果有重复的哈希值,调用后来者的equals方法,参数为前来者,结果得到true,集合判断为重复元素,不存入
相同的字符串如果存进去,哈希值相同,equals方法为true,不会存入相同的
只要哈希值相同或者equals方法为true都成立才不会存入,只要其中一条不满足,都会储存
哈希表存储自定义对象:
package demo; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return this.name + ":" + this.age; } public Person() { } public Person(String name, int age) { super(); this.name = name; this.age = age; } }
package demo; import java.util.HashSet; public class HashDemo { public static void main(String[] args) { HashSet<Person> setPerson = new HashSet<Person>(); setPerson.add(new Person("a",17)); setPerson.add(new Person("b",20)); setPerson.add(new Person("b",20)); setPerson.add(new Person("c",18)); System.out.println(setPerson); //[c:18, b:20, a:17, b:20] //发现存入了重复的元素 //所以想办法使name和age相同的Person对象视为同一个对象 //所以需要重写hashcode方法 } }
自己重写:
package demo; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return this.name + ":" + this.age; } public Person() { } public Person(String name, int age) { super(); this.name = name; this.age = age; } public int hashCode(){ return name.hashCode()+age*66; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (obj instanceof Person) { Person p = (Person) obj; return name.equals(p.name) && age == p.age; } return false; } }
eclipse可以帮助我们写:
package demo; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return this.name + ":" + this.age; } public Person() { } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
LinkedHashSet集合:基于链表的哈希表实现,继承HashSet,它具有顺序
示例:
package demo; import java.util.LinkedHashSet; public class LinkedHashSetDemo { public static void main(String[] args) { //有序的set LinkedHashSet<Integer> link = new LinkedHashSet<Integer>(); link.add(1); link.add(2); link.add(3); link.add(4); System.out.println(link); //[1, 2, 3, 4] } }
关于hashcode和equals的一些问题,在面试中会问道:
1.两个对象哈希值相同,那么equals方法一定返回true吗?不一定
取决于如何重写equals,如果重写固定了它返回false,结果就一定是false
2.equals方法返回true,那么哈希值一定相同吗?一定
如果类中定义一个静态变量(static int a = 1),然后重写hashcode返回a+1,那么每一个对象的哈希值都不一样
不过java中规定:对象相等,必须具有相同的哈希码值,所以这里是一定的
相关文章推荐
- java学习笔记:集合框架之TreeSet
- Java基础知识强化之集合框架笔记67:Map集合面试题之List,Set,Map等接口是否继承自Map接口
- 13. Java类集 Part 1(类集、Collection接口、List接口、Set接口、SortedSet接口、集合的输出) ----- 学习笔记
- 黑马程序员----Java集合框架学习笔记1-List 与Set
- (32)Java学习笔记——集合框架 / Collection 接口 / Iterator 迭代器
- Java学习笔记30(集合框架四:List接口)
- JavaSE入门学习36:Java集合框架之Set接口及其实现类HashSet和TreeSet
- java学习笔记:集合框架之TreeSet
- java学习日记_85:集合框架之set接口
- java学习笔记集合框架Set集合
- Java学习笔记_22_Set接口的实现类
- 【Java学习笔记】集合框架的学习
- Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashset类,hashcode()与LinkedHashSet类))
- Java集合源码学习(10)_Set接口的实现HashSet
- Java集合源码学习(11)_Set接口的实现LinkedHashSet
- Java学习笔记----------集合Set
- Java学习第14天:集合框架零接触和基本理解(List和Set)
- Java学习笔记_22_Set接口的实现类
- 黑马程序员_JAVA学习日记_JAVA中API:集合框架1(Collection,List,Set及其子类和迭代器的应用)
- 黑马程序员_学习笔记:10) 集合框架2:Set(HashSet、TreeSet)、Map(Hashtable、HashMap、TreeMap)、Collections、Arrays