文章目录
Java集合框架分为两部分:
- Collection结构:元素以单个形式存储
- Map结构:元素以键值对的映射关系存储
本篇文章主要介绍Collection部分。
一、Collection
1、Collection继承结构
2、使用idea查看类的继承结构
- 筛选类的子类或者父类
在Idea当中选中一个类,然后按Ctrl+H,可以快速查看当前所选类的继承关系,如下图:
- 查看类的继承结构图
选中类,右键 —> Diagrams ----> Show Diagram(新标签页显示,快捷键 CTRL + ALT + SHIFT + U),Show Diagram Popup(浮动窗显示,快捷键 CTRL + ALT + U),可查看当前类的继承关系图:
3、Collection接口的通用方法
集合中放的是对象。
boolean add(E e) 向集合中添加元素
int size() 获取集合中元素个数
boolean addAll(Collection c)将参数集合中所有元素全部加入当前集合
boolean contains(Object o) 判断集合中是否包含对象o **底层调用equals方法比对**
boolean remove(Object o) 从集合中删除对象o **底层调用equals**
void clear() 清空集合
boolean isEmpty() 判断集合中元素个数是否为0
Object[] toArray() 将集合转换成一维数组
4、Collection集合的通用遍历方法
- 第一步:获取当前集合依赖的迭代器对象
Iterator it = collection.iterator();
第二步:编写循环,循环条件是:当前光标指向的位置是否存在元素
boolean has = it.hasNext();
true:有 false;无
while(it.hasNext()){}
第三步:如果有,将光标指向的当前元素返回,并且将光标向下移动一位。
Object obj =it.next();
二、泛型
泛型(Generics)是一种在编程语言中用于增强类型安全性和代码重用的机制。它允许在定义类、接口和方法时使用类型参数,从而使得这些定义可以在多种数据类型上进行操作,而不仅仅局限于特定的数据类型。使用泛型可以将类型作为参数进行参数化,从而创建可重用的、类型安全的代码。通过泛型,我们可以编写一次代码,然后使用不同类型的参数进行多次调用,而不需要为每种类型编写重复的代码。
泛型的优点包括:
类型安全:通过使用泛型,编译器可以在编译时进行类型检查,确保代码中的类型匹配,减少在运行时出现类型错误的可能性。
代码简洁和重用:通过编写泛型代码,可以创建可重用的方法和数据结构,以适应不同的数据类型,提高代码的灵活性和复用性。通过参数化类型,可以使用相同的代码操作不同类型的数据。
1、在集合中使用泛型
不使用泛型的缺点:不使用泛型,集合中存储的类型是Object类型,每一次从集合中取出的元素想要访问子类中特有的方法,必须向下转型。
while(it.hasNext()){
Objecct obj = it.next(); // 不适用泛型,从集合中取出的元素是Object类型
if(obj instanceof User){
User user = (User)obj;
user.pay()
}
}
2、自定义泛型
(1)在类上定义泛型
语法: class 类名<泛型1,泛型2,泛型3…>
public class MyClass <T> { // <T> 再类声明的时候,给类定义一个泛型,这个T可以用任何字符代替、
private T name;
public MyClass(T name){
this.name = name;
}
public T getName(){
return name;
}
public void setName(T name){
this.name = name;
}
public static void main(String[] args) {
MyClass<String> myClass = new MyClass<>("rongrong");
MyClass<Integer> myClass1 = new MyClass<>(1);
}
}
(2)在静态方法上定义泛型
在静态方法中定义泛型需要在返回值类型前面定义/声明
public static <E> void print(E[] elements){
for (E elt :elements){
System.out.println(elt);
}
}
public static void main(String[] args) {
Integer[] array = {1,2,3};
print(array);
}
(3)在接口上定义泛型
public interface MyComparable<T>
public class Order<T> implements MyComparable<T>
3、泛型通配符
泛型通配符是站在泛型使用的角度来说的。
- 无限定通配符 <?>,此处“?”可以为任意引用数据类型
以下方法的参数是一个ArrayList类型的集合,这个集合可以存储任意类型的数据
public static void print(ArrayList<?> list){}
print(new ArrayList<String>());
print(new ArrayList<Object>());
print(new ArrayList<Integer>());
print(new ArrayList<User>());
- 上限通配符,<? extends Number>,此处“?”为Number及其子类。
- 下限通配符,<? super Number>, 此处“?”必须为Number及其父类。
4、泛型擦除和补偿
泛型擦除:泛型是JDK1.5引入的新特性,是一种编译阶段的功能,编译的时候只做类型检查,程序在运行的时候为了兼容以前的jdk,擦除泛型,类型变为原来的object类型。
泛型补偿:在程序运行的时候,通过获取元素的实际类型进行强转。
三、List
java.util.List:接口
- List家族特点:有序可重复
- 有序:每个元素有下标,从0开始,以1递增
- 可重复:存进去1,还可以再存一个1。
- List接口下常见的实现类有:
- ArrayList
- Vector、Stack
- LinkedList
1、List接口的特有方法
2、List接口中的特有迭代
- add方法在光标指向的位置添加元素后,将光标向下移动一位,在遍历过程中add的元素不会输出。
2、ArrayList
- ArrayList集合底层采用了数组这种数据结构
- ArrayList集合优点:
底层是数组,因此根据下标查找元素的时间复杂度是0(1)。因此检索效率高。 - ArrayList集合缺点:
随机增删元素效率较低。不过只要数组的容量还没满,对末尾元素进行增删,效率不受影响。 - ArrayList集合适用场景:
需要频繁的检索元素,并且很少的进行随机增删元素时建议使用。 - ArrayList默认初始化容量
从源码角度可以看到,当调用无参数构造方法时,初始化容量0,当第一次调用add方法时将ArrayList容量初始化为10个长度。 - ArrayList集合扩容策略?
底层扩容会创建一个新的数组,然后使用数组拷贝。扩容之后的新容量是原容量的1.5倍。