目录
- 第四阶段
- 包装类
- String
- StringBuffer
- Arrays
- System
- Collection
- ArrayList
- Vector
第四阶段
包装类
装箱拆箱以及手动自动
package chapter4;public class Pack {public static void main(String[] args) {// 自动装箱int a = 100;Integer aa = a;// 自动拆箱int b = aa;// 手动装箱Integer a2 = Integer.valueOf(a);// 手动拆箱int b2 = a2.intValue();}
}
String
string 类的几个特性
- 实现了接口 Serializable(支持串行化),和 Comparable(表示可以被比较)
- 它是 final 类,不可被继承
- 他有一个属性 value,用于存放字符串内容
- value 被 final 修饰,不可以直接修改
直接赋值String s1 = "asd"
:从常量池查看是否有 asd 的空间,如果有就直接指向它;如果没有就重新常见并指向它;
s1 最终指向常量池的地址
构造器赋值String s2 = new String("asd")
:堆中先创建空间,维护 value 属性,指向 asd 空间;如果常量池没有 asd 那就重新创建并通过 value 指向;
s2 最终指向堆中地址
str = s1 + s2
变量相加,操作在常量池中;
str = "asd" + "asd"
常量相加,操作在堆中;
StringBuffer
StringBuffer 和 StringBuilder 均为可变字符序列,不像 String 一样直接就 final 终结掉了
StringBuffer 是线程安全的,但是 StringBuilder 不是
当字符串缓冲区被单个线程使用是,推荐直接上 StringBuilder,因为其优化较好,速度快
由于 String 的 value 属性被 final,故我们每次对 string 类型变量进行相加操作时,实际上是先把旧的副本丢掉,并生成新的结果重新赋予变量;这样会导致大量副本留在内存形成碎片,影响性能
Arrays
使用 Arrays 可以对数组进行基本的操作
package chapter4;import java.util.Arrays;public class ArraysDemo {public static void main(String[] args) {int[] arr = {1, 2, 3};System.out.println(Arrays.toString(arr));Arrays.sort(arr);System.out.println(Arrays.binarySearch(arr, 3));}
}
传入自定义 comparable 接口,来实现排序方式多样化
实现降序排序
package chapter4;import java.util.Arrays;
import java.util.Comparator;public class ArraysDemo {public static void main(String[] args) {Integer[] numbers = {5, 2, 8, 1, 9};// 使用自定义的Comparator进行降序排序Arrays.sort(numbers, new Comparator<Integer>() {@Overridepublic int compare(Integer a, Integer b) {// 降序排序,将比较结果反转return b.compareTo(a);}});// 输出排序结果for (Integer number : numbers) {System.out.println(number);}}
}
System
System.arraycopy
执行数组复制
五个参数分别为:原数组,原数组起始索引,目标数组,目标数组起始索引,欲复制多少个元素
package chapter4;import java.util.Arrays;public class SystemDemo {public static void main(String[] args) {int[] arr1 = {1, 31, 4, 12, 3, 12};int[] arr2 = new int[3];System.arraycopy(arr1, 0, arr2, 0, 3);System.out.println(Arrays.toString(arr2));}
}
BigInteger 大数整数类型
需要使用大数类型提供的方法来进行加减乘除运算
同理,还存在一个高精度小数大数运算
package chapter4;import java.math.BigInteger;public class BigNum {public static void main(String[] args) {BigInteger bigInteger1 = new BigInteger("12839371293");BigInteger bigInteger2 = bigInteger1.add(bigInteger1);System.out.println(bigInteger2);}
}
Collection
Collection(集合)是 Java 中用于存储和操作一组对象的接口。
Collection 接口定义了一些常用的方法,如下所示:
boolean add(E element)
:向集合添加一个元素。boolean remove(Object element)
:从集合中移除一个元素。boolean contains(Object element)
:检查集合是否包含指定元素。int size()
:返回集合中元素的数量。boolean isEmpty()
:检查集合是否为空。void clear()
:清空集合中的所有元素。Iterator<E> iterator()
:返回一个迭代器,用于遍历集合中的元素。boolean addAll(Collection<? extends E> collection)
:将另一个集合中的所有元素添加到当前集合中。boolean removeAll(Collection<?> collection)
:从当前集合中移除与另一个集合中相同的元素。
常见的 Collection 子接口包括:
- List:有序的集合,允许重复元素。
- Set:不允许重复元素的集合。
- Queue:队列接口,定义了在集合中进行插入和删除操作的方法。
- Map:键值对的集合,每个元素都包含一个键和一个值。
可以借助迭代器遍历
package chapter5;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class IterateDemo {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("shit");list.add("fuck");Iterator<String> iterator = list.iterator();while (iterator.hasNext()){String str = (String) iterator.next();System.out.println(str);}}
}
ArrayList
底层实现是数组,在多线程条件下不推荐使用
ArrayList 内部使用一个 Object 类型的数组来存储元素。
当创建一个 ArrayList 时,默认会创建一个初始容量为 10 的数组。随着元素的添加,如果数组的容量不足以存储新元素,ArrayList 会自动进行扩容,通常是以当前容量的一半增加容量。
ArrayList 可以通过索引直接访问和修改元素(时间复杂度为 O(1))。插入和删除操作涉及到元素的移动(平均情况下为 O(n))。
ArrayList 频繁进行插入和删除操作时,可能会造成数组的重新分配和复制,导致性能下降。
ArrayList 默认维护一个 elementData 数组
如果无参构造,其容量大小为 0;初次初始化容量变成 10,之后每次容量增加都是 1.5 倍;
如果初始化时指定容量,则后续扩容每次递增 1.5 倍;
源码分析
-
类声明和成员变量:ArrayList 类声明为
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
。它实现了 List 接口,并继承了 AbstractList 类。其中,E
是泛型参数,表示 ArrayList 中存储的元素类型。ArrayList 还实现了其他接口,如 RandomAccess(支持快速随机访问)和 Cloneable(支持克隆)等。 -
成员变量:ArrayList 内部有两个重要的成员变量:
private static final int DEFAULT_CAPACITY = 10
:默认的初始容量为 10。private static final Object[] EMPTY_ELEMENTDATA = {}
:当 ArrayList 创建时没有指定初始容量时,使用此空数组作为初始存储。
-
构造方法:
public ArrayList()
:无参构造方法,使用默认初始容量创建一个空的 ArrayList。public ArrayList(int initialCapacity)
:指定初始容量的构造方法,创建一个指定初始容量的空 ArrayList。public ArrayList(Collection<? extends E> c)
:接收一个集合参数的构造方法,创建一个包含集合元素的 ArrayList。
-
核心方法:
public boolean add(E element)
:将元素添加到 ArrayList 的末尾。public void add(int index, E element)
:在指定位置插入元素。public E get(int index)
:获取指定位置的元素。public E remove(int index)
:删除指定位置的元素,并返回被删除的元素。public boolean remove(Object element)
:删除第一个匹配到的元素。public int size()
:返回 ArrayList 中元素的数量。
-
扩容机制:
- 当插入元素时,如果当前容量不足,会进行扩容。扩容时,创建一个新的容量更大的数组,并将原数组中的元素复制到新数组中。
- 扩容的策略是按当前容量的一半进行扩展,即新容量为原容量的 1.5 倍。
- 扩容操作通过
ensureCapacityInternal
方法实现。
Vector
Vector 是 Java 集合框架中的一个动态数组实现。Vector 与 ArrayList 类似,但具有线程安全的特性,因此在多线程环境下更适合使用。
-
类声明和继承关系:Vector 类声明为
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
。它实现了 List 接口,并继承了 AbstractList 类。与 ArrayList 类似,E
是泛型参数,表示 Vector 中存储的元素类型。Vector 还实现了其他接口,如 RandomAccess(支持快速随机访问)和 Cloneable(支持克隆)等。 -
线程安全性:Vector 是线程安全的,Vector 通过在关键方法上使用
synchronized
关键字来实现线程安全,保证了对共享数据的原子性操作。 -
构造方法:
public Vector()
:无参构造方法,创建一个初始容量为 10 的空 Vector。public Vector(int initialCapacity)
:指定初始容量的构造方法,创建一个指定初始容量的空 Vector。public Vector(int initialCapacity, int capacityIncrement)
:指定初始容量和容量增量的构造方法,创建一个初始容量和容量增量的空 Vector。public Vector(Collection<? extends E> c)
:接收一个集合参数的构造方法,创建一个包含集合元素的 Vector。
-
核心方法:
public synchronized boolean add(E element)
:将元素添加到 Vector 的末尾。public synchronized void add(int index, E element)
:在指定位置插入元素。public synchronized E get(int index)
:获取指定位置的元素。public synchronized E remove(int index)
:删除指定位置的元素,并返回被删除的元素。public synchronized boolean remove(Object element)
:删除第一个匹配到的元素。public synchronized int size()
:返回 Vector 中元素的数量。
单线程环境下,如果不需要线程安全的特性,推荐使用 ArrayList 而不是 Vector,因为 ArrayList 的性能更好。