Set : 无序,不可重复|去重
无序: 存放的顺序与内部真实存储的顺序不一致去重: 集合不包含元素对e1和e2 ,使得e1.equals(e2)和最多一个null元素。 1.2 新增功能
static Set of(E… elements) 返回包含任意数量元素的不可修改集。 1.3 遍历方式
foreachiterator迭代器 1.4 代码
public class Class001_Set {
public static void main(String[] args) {
Set set = new HashSet<>();
set.add("ddd");
set.add("aaa");
set.add("ccc");
set.add("bbb");
set.add("bbb");
set.add("bbb");
set.add(null);
set.add(null);
set.add(null);
System.out.println(set);
System.out.println("----------foreach--------------");
for(String str:set){
System.out.println(str);
}
System.out.println("----------iterator迭代器--------------");
Iterator it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
2 TreeSet
2.1 底层结构
红黑树底层是由TreeMap维护的,本质是TreeMap 2.2 特点
查询效率较高,自动把数据做升序排序 2.3 新增功能
新增了一些与比较大小相关的方法E ceiling(E e) 返回此set中大于或等于给定元素的 null元素,如果没有这样的元素,则 null 。E floor(E e) 返回此set中小于或等于给定元素的最大元素,如果没有这样的元素,则 null 。E first() 返回此集合中当前的第一个(最低)元素。E last() 返回此集合中当前的最后一个(最高)元素。E higher(E e) 返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则 null 。E lower(E e) 返回此集合中的最大元素严格小于给定元素,如果没有这样的元素,则 null 。E pollFirst() 检索并删除第一个(最低)元素,如果此组为空,则返回 null 。E pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 2.4 遍历方式
foreachiterator迭代器 2.5 注意
TreeSet需要存储相同类型的数据,因为会默认存在比较排序 2.6 代码
public class Class002_TreeSet {
public static void main(String[] args) {
TreeSet tree = new TreeSet();
tree.add(3.2);
tree.add(2.2);
tree.add(5.2);
tree.add(1.2);
tree.add(.2);
System.out.println(tree);
TreeSet tree2 = new TreeSet();
tree2.add("bc");
tree2.add("ab");
tree2.add("a");
tree2.add("abc");
System.out.println(tree2);
//E ceiling(E e) 返回此set中大于或等于给定元素的 null元素,如果没有这样的元素,则 null 。
System.out.println(tree.ceiling(2.3));
//E floor(E e) 返回此set中小于或等于给定元素的最大元素,如果没有这样的元素,则 null 。
System.out.println(tree.floor(2.3));
//E first() 返回此集合中当前的第一个(最低)元素。
System.out.println(tree.first());
//E last() 返回此集合中当前的最后一个(最高)元素。
System.out.println(tree.last());
//E higher(E e) 返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则 null 。
System.out.println(tree.higher(2.2));
//E lower(E e) 返回此集合中的最大元素严格小于给定元素,如果没有这样的元素,则 null 。
System.out.println(tree.lower(2.3));
//E pollFirst() 检索并删除第一个(最低)元素,如果此组为空,则返回 null 。
//E pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 。
System.out.println(tree.pollFirst());
System.out.println(tree);
System.out.println(tree.pollLast());
System.out.println(tree);
}
}
3 比较器
TreeSet存储javabean类型的数据
去重与排序: 都是根据比较规则实现的,与equals没有关系比较规则:
内部比较器|内部比较规则|自然排序 : 比较规则定义在javabean类型的内部
javabean类型实现Comparable接口,重写compareTo(T o)方法,在方法中定义比较规则外部比较器|外部比较规则|定制排序 : 比较规则定义在javabean类型的外部
定义一个实现类,实现Comparator接口,重写int compare(T o1, T o2),在方法中定义比较规则 Arrays.sort(数组) 默认升序排序
static void sort(T[] a, Comparator super T> c) 根据指定比较器引发的顺序对指定的对象数组进行排序。
练习: 定义一个存储javabean数据的数组,通过 Arrays.sort对数据做升序排序
3.1 员工类
定义自然排序方式
两个对象 e1,e2
e1.compareTo(e2)
大小由返回值决定 :
0 ---------> e1==e2
<0 --------> e1
但是可以根据自定义的比较方式的实现,真实的实现根据指定内容升序|降序
//员工类 public class Employee implements Comparable3.2 内部比较器{ private int id; private String name; private double salary; public Employee() { } public Employee(int id, String name, double salary) { this.id = id; this.name = name; this.salary = salary; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + ''' + ", salary=" + salary + '}'; } @Override public int compareTo(Employee o) { //e1-->this e2-->o //return this.name.compareTo(o.name); return this.id-o.id; } }
public static void main(String[] args) {
TreeSet tree = new TreeSet<>();
tree.add(new Employee(02,"zhangsan",10000));
tree.add(new Employee(01,"lisi",12000));
tree.add(new Employee(03,"wangwu",8000));
System.out.println(tree);
}
3.3 外部比较器
调用compare方法做两个数据的比较
compare(t1,t2)
返回值:
=0 t1==t2
<0 t1
public class Class003_Comparable {
public static void main(String[] args) {
//TreeSet tree = new TreeSet<>(); //根据Employee默认比较规则,自然排序方式做比较排序
//TreeSet(Comparator super E> comparator) 构造一个新的空树集,根据指定的比较器进行排序。
//TreeSet tree = new TreeSet<>(new Test());
//匿名内部类 : 简化没有类自己作用的实现类
Comparator com = new Comparator() {//实现类的类体
@Override
public int compare(Employee o1, Employee o2) {
return Double.compare(o1.getSalary(),o2.getSalary());
}
};
//Lambda : 简化匿名内部类对象,要求必须为函数式接口才能简化
//com = (o1,o2)->o1.getId()-o2.getId();
//TreeSet tree = new TreeSet<>(com);
//lambda表达式作为实参传递 -> 可以把行为作为参数传递
TreeSet tree = new TreeSet<>((o1,o2)->o1.getId()-o2.getId());
tree.add(new Employee(02,"zhangsan",10000));
tree.add(new Employee(01,"lisi",12000));
tree.add(new Employee(03,"wangwu",8000));
System.out.println(tree);
}
}
//外部比较器
class Test implements Comparator{
@Override
public int compare(Employee o1, Employee o2) {
return Double.compare(o2.getSalary(),o1.getSalary());
}
}
3.4 练习
public static void main(String[] args) {
ArrayList emp = new ArrayList<>();
emp.add(new Employee(02,"zhangsan",10000));
emp.add(new Employee(01,"lisi",12000));
emp.add(new Employee(03,"wangwu",8000));
Collections.sort(emp);
System.out.println(emp);
}
4 HashSet
4.1 List与Set
List 有序 可重复Set 无序 不可重复
TreeSet : 默认升序排序 4.2 底层结构
哈希表(数组+链表+红黑树)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IxtCldrU-1647995516255)(E:program安装资料笔记工具MarkdownPictures容器集合哈希表.png)]
4.3 特点查询,增删效率高 ,去重,无序底层是由HashMap维护的 4.4 遍历
foreachiterator迭代器 4.5 新增方法
无 4.6 注意
此类允许null元素。请注意,此实现不同步。 4.7 练习
定义HashSet存储javabean类型得到数据,实现去重,测试使用去重 : 数据的类型要求重写hashCode与equals方法,返回地址值需要重写toString 4.8 代码
public class Class004_HashSet {
public static void main(String[] args) {
System.out.println("abc".hashCode());
System.out.println(new Person("zhangsan",18).hashCode());
System.out.println(new Person("zhangsan",18).hashCode());
System.out.println(new Integer(105).hashCode());
HashSet set = new HashSet();
set.add("");
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
4.9 练习代码
public class Class004_HashSet {
public static void main(String[] args) {
System.out.println("abc".hashCode());
System.out.println(new Person("zhangsan",18).hashCode());
System.out.println(new Person("zhangsan",18).hashCode());
System.out.println(new Integer(105).hashCode());
Set set = new HashSet();
set.add("张三");
set.add("张三");
Person p1 = new Person("张三",18);
Person p2 = new Person("张三",18);
Person p3 = new Person("李四",18);
HashSet set1 = new HashSet<>();
set1.add(p1);
set1.add(p2);
set1.add(p3);
System.out.println(set1);
for(Person p :set1){
System.out.println(p);
}
System.out.println(set);
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
第二章 Map
1 Map
1.1 理解
Map : 无序的,去重的键值对数据的集合键值对->映射关系键值对: K-VK键 : 无序的,去重的|唯一的 —> SetV值 : 无序的,可重复 —> CollectionK-V可以为任意引用数据类型 1.2 特点
一个key只能对应一个Valuekey相同value覆盖 1.3 遍历方式
values 获取所有键值对的值 底层: 红黑树存储键值对类型的数据,自动升序排序,去重的去重,排序: 根据键值对的key实现,与value本身无关TreeSet底层是由TreeMap请注意,此实现不同步。
2.2 练习
测试: 使用TreeMap存储键值对数据,key要求为javabean类型教师数据,value存储教授学科,测试存储练习 根据key的类型的比较规则 基于哈希表的Map接口的实现。 此实现提供了所有可选的映射操作,并允许null值和null键。HashSet 底层是由HashMap底层结构 : 哈希表(数组+链表+红黑树)
3.2 哈希表
3.2.1 理解
数组 : 节点数组Node[] --> 要求数组的长度为2的整数次幂 哈希表中的数组默认的初始长度 16 0.75 一般不建议改变默认加载因子 : static final float DEFAULT_LOAD_FACTOR = 0.75f;
3.2.4 扩容阀值 threshold
扩容的临界值 数据的个数size>数组的长度*加载因子 就会扩容
3.2.5 扩容机制
原容量的2倍 int newCap = oldCap << 1
3.2.6 新增功能:
无
3.2.7 HashMap的哈希表存储数据的过程
根据key计算哈希值 调用putVal方法实现添加数据(hash,key,value) 去重 : 根据key做去重,要求key的数据类型重写hashCode与equals方法
3.2.9 练习
测试: 定义HashMap存储数据,要求key为javabean,实现去重与测试
3.2.10 练习代码
共同点 : 都是Map接口的实现类,底层结构都是哈希表 异同点 : 5.计算hash值与位桶索引index的算法不同 如何处理HashMap线程不安全问题: 操作集合的工具类静态工厂
2 方法
void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。void shuffle(List) //对List容器内的元素进行随机排列void reverse(List) //对List容器内的元素进行逆续排列void fill(List, Object) //用一个特定的对象重写整个List容器int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象
3 代码
Collection values() 返回此映射中包含的值的Collection视图。keySet 获取所有键值对的key,根据key获取value
Set keySet() 返回此映射中包含的键的Set视图。entrySet 获取所有的键值对,每一个键值对都是一个Entry类型->表示一个键值对
Setpublic class Class001_Map {
public static void main(String[] args) {
Map
2 TreeMap
2.1 理解
是否可以根据key实现去重
测试是否为升序排序,要求根据教师编号做升序排序
2.3 去重|排序
key的数据类型实现内部比较器
传递外部比较规则
2.4 代码
public class Class002_TreeMap {
public static void main(String[] args) {
//TreeMap
3 HashMap
3.1 HashMap
Node : int hash,Object key,Object value,Node next每个索引位置存储的为一个单向链表的首节点(尾插法)当链表的长度>8,数组的长度>64,会把链表优化成为红黑树当链表的长度>8,但是数组的长度不大于64,这时候会实现扩容(数组的扩容)
3.2.2 初始容量
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16数组的容量最大容量 : static final int MAXIMUM_CAPACITY = 1 << 30;
3.2.3 加载因子
通过key的hashCode方法的返回值进一步进行hash算法的运算,得到的整数
int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
1)判断是否是第一次调用put方法做添加 if ((tab = table) == null || (n = tab.length) == 0)
如果是第一次添加,直接调用resize()实现扩容
2)计算位桶的索引 int index = (n - 1) & hash
3)判断哈希表结构的数组table[index]是否存在数据,
如果不存在数据,证明没有头节点,创建新节点,放入当前数组的对应索引位置作为头节点
table[index] = new Node<>(hash, key, value, next);
size数据的个数+1,判断是否>扩容的阀值,如果大于需要调用resize方法进行扩容,如果不大于,不需要扩容直接返回null
if (++size > threshold) resize();
return null;
如果存在数据,作为链表的头结点,遍历这个链表,拿到每一个节点的key与hash值判断是否与要添加的key和hash相同,如果相同,value覆盖
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
value覆盖之后,返回被覆盖的value
V oldValue = e.value;
e.value = value;
return oldValue;public class Class003_HashMap {
public static void main(String[] args) {
HashMap
3.3 Hashtable 与 HashMap
3.3.1 区别
1.继承体系不同
2.线程是否安全不同
HashMap 线程不安全|不同步
Hashtable 线程安全的|同步的
3.扩容机制不同
HashMap扩容机制 : 每次扩容原容量的2倍
int newCap = oldCap << 1
Hashtable扩容机制 : 原容量的2倍+1
int newCapacity = (oldCapacity << 1) + 1;
4.键值对数据null值的要求不同
HashMap 可以存储null值的key与value
Hashtable key与value都不为null
HashMap :
int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
int index = (n - 1) & hash
Hashtable :
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
1.使用Hashtable
2.使用Collections工具类中static
3.juc高级并发编程包 ConcurrentHashMappublic class Class001_Collections {
public static void main(String[] args) {
List



