集合框架
1:集合:(1) Collection(单列集合)List(有序,可重复)ArrayList底层数据结构是数组,查询快,增删慢 线程不安全,效率高Vector 底层数据结构是数组,查询快,增删慢 线程安全,效率低LinkedList 底层数据结构是链表,查询慢,增删快 线程不安全,效率高Set(无序,唯一)HashSet 底层数据结构是哈希表。 哈希表依赖两个方法:hashCode()和equals()
LinkedHashSet底层数据结构由链表和哈希表组成。 由链表保证元素有序。 由哈希表保证元素唯一。TreeSet 底层数据结构是红黑树。(是一种自平衡的二叉树) 如何保证元素唯一性呢? 根据比较的返回值是否是0来决定 如何保证元素的排序呢? 两种方式 自然排序(元素具备比较性) 让元素所属的类实现Comparable接口 比较器排序(集合具备比较性) 让集合接收一个Comparator的实现类对象
(2)Map(双列集合)A:Map集合的数据结构仅仅针对键有效,与值无关。 B:存储的是键值对形式的元素,键唯一,值可重复。 HashMap 底层数据结构是哈希表。线程不安全,效率高 哈希表依赖两个方法:hashCode()和equals() 执行顺序: 首先判断hashCode()值是否相同 是:继续执行equals(),看其返回值 是true:说明元素重复,不添加 是false:就直接添加到集合 否:就直接添加到集合 最终: 自动生成hashCode()和equals()即可 LinkedHashMap 底层数据结构由链表和哈希表组成。 由链表保证元素有序。 由哈希表保证元素唯一。Hashtable 底层数据结构是哈希表。线程安全,效率低 哈希表依赖两个方法:hashCode()和equals() 执行顺序: 首先判断hashCode()值是否相同 是:继续执行equals(),看其返回值 是true:说明元素重复,不添加 是false:就直接添加到集合 否:就直接添加到集合 最终: 自动生成hashCode()和equals()即可TreeMap 底层数据结构是红黑树。(是一种自平衡的二叉树) 如何保证元素唯一性呢? 根据比较的返回值是否是0来决定 如何保证元素的排序呢? 两种方式 自然排序(元素具备比较性) 让元素所属的类实现Comparable接口 比较器排序(集合具备比较性) 让集合接收一个Comparator的实现类对象
2:到底使用那种集合:是否是键值对象形式:是:Map键是否需要排序:是:TreeMap否:HashMap 不知道,就使用HashMap。
否:Collection元素是否唯一:是:Set元素是否需要排序:是:TreeSet否:HashSet 不知道,就使用HashSet否:List要安全吗:是:Vector否:ArrayList或者LinkedList增删多:LinkedList 查询多:ArrayList 不知道,就使用ArrayList不知道,就使用ArrayList
Collection接口
Collection 层次结构 中的根接口,单列集合。存储的对象。
目标: Collection集合概述。
什么是集合?
集合是一个大小可变的容器。
容器中的每个数据称为一个元素。数据==元素。
集合的特点是:类型可以不确定,大小不固定。集合有很多种,不同的集合特点和使用场景不同。
数组:类型和长度一旦定义出来就都固定了。
集合有啥用?
在开发中,很多时候元素的个数是不确定的。
而且经常要进行元素的增删改查操作,集合都是非常合适的。
开发中集合用的更多!!
Java 中集合的代表是: Collection.
Collection集合是Java中集合的祖宗类。
学习Collection集合的功能,那么一切集合可以用这些功能!!
集合的特点:
set系列集合,添加的元素是无序,不重复,无索引的。
—— HashSet: 添加的元素是无序,不重复,无索引的。
—– LinkedHashSet: 添加的元素是有序,不重复,无索引的。
—– TreeSet:不重复,无索引,按照大小默认升序排序!!
List系列集合: 添加的元素是有序,可重复,有索引。
—— ArrayList: 添加的元素是有序,可重复,有索引。
—– LinekdList: 添加的元素是有序,可重复,有索引。
小结:
Collection是集合的祖宗类,Collection集合的功能时一切集合都可以直接使用的。
数组与集合
1.数组可以存储任意数据类型,可以存储基本数据类型也可以存储引用数据类型。 只能存储同一种。
并且在一开始的时候,长度就固定了。对于数组增删操作时,移动的位置会多。
2.集合实质是对数组的一个补充,集合中可以存储任意数据类型的对象。但是不能存储基本数据类型
的数值的,提供了方法,对数据的crud,进行便捷操作。
3.无论是数组还是集合,都是用来存储数据的容器。
集合创建对象
1.Collection 集合体系:
2.集合是一个接口。必须通过子类来创建对象。
构造方法:
① ArrayList()
3.集合常用方法:
① add(E e) 添加
② addAll(Collection< ? extends E> c) 将一个集合中的元素添加到另一个集合。
③ clear() 清除
④ contains(Object o) 判断包含
注意:
判断结果取决于参数的equals方法。对于自定义类来说,要重写equals方法,达到按需求返回true的目的。
代码
package com.demo;
import java.util.ArrayList;
import java.util.Collection;
/**
1.Collection 集合体系:
2.集合是一个接口。必须通过子类来创建对象。
构造方法:
① ArrayList()
3.集合常用方法:
① add(E e) 添加
② addAll(Collection<? extends E> c) 将一个集合中的元素添加到另一个集合。
③ clear() 清除
④ contains(Object o) 判断包含
注意:判断结果取决于参数的equals方法。对于自定义类来说,要重写equals方法,达到按 需求返回true的目的。
*/
public class Collection集合 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(true);//Boolean
c.add(123);// Integer
c.add("abc");
c.add(new Person("张三",19));
Collection c1 = new ArrayList();
// ② addAll(Collection<? extends E> c) 将一个集合中的元素添加到另一个集合。
// c1.addAll(c);
// ③ clear() 清除
// c.clear();
// ④ contains(Object o) 判断包含
// System.out.println(c.contains(1234));
System.out.println(c.contains(new Person("张三",19)));
}
}
class Person{
String name;
int age;
public Person() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Collection
常用方法
1.remove(Object o) 移除 单个元素,多个重复元素,每次只能删除一个
2.size() 相当于length 表示集合中元素个数
3.toArray() 集合转数组 ,返回值的数据类型 Object
代码
package com.demo;
import java.util.ArrayList;
import java.util.Collection;
/**
1.remove(Object o) 移除 单个元素,多个重复元素,每次只能删除一个
2.size() 相当于length 表示集合中元素个数
3.toArray() 集合转数组 ,返回值的数据类型 Object */
public class 集合常用方法 {
public static void main(String[] args) {
Collection c = new ArrayList();
//isEmpty() 判断集合是否为空元素集合,如果是返回true
// System.out.println(c.isEmpty());
c.add(1);
c.add(2);
c.add(3);
c.add(4);
c.add(2);
/* System.out.println(c);
for (int i = 0; i < c.size(); i++) {
c.remove(2);
}System.out.println(c);*/
Object[] arr = c.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
迭代器
1.Iterator :迭代器
① hasNext():判断该位置是否还有集合元素
② next() :返回该集合元素
③ remove() : 删除集合元素
2.获取迭代器的方式:
① iterator()
3.NoSuchElementException 没有该元素异常 ,发生于集合中没有元素,但是通过next方法获取时。
4.建议:
迭代器额hasNext与next方法一配一使用。
代码
package com.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
1.数据操作 :crud 增删改查。
2.Iterator :迭代器
① hasNext():判断该位置是否还有集合元素
② next() :返回该集合元素
③ remove() : 删除集合元素
3.获取迭代器的方式:
① iterator()
4.NoSuchElementException 没有该元素异常 ,发生于集合中没有元素,但是通过next方法获取 时。
*/
public class 迭代器 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(1);
c.add("abc");
c.add(true);
c.add('我');
//获取 集合中某个位置的元素 "abc" 遍历
Iterator it = c.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
并发修改异常
1.集合删除元素:
① remove(obj) 集合的删除方法 删除单个元素
② remove() 迭代器的删除
\2. 并发修改异常:ConcurrentModificationException
原因:
当使用集合进行类似于迭代器的遍历时,如果在遍历的过程中,对集合进行了增删操作,就会报该异常。
必须使用迭代器自身的删除方法,才不会有问题。
代码
package com.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
1.集合删除元素:
① remove(obj) 集合的删除方法 删除单个元素
② remove() 迭代器的删除
2. 并发修改异常:ConcurrentModificationException
原因:当使用集合进行类似于迭代器的遍历时,如果在遍历的过程中,对集合进行了增删操作,就会报该异常。
必须使用迭代器自身的删除方法,才不会有问题。 */
public class 集合元素删除的方式 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(1);
c.add(2);
c.add(3);
c.add(4);
c.add(5);
Iterator it = c.iterator();
while (it.hasNext()){
Object obj = it.next();
//删除值为3 的元素
if (obj.equals(3)){
it.remove();
// c.remove(3); //建议使用迭代器自身的删除方法而不是集合的删除方法
}
}
System.out.println(c);
}
}
集合的泛型
1.引入泛型:
检测数据类型是否符合要求。
2.格式:
集合的数据类型<要存储的数据类型>
3.集合泛型:
① 将运行期的类型转换异常转变成编译期的异常,提高了程序的健壮性。
② 避免了向下转型。
4.泛型的特点:
① 可擦除技术:泛型只存在编译期,class文件中不存在。
② 菱形技术:1.6必须只能new后的集合对象的泛型的数据类型,但是1.7之后,有了类型推断,根据前面的泛型,可以推导后面的泛型,省略不写。
代码
package com.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
1.引入泛型:
检测数据类型是否符合要求。
2.格式:
集合的数据类型<要存储的数据类型>
3.集合泛型:
① 将运行期的类型转换异常转变成编译期的异常,提高了程序的健壮性。
② 避免了向下转型。
4.泛型的特点:
① 可擦除技术:泛型只存在编译期,class文件中不存在。
② 菱形技术:1.6必须只能new后的集合对象的泛型的数据类型,但是1.7之后,有了类型推断,根据前面的泛型,可以推导后面的泛型,省略不写。
*/
public class 集合的泛型 {
public static void main(String[] args) {
Collection<Student> c = new ArrayList<>();//菱形技术。省略不写泛型的数据类型。
c.add(new Student("张三", 19));
c.add(new Student("李思", 19));
// c.add(1);
// c.add("abc");
// c.add(true);
//使用集合判断如果是学生对象,就调用study方法。
/*Iterator it = c.iterator();
while (it.hasNext()){
Object obj = it.next();
if ( obj instanceof Student){
Student st = (Student) obj;
st.study();
}
}*/
//带有泛型的形式
Iterator<Student> it = c.iterator();
while (it.hasNext()){
Student st = it.next();
System.out.println(st.name);
}
}
}
class Student {
String name;
int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void study(){
System.out.println("goodgoodstudy");
}
}
List集合
概述
1.有序的集合:
有序:插入与存储顺序相同
(***) 2.List集合特点:
有序 可重复 可插入null
3.List集合可以通过索引访问集合中的元素。
4.常用方法:
① add(int index, E element) 根据index 添加元素
注意:
第一个参数index有范围,从[0,size]范围为止。
(***)② get(int index) 返回index位置的元素
(***)③ listIterator()/listIterator(int index) 获取List集合特有的迭代器
1》 hasPrevious() 向上判断是否存在元素
2》 previous() 获取元素值
④ remove(int index) /remove(Object o) 删除索引/对象元素
注意:
如果是数值,认为是index索引值,如果是想通过数值对象删除,必须通过new操作创建对象。
⑤ set(int index, E element) 修改
代码
package com.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
/**
1.有序的集合:
有序:插入与存储顺序相同
(***) 2.List集合特点:
有序 可重复 可插入null
3.List集合可以通过索引访问集合中的元素。
4.常用方法:
① add(int index, E element) 根据index 添加元素
注意:
第一个参数index有范围,从[0,size]范围为止。
(***)② get(int index) 返回index位置的元素
(***)③ listIterator()/listIterator(int index) 获取List集合特有的迭代器
1》 hasPrevious() 向上判断是否存在元素
2》 previous() 获取元素值
④ remove(int index) /remove(Object o) 删除索引/对象元素
注意:
如果是数值,认为是index索引值,如果是想通过数值对象删除,必须通过new操作创建对象。
⑤ set(int index, E element) 修改
*/
public class List集合 {
public static void main(String[] args) {
List<Integer> c = new ArrayList<>();
c.add(1);
c.add(5);
c.add(2);
c.add(7);
System.out.println(c);
// ① add(int index, E element) 根据index 添加元素
// c.add(5, 15);
// (***)② get(int index) 返回index位置的元素
// System.out.println(c.get(2));
// ③ listIterator() 获取List集合特有的迭代器
/* ListIterator<Integer> it = c.listIterator(c.size());
*//*while(it.hasNext()){
System.out.println(it.next());
}*//*
while(it.hasPrevious()){
System.out.println(it.previous());
}*/
// ④ remove(int index) /remove(Object o) 删除索引/对象元素
//删除数值为5的元素
// c.remove(new Integer(5));
// ⑤ set(int index, E element) 修改
c.set(1, 17);
System.out.println(c);
}
}
ArrayList集合
概述
(***)1.ArrayList 底层:List 接口的大小可变数组的实现
2.ArrayList 特点: 有序 可重复 可存储null
3.构造方法:
① ArrayList() 初始容量为10的数组
② ArrayList(Collection< ? extends E> c)
代码
package com.demo;
import java.util.ArrayList;
/**
(***)1.ArrayList 底层:List 接口的大小可变数组的实现
2.ArrayList 特点: 有序 可重复 可存储null
3.构造方法:
① ArrayList() 初始容量为10的数组
② ArrayList(Collection<? extends E> c)
*/
public class ArrayList集合 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
System.out.println(list);
list.add("abc");
list.add("def");
ArrayList<String> list1 = new ArrayList<>(list);
System.out.println(list1);
}
}
集合的遍历方式
1.集合的遍历方式:
① 迭代器: Iterator : hasNext next 单列集合通过
② List下特有的接口:只能List集合使用 ListIterator
③ for循环 :只适用于List集合
④ 转数组 toArray()单列集合通过
(***) ⑤ 增强for循环 底层原理:迭代
格式:
for(变量的数据类型 变量的名称: 整体的名称){
}
代码
package com.demo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
/**
1.集合的遍历方式:
① 迭代器: Iterator : hasNext next 单列集合通过
② List下特有的接口:只能List集合使用 ListIterator
③ for循环 :只适用于List集合
④ 转数组 toArray()单列集合通过
(***) ⑤ 增强for循环 底层原理:迭代
格式:
for(变量的数据类型 变量的名称: 整体的名称){
}
*/
public class 集合的遍历方式 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// ① 迭代器: Iterator : hasNext next
/* Iterator<Integer> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}*/
// ② List下特有的接口:只能List集合使用 ListIterator
/*ListIterator<Integer> listIt = list.listIterator(list.size());
while (listIt.hasPrevious()){
System.out.println(listIt.previous());
}*/
// ③ for循环 只适用于List集合
/* for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}*/
// ④ 转数组 toArray()单列集合通过
/* Object[] arr = list.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
*/
// ⑤ 增强for循环
/* for (Integer it:list) {
System.out.println(it);
}*/
int[] arr2 = {1,2,3,4,5,6};
for(int i:arr2){
System.out.println(i);
}
}
}
LinkedList
结构
(***)
1.ArrayList与LinkedList的区别?
ArrayList底层是大小可变的数组的实现,查询快 增删慢。线程不安全
LinkedList底层是双向链表的实现,增删快 ,查询慢。线程不安全。
2.LinkedList可以当做堆栈、队列或双端队列。
队列: 先进先出
栈: 先进后出。
原理
1.底层: 双向链表
2.特点: 有序 可重复 可以插入null
代码
package com.demo;
import java.util.LinkedList;
/**
(***) 1.底层: 双向链表
2.特点: 有序 可重复 可以插入null
*/
public class LinkedList集合 {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
}
}
Vector
用法用Arraylist。该集合是线程安全的,如果需要使用线程安全的集合,可以采用Vector。
单列集合的体系结构和它们之间的区别
List:其中List的集合查询快,增删慢,原因是因为List的存储的结构是数组结构。
**而List下的_LinkList_**的集合查询慢,增删快。原因是 Linklist的存储结构是链表。在其中有大量操作收尾元素的方法,不过使用其特有的方法时不能使用多态。
Set:在Set中不能有重复元素。没有索引,不能使用普通for循环遍历。是一个无序的集合,储存元素和取出元素的顺序很有可能不一致。底层是一个哈希表结构,查询速度很快。
Set下的_HashSet_:首先要明白哈希值。是系统模拟的地址,而不是真实的地址,不同对象的哈希值不一样,如果对求哈希值的方法进行重写,那么就能使哈希值相同。String下的所有哈希值是一样的。JDK1.8之后,底层是数组加链表/红黑,如果链表的长度超过8位就会转换为红黑树。
HashSet不能存储重复元素的原理: Set集合在调用add方法的时候,add方法会调用元素的hashcode方法和equals方法。如果没有相同的哈希值,就放入集合,如果相同就调用equals方法。返回true就不会存储集合中。
(equals默认比较两个对象地址值,自定义上的类型一定要重写hashcode方法和equals方法)
Set下的_LinkedHashSet_:LinkedHashSet继承了HashSet,比HashSet多了一条链表(记录元素的存储数据),保证元素有序。也不允许重复。
Set集合
概述
Set集合特点: 不重复,只能存储一个null
HashSet
1.特点:无序 不重复,只能存储一个null
2.构造方法: HashSet() 初始容量是16
3.底层: 哈希表 ()
4.如何对自定义类的对象的存储进行去重复: 重写hashCode和equals。
5.HashSet存储原理: ① hashCode() ② equals
① 将存储到集合中的元素,调用该元素的hashCode方法,算出哈希码值,然后根据哈希算法,换 算出在哈希表中的位置,如果该位置没有元素,直接插入。
② 如果该位置有元素,这种现象称为哈希碰撞也叫哈希冲突。发生了这种情况,调用equals方法 进行判断,如果返回值为false,在该索引位置下以链表的形式插入。
③ 如果发生了哈希冲突之后,调用equals方法判断结果为true。此时不插入。
6.HashSet存储细节问题:
① 发生哈希冲突插入形式:
1》 1.7jdk以前 ,头插法
2》 1.8jdk之后 ,尾插法
2.哈希桶存储元素:
1.7之前 采用链表的形式。
1.8之后 采用链表 + 红黑树的形式
阈值是8 ,当链表长度超过8的时候,从链表转换成红黑树。
阈值小于5,红黑树转链表。
3.加载因子:
当哈希桶容量*加载因子超过这个数值时,就扩容。
注意:
扩容还是转树不是必然的,不是硬性超过阈值为8 就转。需要看扩容和转树哪个性能更好,哪个好转哪个。
红黑树
红黑树(Red Black Tree) 是一种自平衡二叉查找树
二叉树:
二叉查找树:
特点:
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。
总结:
左小右大,没有相等
TreeSet集合
概述
(***)TreeSet底层: 基于红黑树的TreeMap集合。
(***)TreeSet的特点: 无序 不重复 可存储一个null 可排序
1.注意:
① 使用TreeSet()构造方法时,默认会使用元素的自然顺序比较器,如果存储在该集合中的类
没有实现Comparable该接口,
会报ClassCastException类型转换异常。
② TreeSet集合在进行存储时,会自动调用ComparaTo方法进行判断,根据 >0 <0 ==0的结
果进行插入。
如果等于0 不插入。
2.TreeSet利用比较器进行比较的,如果自定义类去重,不需要重写hashCode和equals。
第三方比较器
概述
1.TreeSet(Comparator< ? super E> comparator)
2.Comparator :
第三方比较器 :
compare(T o1, T o2)
相当于 compareTo方法中的:this相当于o1 o 相当于o2.
3.当存在第三方比较器时,根据就近原则,第三方比较器优先有效。
代码
package com.demo;
import java.util.Comparator;
import java.util.TreeSet;
/**
1.TreeSet(Comparator<? super E> comparator)
2.Comparator :第三方比较器 :
compare(T o1, T o2)
相当于 compareTo方法中的:this相当于o1 o 相当于o2.
3.当存在第三方比较器时,根据就近原则,第三方比较器优先有效。
*/
public class 第三方比较器 {
public static void main(String[] args) {
TreeSet<Person> set = new TreeSet<>(new NameComparator());
set.add(new Person("zs", 19));
set.add(new Person("ls", 20));
System.out.println(set);
}
}
class NameComparator implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
return o1.name .compareTo(o2.name);
}
}
class Person implements Comparable<Person>{
String name;
int age ;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age -o.age;
}
}
LinkedHashSet
概念
(***)底层: 哈希表和双向链表组成。
(***)特点: 有序 不重复 可以存储一个null
场景:
购物车 商品历史浏览记录
Map
Map
双列集合:
Map<K,V>
将键映射到值的对象。一个映射不能包含重复的键;键与值是一一对应的关系,键不能重复,但是值可
以重复。
1.Map集合常用方法:
① put(key,value) 将键值对添加到集合 add方法。
注意:
键如果重复,会覆盖原有的值,并且将原有的值返回。
② containsKey(Object key) /containsValue(Object value) 包含
注意:
自定义类的对象需要重写hashCode和equals
(***)③ get(Object key) 通过key获取value
④ Collection
2.Map对象的创建 :
① HashMap() 创建初始容量为16,加载因子0.75
代码
package com.demo;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
1.Map集合常用方法:
① put(key,value) 将键值对添加到集合 add方法。
注意:
键如果重复,会覆盖原有的值,并且将原有的值返回。
② containsKey(Object key) /containsValue(Object value) 包含
注意:
自定义类的对象需要重写hashCode和equals
(***)③ get(Object key) 通过key获取value
④ Collection<V> values() 获取值的集合。
2.Map对象的创建 :
① HashMap() 创建初始容量为16,加载因子0.75
*/
public class Map集合的常用方法 {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("一", 1);
map.put("二", 2);
map.put("三", 3);
System.out.println(map);
/*Integer it = map.put("三", 5);
System.out.println(it);*/
// ② containsKey(Object key) /containsValue(Object value) 包含
// System.out.println(map.containsKey("二"));
// (***)③ get(Object key) 通过key获取value
// System.out.println(map.get("二"));
// ④ Collection<V> values() 获取值的集合。
Collection<Integer> cl = map.values();
System.out.println(cl);
}
}
Map集合的遍历方式之一
Map集合的遍历:
① keySet()
思路:
Map集合没有迭代器,Map集合需要先转Set集合,然后迭代。
代码
package com.demo;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
Map集合的遍历:
① keySet()
思路:
Map集合没有迭代器,Map集合需要先转Set集合,然后迭代。
*/
public class Map集合的遍历 {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("一", 1);
map.put("二", 2);
map.put("三", 3);
Set<String> keys = map.keySet();
//遍历
Iterator<String> it = keys.iterator();
while (it.hasNext()){
String key = it.next();
System.out.println(key +"==>" + map.get(key));
}
}
}
Map.Entry
Map.Entry
映射项(键-值对)。
1.Map集合的遍历方式二:
Map.Entry Map中的子接口。
2.常用方法:
① getKey()获取键
② getValue() 获取值
3.Map的常用方法:
entrySet() 获取Map.Entry的Set集合
代码
package com.demo;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
//import java.util.Map.Entry; //直接写Entry 可以在该位置导包
/**
1.Map集合的遍历方式二:
Map.Entry Map中的子接口。
2.常用方法:
① getKey()获取键
② getValue() 获取值
3.Map的常用方法:
entrySet() 获取Map.Entry的Set集合。
*/
public class Map的遍历方式二 {
public static void main(String[] args) {
HashMap<String,Integer> map = new HashMap<>();
map.put("二", 2);
map.put("三", 3);
map.put("一", 1);
Set<Map.Entry<String,Integer>> entry = map.entrySet();
//遍历
/*Iterator<Map.Entry<String,Integer>> it = entry.iterator();
while(it.hasNext()){
Map.Entry<String,Integer> en = it.next();
System.out.println(en.getKey() + "====="+ en.getValue());
}*/
for (Iterator<Map.Entry<String,Integer>> it = entry.iterator(); it.hasNext();){
Map.Entry<String, Integer> value = it.next();
System.out.println(value.getKey() + "==="+ value.getValue());
}
}
}
HashMap
概述
底层:
基于哈希表的实现。
特点:
键值对的映射,一个键对应一个值,键是不重复的,键无序
HashMap 细节问题:
自定义类做键: 需要重写hashCode和equals方法。
代码
package com.demo;
import java.util.HashMap;
import java.util.Map;
/**
1.HashMap 细节问题:
自定义类做键: 需要重写hashCode和equals方法。
*/
public class HashMap细节问题 {
public static void main(String[] args) {
/*HashMap<String ,Person> map = new HashMap<>();
map.put("张三",new Person("张三", 19));
map.put("张三1",new Person("张三1", 19));
map.put("张三2",new Person("张三2", 19));
map.put("张三2",new Person("张三2", 20));
System.out.println(map);*/
HashMap<Person,String> map = new HashMap<>();
map.put(new Person("zs", 19), "zs");
map.put(new Person("zs1", 19), "zs1");
map.put(new Person("zs2", 19), "zs2");
map.put(new Person("zs3", 19), "zs3");
map.put(new Person("zs3", 19), "zs5");
System.out.println(map);
}
}
class Person{
String name;
int age ;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person() {
}
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;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
TreeMap
概述
底层:基于红黑树(Red-Black tree)的 NavigableMap 实现
特点:
键值对的映射,一个键对应一个值,键是不重复的,键无序 键可排序
TreeMap 细节问题:
自定义类做键: 需要在类或者构造方法中使用比较器。
代码
package com.demo;
import java.util.Comparator;
import java.util.TreeMap;
/**
*/
public class TreeMap细节问题 {
public static void main(String[] args) {
/*TreeMap<String,Student> map = new TreeMap<>();
map.put("张三", new Student("张三", 19));
map.put("张三", new Student("张三1", 19));
System.out.println(map);*/
TreeMap<Student ,String> map = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
});
map.put(new Student("zs", 19), "zs");
map.put(new Student("zs", 19), "zs1");
System.out.println(map);
}
}
class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Collections
概述
集合工具类
可变参数
格式:
数据类型… 变量的名称
调用可变参数的方法时,可以传递0-任意个参数,但是定义可变参数对应的方法时,要求可变参数定
义在最后。
实质: 数组
常用方法
1.常用方法:
① addAll(Collection<? super T> c, T… elements) 添加元素到集合
② fill(List<? super T> list, T obj) 替换
③ max/min (Collection<? extends T> coll, Comparator<? super T> comp) 求最大小值
④ sort(List
排序默认没有第二个参数表示按元素的自然顺序进行排序,有按第三方比较器
⑤ shuffle(List> list) 随机置换
代码
package com.demo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
1.常用方法:
① addAll(Collection<? super T> c, T... elements) 添加元素到集合
② fill(List<? super T> list, T obj) 替换
③ max/min (Collection<? extends T> coll, Comparator<? super T> comp) 求最大小值
④ sort(List<T> list, Comparator<? super T> c)
排序默认没有第二个参数表示按元素的自然顺序进行排序,有按第三方比较器
⑤ shuffle(List<?> list) 随机置换
*/
public class 集合工具类 {
public static void main(String[] args) {
// A a = new A();
// a.add();
ArrayList<String> list = new ArrayList<>();
// Collections.addAll(list,"abc","bcd","def");
/* System.out.println(list);*/
// ② fill(List< ? super T> list, T obj) 替换
/* Collections.fill(list,"kkk");
System.out.println(list);*/
// ③ max/min (Collection<? extends T> coll, Comparator<? super T> comp) 求最大小值,如果没有第二个参数表示按照元素的自然顺序进行排序。
/* String max = Collections.max(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
System.out.println(max);*/
// ⑤ shuffle(List<?> list) 随机置换
Collections.addAll(list,"1","2","3","4","5","6");
Collections.shuffle(list);
System.out.println(list);
}
}
class A {
//int 3 4 5
public void add(int b,int... a){
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}
集合总结
单列集合
-
Collection:
-
List:有序 可重复 可插入多个null
-
ArrayList:底层: 大小可变的数组的实现。
特点: 有序 可重复 可插入多个null 查询快
增删慢 线程不安全
-
LinkedList:底层: 双向链表
特点:有序 可重复 可插入多个null 查询慢
增删快 线程不安全
-
Vector:用法同ArrayList 线程安全
-
-
Set:无序 不重复 只能插入一个null
-
HashSet:底层: 哈希表–》HashMap
特点:无序 不重复 只能插入一个null 线程不安全
自定义类对象去重:重写hashCode和equals方法
存储原理:
1.8jdk结构改进。
-
LinkedHashSet:底层: 哈希表+双向链表
特点:有序 不重复 只能插入一个null 线程不安全
-
TreeSet:底层: 基于红黑树的TreeMap
特点:可排序 无序 不重复 只能插入一个null 线程不安全
比较器:① 元素的自然顺序比较器: Comparable
② 第三方比较器:Comparator
-
-
通用方法
1.add()
2.List–>get(index)
3.集合的遍历: 五种 ,Set :迭代器 增强for 转数组r