一、什么是集合?
1.1什么是集合?
1、集合类存放于java.util包中。
2、集合类型主要有3种:set(集)、list(列表)和map(映射)。
3、集合存放的都是对象的引用,而非对象本身。所以我们称集合中的对象就是集合中对象的引用。
简单来讲:集合就是一个放数据的容器,准确的说是放数据对象引用的容器。
二、集合的继承结构关系图
三 、Collection接口
3.1 继承图
3.2常用方法
add(Object o):增加元素
addAll(Collection c)
clear():清空
contains(Object o):是否包含指定元素
containsAll(Collection c):是否包含集合c中的所有元素
iterator():返回Iterator对象,用于遍历集合中的元素
remove(Object o):移除元素
removeAll(Collection c):相当于减集合c
retainAll(Collection c):相当于求与c的交集
size():返回元素个数
toArray():把集合转换为一个数组
四、List集合
4.1、ArrayList:
特点:底层数据结构是数组,查询快,增删慢,线程不安全,效率高
问:ArrayList底层数据结构是数组,数组在定义后就不能修改大小,为什么ArrayList可以改变大小?
答:数组不可以改变大小是肯定的的,ArrayList有个扩容机制,默认开辟10个大小的空间,如果超出容量了,就会触发扩容机制,每次扩容都是原来的1.5倍
4.2、vector:
特点:底层数据结构是数组,查询快,增删慢,线程安全,效率低
4.3、LinkedList:
特点:底层数据是链表,查询慢,增删快,线程不安全,效率高
4.4、常见的数据结构
1.数组
2.堆栈
3.队列
4.链表
5.哈希表
五、Iterator迭代器
5.1什么是迭代器?
答:迭代器是一个设计模式,它是一个对象,他可以遍历序列中的所有对象,而开发人员不需要了解它的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2)使用next()获得序列中的下一个元素。
(3)使用hasNext()检查序列中是否还有元素。
(4)使用remove()将迭代器新返回的元素删除
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
public class Demo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
//方式一
for(int i=0;i<list.size();i++) {
String s = (String)list.get(i);
System.out.println(s);
}
System.out.println("-----------------------");
//方式二
Iterator i = list.iterator();
while(i.hasNext()) {
String s = (String)i.next();
System.out.println(s);
}
System.out.println("-----------------------");
//方式三
ListIterator iterator = list.listIterator();
while(iterator.hasNext()) {
String s = (String)iterator.next();
System.out.println(s);
}
System.out.println("-----------------------");
//逆向遍历
while(iterator.hasPrevious()) {
String s = (String)iterator.previous();
System.out.println(s);
}
}
}
5.2、用几种方式遍历集合
package 集合的基本操作;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 功能:集合的几种遍历方式
* 作者:吴工
* 时间:2021/7/20 10:42
* 版本:1.0
**/
public class Test2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1212");
list.add("1212");
printList(list);
System.out.println("------------------------------------");
printList2(list);
System.out.println("------------------------------------");
printList3(list);
System.out.println("------------------------------------");
printList4(list);
System.out.println("------------------------------------");
printList5(list);
System.out.println("------------------------------------");
printList6(list);
System.out.println("------------------------------------");
printList7(list);
}
/*
* @功能: lambda表达式
* @Author 吴工
* @Date 10:52 2021/7/20
* @Param
* @return
**/
public static void printList6(List<String> list) {
list.forEach(li -> System.out.println(li));
}
/*
* @功能: 迭代器遍历
* @Author 吴工
* @Date 10:49 2021/7/20
* @Param
* @return
**/
public static void printList5(List<String> list) {
Iterator<String> iterator = list.iterator();
//判断是否还有下一个元素
while (iterator.hasNext()) {
//输出元素
String next = iterator.next();
System.out.println(next);
}
}
/*
* @功能: lambda简写方式
* @Author 吴工
* @Date 10:58 2021/7/20
* @Param
* @return
**/
public static void printList7(List<String> list) {
list.forEach(System.out::println);
}
/*
* @功能: 普通for循环
* @Author 吴工
* @Date 10:44 2021/7/20
* @Param
* @return
**/
public static void printList(List<String> list) {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
/*
* @功能: 增强for循环
* @Author 吴工
* @Date 10:45 2021/7/20
* @Param
* @return
**/
public static void printList2(List<String> list) {
for (String li : list) {
System.out.println(li);
}
}
/*
* @功能: while循环
* @Author 吴工
* @Date 10:46 2021/7/20
* @Param
* @return
**/
public static void printList3(List<String> list) {
int i = 0;
while (i < list.size()) {
System.out.println(list.get(i));
i++;
}
}
/*
* @功能: do while循环
* @Author 吴工
* @Date 10:48 2021/7/20
* @Param
* @return
**/
public static void printList4(List<String> list) {
int i = 0;
do {
System.out.println(list.get(i));
i++;
} while (i < list.size());
}
}
六、泛型
6.1、什么是泛型?
答:就是“参数化类型” ,定义方法时有形参,调用法时传递实参。那么什么是泛型呢,就是将类型由原来的具体的类型参数化,类似于方法中的变量类型,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
6.2、泛型类
6.3、泛型接口
6.4、泛型方法
6.5、通配符
6.6、泛型的限定
七、Set集合(set:无序,唯一,无索引)
7.1、HashSet
(1)底层数据结构是哈希表
(2)哈希表依赖两个方法:hashCode()和equals()
!!!!!
(一般规则:对象equals 是true的话,hashCode需要相同,但是hashCode相同的对象不一定equals,这就是所谓的冲突现象,但是有不同的冲突解决方法。你的hashCode()设计的好的话冲突也就小了。比如楼上给出的超出int范围之后这种hashCode()实现,对象肯定是无数的,但是hash实现是有限的呢,所以冲突了。)
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
是false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可
7.2、LinkedHashSet
(1)底层数据结构由链表和哈希表组成
(2)由链表保证元素有序
(3)由哈希表保证元素唯一
7.3、TreeSet
底层数据结构是红黑树。(是一种自平衡的二叉树)
(1)如何保证元素唯一性?
答:根据标胶的返回值是否为0来决定
(2)如何保证元素的排序呢?
答:两种方式:
①自然排序(元素具备比较性):让元素所属的类实现Comparable接口
②比较器排序(集合具备比较性):让集合接收一个Comparable的实现类对象
八、Map(双列集合)
1.Map集合的数据结构仅仅对键有效,与值无关
2.存储的是键值对形式的元素,键唯一,值可重复
8.1、HashMap
底层数据结构是哈希表。线程不安全,效率高
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
是false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可
8.2、 LinkedHashMap
底层数据结构由链表和哈希表组成。
由链表保证元素有序。
由哈希表保证元素唯一。
8.3、 Hashtable
底层数据结构是哈希表。线程安全,效率低
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
是false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可
8.4、TreeMap
底层数据结构是红黑树。(是一种自平衡的二叉树)
如何保证元素唯一性呢?
根据比较的返回值是否是0来决定
如何保证元素的排序呢?
两种方式
自然排序(元素具备比较性)
让元素所属的类实现Comparable接口
比较器排序(集合具备比较性)
让集合接收一个Comparator的实现类对象