数组:元素的线性集合
1.定义方式一:
(1)int[] a = {1,2,3,4};定义时初始化。
(2)int[] a; a = {1,2,3,4};不可以先定义,再初始化。
2.定义方式二:
(1)int[] a = new int[]{1,2,3,4};可以定义初始化
(2)a = new int[]{5,6,7,8};也可以赋值
(2)int[] a = new int[5];定义一个长度为5 的数组,元素的默认值是0对应的各种类型
1.数组的定义初始化与赋值
import java.util.Arrays;
public class 定义int类型数组的变量 {
public static void main(String[] args) {
int[] a;
System.out.println(a);//数组只定义了,没有初始化
int[] a={1,2,3,4};
System.out.println(a);//可以运行,但不打印数组
int[] a;
a={1,2,3,4};
System.out.println(a);//不可以先定义再赋值
String[] a = new String[]{"hello","world"};//初始化
a = new String[]{"go","come","yes","no"};//赋值
int[] a = new int[5];//定义一个数组,元素类型是int,长度是5
//其中每个元素的值都是int类型的默认值-0;
int[] b = method();//可以直接调用方法返回一个数组
}
private static int[] method() {
return new int[]{9,8,7,6};
}
}
2.数组的两种遍历方法
public class 定义int类型数组的变量 {
public static void main(String[] args) {
int[] a =new int[]{1,2,3,4};
int b=a.length;
System.out.println(b);
System.out.println(Arrays.toString(a));
//数组下标遍历
for(int i=0;i<a.length;i++){
int j=a[i];
System.out.printf("%d ",j);
}
System.out.println();
//数组全体遍历
for(int i:a){
System.out.println(i);
}
}
}
3.使用Arrays中的常用方法
import java.util.Arrays;
public class 使用Arrays中的方法 {
public static void main(String[] args) {
testBinarySearch();//测试二分查找
testEquals();//测试数组相等
testFill();//数组填充
testSort();//数组排序
testCopy();//数组拷贝
testCopyRange();//数组范围拷贝
}
private static void testCopyRange() {
long[] a = { 1, 2, 3, 4, 5 };
// [from, to)
//long[] copy = Arrays.copyOfRange(a, 3, 4);
//long[] copy = Arrays.copyOfRange(a, 3, a.length);
long[] copy = Arrays.copyOfRange(a, 3, 10);//拷贝a数组从3到10
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(copy));
}
private static void testCopy() {
long[] a = { 1, 2, 3, 4, 5 };
System.out.println(Arrays.toString(a));
long[] copy = Arrays.copyOf(a, 3);// 新数组长度小于源长度
long[] copy = Arrays.copyOf(a, 5);// 新数组长度等于源长度
long[] copy = Arrays.copyOf(a, 10);// 新数组长度大于源长度
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(copy));
Arrays.fill(a, 100);//数组填充,填充100
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(copy));
}
private static void testSort() {
long[] a = { 9, 5, 2, 7, 1, 6, 8, 3, 0, 4 };
System.out.println(Arrays.toString(a));
Arrays.sort(a); // In-place Sort 原地排序
System.out.println(Arrays.toString(a));
}
private static void testFill() {
long[] a = new long[10];
System.out.println(Arrays.toString(a));
Arrays.fill(a, 1, 8, 100);//a数组从1到8填充100
System.out.println(Arrays.toString(a));
}
private static void testEquals() {
long[] a = { 1, 2, 3, 4 };
long[] b = { 1, 2, 3, 0 };
b[3] = 4;
System.out.println(Arrays.equals(a, b));//true
}
private static void testBinarySearch() {
long[] a = { 9, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9 };
System.out.println(Arrays.binarySearch(a, 1)); // 由于数组无序,返回什么都是合理的
// System.out.println(Arrays.binarySearch(a, 3)); // 2
// System.out.println(Arrays.binarySearch(a, 4)); // 3 OR 4
// System.out.println(Arrays.binarySearch(a, -1)); // -1
// System.out.println(Arrays.binarySearch(a, 10)); // -11
}
}
4.自写toString,copyOf,copyOfRange,冒泡排序,二分查找
public class MyArrays {
// "[1, 2, 3, 4]"
public static String toString(long[] array) {
String ans = "[";
// 遍历 除了 最后一个元素之外的其余所有元素
for (int i = 0; i < array.length - 1; i++) {
long element = array[i];
// String + long + String
// String + String.valueOf(long) + String
// "["
// "[1, "
// "[1, 2, "
// "[1, 2, 3, "
// "[1, 2, 3, 4, "
ans = ans + element + ", ";
}
// 把最后一个元素添加到字符串 ans 中
// 数组中最后一个元素的下标是 array.length - 1
// 思考 array.length 的取值范围是多少 >= 0
// "[1, 2, 3, 4, 5"
if (array.length > 0) {
long lastElement = array[array.length - 1];
ans = ans + lastElement;
}
// "[1, 2, 3, 4, 5]"
ans = ans + "]";
return ans;
}
public static long[] copyOf(long[] original, int newLength) {
if (newLength < 0) {
throw new RuntimeException("newLength 必须 >= 0");
}
long[] ans = new long[newLength];
// 下标(i) 走到哪个位置停下来?
// original.length 和 ans.length 中小的一个
int size = Integer.min(original.length, newLength);
for (int i = 0; i < size; i++) {
// 需要保证等号两边的下标使用都是合法的!!
ans[i] = original[i];
}
// 如果 newLength > original.length 了
// ans 中剩余的位置,已经是 long 类型的默认值了(0)
// 所以我们不需要做什么事情了
return ans;
}
// 0 <= from <= original.length && 0 <= from <= to
public static long[] copyRangeOf(long[] original, int from, int to) {
if (from < 0) {
throw new RuntimeException("from 必须 >= 0");
}
if (from > to) {
throw new RuntimeException("from 必须 <= to");
}
if (from > original.length) {
throw new RuntimeException("from 必须 <= original.length");
}
int newLength = to - from;
long[] ans = new long[newLength];
// ans[0] = original[from];
// ans[1] = original[from + 1];
// ans[2] = original[from + 2];
// i 假如代表的是 ans 的下标
// i 的合法取值范围必须满足两个条件
// 1. i 在 ans 中是合法下标 [0, ans.length)
// 2. from + i 在 original 中是合法下标 [0, original.length)
// i 的取值范围 [-from, original.length - from)
// 最后,i 的合法范围:[0, ans.length) 和 [-from, original.length - from) 的交集
// i ~ [0, min(ans.length, original.length - from))
int size = Integer.min(newLength, original.length - from);
for (int i = 0; i < size; i++) {
// 保证两边的下标都合法
ans[i] = original[from + i];
}
// // i 假如代表的是 original 的下标
// for (int i = from; i < ?; i++) {
// ans[i - from] = original[i];
// }
// 思考过填充默认值的情况,和 copyOf 一样
return ans;
}
public static void bubbleSort(long[] array) {
// 一共有 array.length 个元素,需要经过 array.length - 1 次 “冒泡” 数组会有序
for (int i = 0; i < array.length - 1; i++) {
// 每循环一次,经过一次 “冒泡过程”
// 把无序区间中的最大的数,冒泡到,无序区间的最后去
// 数组看作一个整体区间,表示 [0, array.length)
// 无序区间: [0, array.length - i)
// 实现具体的冒泡过程
// j 代表的是黑色下标
// j ~ [0, array.length - i) 无序区间
// j + 1 ~ [0, array.length - i) 无序区间 <=> j ~ [-1, array.length - i - 1)
// j 需要取交集 [max(0, -1), min(array.length - i, array.length - i - 1))
// j ~ [0, array.length - i - 1)
for (int j = 0; j < array.length - i - 1; j++) {
// j 需要保证 array[j] 和 array[j + 1] 的下标都合法
if (array[j] > array[j + 1]) {
long t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}
}
// 前提:array 有序
// 找到 target 所在的下标,如果 target 有多个,不保证找到哪一个
// 如果没有找到,返回 -1
public static int binarySearch(long[] array, long target) {
// 待查找区间表示为: [low, high)
// 带查找区间内的元素个数: high - low
// 定义待查找区间的下限
int lowIndex = 0;
// 定义待查找区间的上限
int highIndex = array.length;
// 只要带查找区间内还有元素,查找过程就得继续
while (highIndex - lowIndex > 0) {
int midIndex = (lowIndex + highIndex) / 2; // 暂时不考虑溢出的情况
long midElement = array[midIndex];
if (target == midElement) {
return midIndex;
} else if (target < midElement) {
// 需要扔掉右边 [midIndex, ...)
// highIndex 是开区间,所以 = midIndex,但区间里没有 midIndex 对应的元素
highIndex = midIndex;
} else {
// 需要扔掉左边 [..., midIndex]
// lowIndex 是闭区间,所以 = midIndex + 1,区间里没有 midIndex 对应的元素
lowIndex = midIndex + 1;
}
}
// high - low <= 0 换言之 带查找区间内一个元素都没有了
// 说明 target 不在 array 中
return -1;
}
}
本文详细介绍了Java中数组的定义、初始化、赋值以及两种遍历方法。同时,深入探讨了Arrays工具类的常用方法,包括二分查找、数组相等判断、填充、排序和拷贝。此外,还提供了自定义实现toString、copyOf和copyOfRange以及冒泡排序和二分查找的示例代码,帮助读者更好地理解和运用Java数组操作。
162

被折叠的 条评论
为什么被折叠?



