数组
目录
一、数组的概念
相同类型数据的集合。
二、数组的创建
方法1:
int[] arr1 = new int[]{1,2,3,4};
方法2:
int[] arr2 = {1,2,3,4};
方法3:
int[] arr3 = new int[4]; //数组元素初始化成0
//该方法主要用于指定长度,网络编程中比较常见。
byte[] buffer = new byte[1024];
- Tips1: Java中的 arr* 数组的类型就是 int[];
- Tips2: C语言中,int[4] 和 int[5] 是两种不同的类型,因此不能相互赋值;但是在Java中,大家都是同一种类型,因此可以相互赋值。
三、数组的功能
1.获取数组长度
int[] arr1 = new int[]{1,2,3,4};
System.out.println(arr1.length);
运行结果:
- Tips: 数组在创建完成之后,其长度无法修改,进而通过 length 访问的时候对 length 是无法赋值和修改的。
2.获取数组元素
通过下标来访问数组元素,下标是从0开始;不能超出有效范围,如果超出,则会抛出数组下标越界异常。若是在C语言中,则会表示为未定义行为。
int[] arr1 = new int[]{1,2,3,4};
System.out.println(arr1[1]);
运行结果:
3.遍历数组
- for 循环遍历
int[] arr = {1,2,3,4};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
运行结果
- for each
for(int x : arr){
System.out.println(x);
}
运行结果:
- Tips:for each 方法中,x 不能修改。
四、数组作为方法的参数
- C语言中,如若数组作为函数的参数,就会隐士转成指向首元素的指针。
- Java中则不会出现这种情况。
- 数组传参,相当于赋值,即并不是把原来的数组拷贝一份得到新的数组,而是在原有的数组基础上,多起一个“别名”。
public class Test {
public static void main(String[] args) {
// System.out.println("hello");
//数组作为参数
int[] arr = {1,2,3,4};
transform(arr);
printArray(arr);
}
public static void transform(int[] arr) {
arr[0] = 100;
}
private static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
运行结果
五、数组作为方法的返回值
public class Test {
public static void main(String[] args) {
// System.out.println("hello");
//数组的返回值
//创建一个方法,把数组中的每个元素都 * 2
int[] arr = {1,2,3,4};
int[] result = transform(arr);
printfArray(arr);
System.out.println("========================");
printfArray(result);
}
private static int[] transform(int[] a) {
int [] result = new int[a.length];
for (int i = 0; i < a.length; i++) {
result[i] = 2 * a[i];
}
return result;
}
private static void printfArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
- Tips: 对于方法 transform 中的 result ,若在C语言中,是无法返回的,因为在使用完之后会被释放;但是在Java中编译器有一个类似于“垃圾回收器”功能,对于使用过的变量不会里面释放,而是根据后续程序的执行情况,暂时保存。
六、数组与其他数据类型之间的转换
1.数组转字符串–Arrays.toString()
2.数组拷贝
-
浅拷贝:只拷贝第一层数组元素,比如一维数组的拷贝。
-
深拷贝:除了将第一层数组元素拷贝之后还会将每个元素所对应得数组再拷贝。比如二维数组的拷贝。
创建一个新的数组,并将原有的数组元素拷贝一份,因此,改变原有的数组元素并不会影响 拷贝数组的元素。
int[] arr = {1,2,3,4};
int[] result = copyof(arr);
System.out.println(Arrays.toString(result));
result[0] = 100;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(result));
}
public static int[] copyof(int[] arr) {
int[] newArr = new int[arr.length];
for(int i = 0;i < arr.length;i++){
newArr[i] = arr[i];
}
return newArr;
}
- 标准库的 Arrays.copyO 允许新的数组和旧的数组不一样。若新的数组长度更短,就会发生“截断”;若新的数组长度更长,多出来的部分就会自动填充成0;
七、数组应用
1.找数组中的最大元素----基本原理:打擂台
int[] arr = {2,6,4,9,1,0};
int maxValue = Max(arr);
System.out.println(maxValue);
}
public static int Max(int[] arr) {
int result = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > result){
result = arr[i];
}
}
return result;
}
运行结果
2.求数组中元素的平均值
int[] arr = {4,5,3,7,8,1};
double avgValue = Avg(arr);
System.out.println(avgValue);
}
public static double Avg(int[] arr) {
int sum = 0;
for(int x :arr){
sum += x;
}
return (double)sum / arr.length;
}
运行结果
3.给定元素查找下标
- 遍历查找
int[] arr = {2,6,4,9,1,0};
int pos = search(arr,1);
System.out.println(pos);
}
public static int search(int[] arr,int toSearch){
//依次遍历数组元素
for (int i = 0; i < arr.length; i++) {
if(arr[i] == toSearch){
return i;
}
}
return -1;
}
运行结果
- 针对有序数列可进行二分查找
int[] arr = {0,2,5,6,9,10};
int pos = binarySearch(arr,10); //二分查找
System.out.println(pos);
}
public static int binarySearch(int[] arr,int
toSearch) {
int left = 0;
int right = arr.length - 1;
//二分查找为了解决溢出问题
//面试专属写法
//int mid = left + (right - left) / 2;
while(left <= right){
int mid = (left + right) / 2;
if(toSearch < arr[mid]){
//左侧查找
right = mid - 1;
}else if(toSearch > arr[mid]){
//右侧查找
left = mid + 1;
}else {
//相等情况
return mid;
}
}
return -1;
}
运行结果
- 二分查找效率遵循对数函数增长趋势。
//二分查找效率检测
int[] arr = makeBigArray();
int pos = binarySearch(arr,9999);
}
private static int[] makeBigArray() {
int[] arr = new int[10000];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
return arr;
}
public static int binarySearch(int[] arr,int
toSearch) {
int count = 0;
int left = 0;
int right = arr.length - 1;
//二分查找为了解决溢出问题
//面试专属写法
//int mid = left + (right - left) / 2;
while(left <= right){
count ++;
int mid = (left + right) / 2;
if(toSearch < arr[mid]){
//左侧查找
right = mid - 1;
}else if(toSearch > arr[mid]){
//右侧查找
left = mid + 1;
}else {
//相等情况
System.out.println("count = " + count);
return mid;
}
}
System.out.println("count = " + count);
return -1;
}
4.检查数组的有序性
- 核心思想:找反例,即:循环寻找相邻元素,看相邻元素是否符合要求顺序,只要是不符合,则可以排除此数组是有序数组;反之,则为有序数组。
int[] arr = {0,2,5,6,9,10};
System.out.println(isSorted(arr));
}
private static boolean isSorted(int[] arr) {
for (int i = 0; i + 1 < arr.length; i++) {
if(arr[i] > arr[i + 1]){
//反例,不符合升序
return false;
}
}
return true;
}
运行结果
5.数组排序—冒泡排序
原理解析:
6.数组的逆序
是根据下标不动修改数组元素内容,而不是反向打印
int[] arr = {0,2,5,4,9,10};
reverse(arr);
System.out.println(Arrays.toString(arr));
}
public static void reverse(int[] arr) {
int left = 0;
int right = arr.length - 1;
while(left < right){
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
public static String arrayToString(int[] arr) {
String result = "[";
for (int i = 0; i < arr.length; i++) {
result += arr[i];
if(i != arr.length - 1){
result += ", ";
}
}
result += "]";
return result;
}
运行结果
7.数组数字排列
给定一个整型数组, 将所有的偶数放在前半部分, 将所有的奇数放在数组后半部分
int[] arr = {1,2,5,4,9,10};
transform2(arr);
System.out.println(arrayToString(arr));
}
public static void transform2(int[] arr) {
int left = 0;
int right = arr.length - 1;
while(left < right){
//从左往右找奇数
while(left < right && arr[left] % 2== 0){
left++;
}
//从右往左找偶数
while(left < right && arr[right] % 2 != 0){
right--;
}
//交换left和right
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
}
}
public static void reverse(int[] arr) {
int left = 0;
int right = arr.length - 1;
while(left < right){
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
public static String arrayToString(int[] arr) {
String result = "[";
for (int i = 0; i < arr.length; i++) {
result += arr[i];
if(i != arr.length - 1){
result += ", ";
}
}
result += "]";
return result;
}
运行结果