一、继承Collection接口的set集合接口
- 特点:
- 无序 ,存取不一致的
- 唯一,不能重复数据
- set集合的实现类:HashSet、TreeSet
- 代码用例HashSet继承属性特点:无序、存取不一致
package qf22020301;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Demo01 {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("a");
set.add("w");
set.add("w");
set.add("c");
set.add("d");
set.add("d");
//方式1
for (String obj : set) {
System.out.println(obj);
}
System.out.println("=====================");
//方式2
Iterator<String> itr = set.iterator();
while (itr.hasNext()){
System.out.println(itr.next());
}
}
}
- 代码用例TreeSet特点:有序、存取不一致
package qf22020301;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Demo01 {
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("a");
set.add("w");
set.add("w");
set.add("c");
set.add("d");
set.add("d");
//方式1
for (String obj : set) {
System.out.println(obj);
}
System.out.println("=====================");
//方式2
Iterator<String> itr = set.iterator();
while (itr.hasNext()){
System.out.println(itr.next());
}
}
}
- 结果:
二、实现Set接口的HashSet实现类
- 简介:HashCode 值是根据内存地址生成的一个十进制数,可以被重写,不能根据HashCode值来表示内存地址(引用数据类型一般会重写HashCode值)
- 例子:可以查看String的构造方法,里面重写了HashCode的值,所以String相同内容,其哈希吗值也相等
- 注意:字符串存在哈希值冲突,即内容不同,哈希值相同
三、HashSet唯一特点存储原理分析-红黑树
-
红黑树:
-
特点:
-
数据结构是有Hash表结构进行存储
-
此实现类不是同步的,在多线程中是不安全
-
默认初始容量为16
-
哈希表结构如下图:
-
HashCode唯一特点原理分析
注意:String中,"abc"存储的哈希值一样内容一样,s3,s4 哈希值一样内容不一样
- 例子:把四个对象存放到HashSet集合中,相同属性的对象只存放一个
- 创建一个Person类
package qf22020301.Demo08;
import java.util.Objects;
public class Person {
private Integer age;
private String name;
public Person() {
}
public Person(Integer age, String name) {
this.age = age;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
//把原来比较的包名+类名改成用对象之间的属性进行比较,
//根据hash表数据存储结构:比较顺序为先hashCode再equals
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(age, person.age) &&
Objects.equals(name, person.name);
}
//把原来根据内存地址生成的哈希值重写为用年龄、姓名生成
@Override
public int hashCode() {
return Objects.hash(age, name);
}
}
- 测试类
package qf22020301.Demo08;
import java.util.HashSet;
import java.util.Set;
public class Demo01 {
public static void main(String[] args) {
Set<Person> set = new HashSet<>();
set.add(new Person(20,"小明"));
set.add(new Person(20,"小明"));
set.add(new Person(22,"小红"));
set.add(new Person(22,"小明"));
System.out.println(set);
}
}
- 输出结果
四、实现Set接口的TreeSet实现类
特点:对元素进行排序
-
Comparable 或 Comparator 提供这个两个类来定义比较规则
-
此实现类不是同步的,在多线程中是不安全的
排序规则: -
数值类型是按照升序(从小到大)
-
字符类型是按首个字母的ascmall来进行比较(中文首个字符)
-
自定义数据类型:定义其规则(如根据对象属性),如果没有直接添加则会报错
-
使用Comparable类比较定义规则:
-
定义一个Person类
package qf22020301.Demo09;
public class Person implements Comparable {
private Integer age;
private String name;
public Person() {
}
public Person(Integer age, String name) {
this.age = age;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(Object o) {
Person p = (Person) o;
//根据年龄来排序
//返回值为零时,不加入,这里加判断把它加入
//从小到大排序(本类-传入的类),否则相反
return this.age - p.age == 0 ? 1 : this.age - p.age;
}
}
- 定义一个测试
package qf22020301.Demo09;
import java.util.Set;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
Set<Object> objects = new TreeSet<>();
objects.add(new Person(20,"小明"));
objects.add(new Person(80,"小李"));
objects.add(new Person(23,"小明"));
objects.add(new Person(73,"小王"));
System.out.println(objects);
}
}
- 结果:
- Comparator类比较定义规则:
- 定义一个Person类
package qf22020301.Demo09;
public class Person {
private Integer age;
private String name;
public Person() {
}
public Person(Integer age, String name) {
this.age = age;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
- 测试
package qf22020301.Demo09;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
Set<Person> objects = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
//根据年龄从大到小排序
return o2.getAge() - o1.getAge();
}
});
objects.add(new Person(20, "小明"));
objects.add(new Person(80, "小李"));
objects.add(new Person(23, "小明"));
objects.add(new Person(73, "小王"));
System.out.println(objects);
}
}
- 结果:
五、继承于HashSet类与实现Set接口的LinkedHashSet实现类
特点:
-
具有可预知迭代顺序的Set接口的Set的哈希表和链接列表的实现
-
数据结构hash表+双链表
-
具有有序,并且唯一性,有序是值存取时的位置和值一样
-
此实现类不是同步的,所以是多线程不安全
-
例子:
package qf22020302.Demo01;
import java.util.HashSet;
import java.util.LinkedHashSet;
public class Demo01 {
public static void main(String[] args) {
HashSet<Object> lhs = new LinkedHashSet<>();
lhs.add(1);
lhs.add(45);
lhs.add(2);
lhs.add(778);
System.out.println(lhs);
System.out.println("===================");
lhs.clear();
lhs.add("a");
lhs.add("h");
lhs.add("b");
lhs.add("e");
System.out.println(lhs);
}
}
- 结果
六、Map顶级集合接口
特点:
- 将键映射到值的对象
- 一个映射不能包含重复的键:每个键最多只能映射到一个值
- 不是同步的,在多线程不安全的
实现类: - TreeMap 有序 HashMap无序 (解释:有序是值存取的位置(key)不变,无序是值存取的位置(key)可能变了)
七、实现Map接口的HashMap实现类
- 单列集合与双列集合的比较
- 单列集合的数据结构针对的是元素
- 双列集合,键值来进行映射,数据结构针对的是键(键是唯一的