一、Set集合:
无序、不能出现重复元素、没有角标 的集合
Set的遍历方式:
1、直接打印System.out.println(set);
2、增强for循环foreach
3、迭代器遍历iterator
特点:
无序:Set集合的无序 指的是与元素放入的顺序无关
不能重复:每一个Set子类都有自己的元素查重规则
没有角标:Set和List不一样,List是数组结构的集合
1、子类TreeSet(排序子类集合)
无序:指的是与元素放入的顺序无关,但是输出时的结果是有顺序的,排序的规则是比较器接口
无角标
注意:如果TreeSet放入的元素是引用数据类型(8中基本包装类除外),那么该引用数据类型必须实现比较器接口,自定义比较规则。
TreeSet与Comparable和Comparator两种比较器的结合使用
2、 子类HashSet(散列存放的子类)
特点:
1、无序,与存放的顺序无关,输出的结果也是无序的
2、不允许有重复的元素
注意:HashSet与TreeSet不同之处是,hashSet没有实现比较器接口放入元素时输出也不会报错,因为他有自己的查重规则,调用了只是没有实现
HashSet的查重规则不是实现比较器接口
HashSet实现查重的规则是:
先调用hashCode()方法,再调用equals()方法
先调用hashCode()方法,如果返回值相等,则再调用equals()方法进行对象的各个属性的比较,如果hashCode()返回值不相等,则直接判定两个对象不相等。
问题:为什么是先调用hashCode()后调用equals()方法,这两种方法的内容是怎样的?
回答: hashCode()是Object类中定义的,是返回一个跟对象地址值相关的一串数据(无意义),所以需要我们自己去覆写这个方法赋予我们需要的意义。
先调用hashCode()进行比较更高效,equals()方法是比较对象的具体的属性值是否相等,相对来说效率低,只有hashCode()返回值相等时,再去调用equals()方法。 先比较hashCode方法是为了提高比较效率,后用equals比较 是为了提高比较的准确率
那么我们如果不覆写这两个方法 HashSet不会报错 ,但是也没有实现查重 为什么?
因为如果我们没覆写,那么调用是父类Object的hashCode方法,而Object的hashCode方法返回地址值
只要是新创建出来的对象 地址必然不相等
那么如果地址相等了 hashSet还会去调用equals方法,那么此时我们依然没覆写,调用的是Obejct类的
Object类的equals是进行==比较 比较地址
所以我们必须进行两个方法的合理覆写,定义我们想要比较的规则
TreeSet与HashSet的异同
相同点:
1、元素的存放是无序的
2、没有角标
3、不允许有重复的元素
不同点:
1、HashSet的输出结果是无序的,TreeSet的结果是有序的
2、TreeSet的排序规则是比较器,HashSet的查重规则是覆写调用hashCode()和equals()
3、TreeSet不允许出现空值null,HashSet允许出现null,多个null则视为重复,输出结果只会出现一个
Map集合: 存放的是 键值对
键不可以重复,值可以重复,键一旦重复,值覆盖。
把每一个键值对看成集合的一个元素
Map集合中,键是最主要的,所以一般不用整数来作为键,因为整数没法很好的描述当前值
1、TreeMap
放入无序,结果是有序的(按键的大小排序的),排序规则是实现比较器
键不允许重复,键不允许为 null
遍历方式:
keySet()
将Map集合所有的键存放入Set集合,然后用Set集合的三种遍历方式遍历
entrySet()
将Map集合的键值对封装成Entry对象中,把多个entry对象放入Set集合,然后用Set集合的三种遍历方式遍历
2、HashMap
放入无序,结果无序
键不允许重复,查重规则是hashCode和equals 方法
键允许为 null,值允许为 null
JDK1.2推出 非线程安全集合 效率高
遍历方式:
keySet()
将Map集合所有的键存放入Set集合,然后用Set集合的三种遍历方式遍历
entrySet()
将Map集合的键值对封装成Entry对象中,把多个entry对象放入Set集合,然后用Set集合的三种遍历方式遍历
3、Hashtable
放入而无序,结果无序
键不允许重复,查重规则是hashCode和equals 方法
键不允许为 null 或者 值不允许为 null
JDK1.0推出 线程安全的集合 效率低
多了两种获取所有的键和值的方法 elements()和key()方法
遍历方法:
有特定的枚举器遍历