1. 一维数组
概念: 数组就是在堆内存中开辟的一段连续的内存空间:
- 一维数组长度不可改变,内容类型必须一致。
- 一维数组下标从0开始,在知道位置的情况下查询快,操作费事。
- 数组是有默认值的,如int数组中的每个值都默认为0,double数组中的每个值都默认为0.0等。
数组内存分布图
1.1 一维数组声明
概念:
- 声明一个数组的时候,要么指定内容,要么指定长度,且不可同时指定。
- 数组是引用数据类型,直接输出数组变量,得到的是引用数据类型的内存地址。
因为String的特权导致,char[]是可以直接打印输出的(String的底层就是char数组),所以如果非要查看char[]的内存地址,可以将其拼接一个空字符串再输出,或者对其使用
toString()。
源码: /javase-start/
- src:
c.y.array.OneDimensionalArrayTest.build()
/**
* @author yap
*/
public class OneDimensionalArrayTest {
@Test
public void build() {
int[] arrA = new int[]{1, 2, 3};
int arrB[] = {1, 2, 3};
int[] arrC = new int[3];
arrC[0] = 1;
arrC[1] = 2;
arrC[2] = 3;
System.out.println(arrA);
System.out.println(arrB);
System.out.println(arrC);
}
}
1.2 一维数组遍历
概念: 遍历指的就是将容器(这里指数组)中的元素一个一个拿出来进行其他操作。
- 数组一般使用
for或者for-each循环来进行遍历。 - 数组长度:使用
arr.length来查看数组的长度。 Arrays.toString():快速查看一维数组内容的字符串表示形式。
源码: /javase-start/
- src:
c.y.array.OneDimensionalArrayTest.traverse()
@Test
public void traverse() {
int[] nums = {1, 2, 3};
for (int i = 0, j = nums.length; i < j; i++) {
System.out.println(nums[i]);
}
for (int num : nums) {
System.out.println(num);
}
System.out.println(Arrays.toString(nums));
}
1.3 一维数组复制
概念: 数组是引用数据类型,所以复制一个数组和直接递交引用并非是同一个概念,常见的数组复制方式有如下几种:
- 利用
for循环复制数组。 - 利用
System.arraycopy()复制数组:- p1:原数组
- p2:从原数组的哪个位置开始复制
- p3:目标数组
- p4:从目标数组的哪个位置开始粘贴
- p5:复制多长
- 利用
Arrays.copyOf(int[] arr, int length):- p1:原数组
- p5:复制多长
- 底层调用的
System.arraycopy()
源码: /javase-start/
- src:
c.y.array.OneDimensionalArrayTest.copy()
@Test
public void copy() {
int[] arr = {1, 2, 3};
int[] arrA = new int[arr.length];
for (int i = 0, j = arrA.length; i < j; i++) {
arrA[i] = arr[i];
}
System.out.println(Arrays.toString(arrA));
int[] arrB = new int[arrA.length];
System.arraycopy(arr, 0, arrB, 0, arr.length);
System.out.println(Arrays.toString(arrB));
int[] arrC = Arrays.copyOf(arr, arr.length);
System.out.println(Arrays.toString(arrC));
}
1.4 一维数组查找
概念:
- 从一个一维数组中查找某个元素,需要遍历这个数组,用其中的每一个元素和我们要找的元素进行比较,这种方式浪费了大量的时间,很影响效率,所以我们在大量数据中查找某个元素的情况下,会使用到二分法的方式进行查找。
- 采用二分法查找时,数据需是排好序的。
流程:
- 计算查找区间的中间位k:
(高位 + 低位) / 2。
- 用
arr[k]与目标查找值进行比较:- 若相等,查找成功,返回k。
- 若
arr[k]比目标值大,则划掉k及k后面位置上的所有元素。 - 若
arr[k]比目标值小,则划掉k及k前面位置上的所有元素。 - 重新划分查找区域(重新计算中间位),继续二分查找。
Arrays.binarySearch(int[] arr, char key):在arr数组中,用二进制搜索法搜索key。
源码: /javase-start/
- src:
c.y.array.OneDimensionalArrayTest.binarySearch()
@Test
public void binarySearch(){
int target = 13;
int result = -1;
int[] arr = { 1, 3, 5, 7, 9, 11, 13, 15 };
int lowIndex = 0;
int highIndex = arr.length - 1;
int midIndex = (lowIndex + highIndex) / 2;
while (lowIndex <= highIndex) {
if (arr[midIndex] == target) {
result = midIndex;
break;
} else {
if (arr[midIndex] < target) {
lowIndex = midIndex + 1;
} else {
highIndex = midIndex - 1;
}
}
midIndex = (lowIndex + highIndex) / 2;
}
System.out.println(result);
}
2. 二维数组
概念: 二维数组可以看成是数组的数组,如果将二维数组看成是一个特殊的一维数组,那么这个一维数组的每一个元素都是数组。
2.1 二维数组声明
概念:
- 声明一个二维数组的时候,要么指定内容,要么指定长度,且不可同时指定。
- 二维数组中的每个一维数组的长度可以不同。
- 可以利用
Arrays.deepToString(arr)快速查看二维数组。
源码: /javase-start/
- src:
c.y.array.TwoDimensionalArrayTest.build()
/**
* @author yap
*/
public class TwoDimensionalArrayTest {
@Test
public void build() {
int[][] arrA = new int[][]{{1}, {4, 67}, {80}};
System.out.println(Arrays.deepToString(arrA));
int[] arrB[] = {{1}, {4, 67}, {80}};
System.out.println(Arrays.deepToString(arrB));
int[][] arrC = new int[2][3];
arrC[0][0] = 1;
arrC[0][1] = 22;
arrC[0][2] = 313;
arrC[1][0] = 34;
arrC[1][1] = 311;
arrC[1][2] = 35;
System.out.println(Arrays.deepToString(arrC));
}
}
2.2 二维数组遍历
概念:
- 遍历方式:指的就是将容器(这里指数组)中的元素一个一个拿出来进行其他操作,一般使用两个
for或者for-each循环来遍历二维数组。 - 数组长度:使用
arr.length来查看二维数组中一维数组的个数。 Arrays.deepToString():快速查看二维数组内容的字符串表示形式。
源码: /javase-start/
- src:
c.y.array.TwoDimensionalArrayTest.traverse()
@Test
public void traverse() {
int[][] arr = {{1}, {4, 67}, {5}, {16, 17, 18, 40}};
for (int i = 0, j = arr.length; i < j; i++) {
for (int m = 0; m < arr[i].length; m++) {
System.out.print(arr[i][m] + "\t");
}
}
for (int[] e1 : arr) {
for (int e2 : e1) {
System.out.print(e2 + "\t");
}
}
System.out.println(Arrays.deepToString(arr));
}
3. 位组
概念: java.util.BitSet 的特点可以按位存储一个布尔值。
BitSet(int nbits):在构造位组的时候可以指定初始容量,如果不指定,默认容量64,值都是false。void set(int bitIndex):将位组中bitIndex号位置上的false改为true,如果角标超出当前容量,则会触发自动扩容,每次扩容64个。int size():获取位组当前的容量。boolean get(int bitIndex):获取bitIndex号位置上的值,如果角标超出当前容量,不会触发自动扩容,直接返回false。
源码: /javase-start/
- src:
c.y.array.BitSetTest.api()
/**
* @author yap
*/
public class BitSetTest {
@Test
public void api() {
BitSet bitSet = new BitSet();
bitSet.set(0);
bitSet.set(12);
System.out.println(bitSet.size());
bitSet.set(64);
System.out.println(bitSet.size());
System.out.println(bitSet.get(0));
System.out.println(bitSet.get(1));
System.out.println(bitSet.get(500));
System.out.println(bitSet.size());
}
@Test
public void work01() {
BitSet bitSet = new BitSet(365);
int[] holidays = {1, 15, 50, 148, 185, 246, 281, 316, 326, 359};
for (int holiday : holidays) {
bitSet.set(holiday);
};
System.out.println(bitSet.get(1) ? "is holiday" : "is not holiday");
System.out.println(bitSet.get(2) ? "is holiday" : "is not holiday");
}
}
4. 数据结构-栈
概念: 栈是一种后进先出(last in first out)的数据结构。
push():将元素推入栈顶(数组尾部),使得原栈结构的长度加1。pop():将栈顶元素移除并返回,使得原栈结构的长度减1。peek():将栈顶元素返回,原栈结构的长度不变。
5. 数据结构-队列
概念: 队列是一种先进先出(first in first out)的数据结构。
add():将元素推入队列(数组尾部),使得原队列结构的长度加1。poll():队列头出队,使得原队列结构的长度减1。。peek():查看队列头,原队列结构的长度不变。