1.1 数组的基础知识
1.1.1 声明数组变量
为了在程序中使用数组,必须声明一个引用数组的变量,并指明数组的元素类型(一个数组中的所有元素都必须是相同的数据类型)
例如:double[] myList(推荐使用)
double myList[]
1.1.2 创建数组
不同于声明基本数据类型变量,声明一个数组变量时并不给数组分配任何内存空间。只是创建一个对数组的引用的存储位置。如果变量还未引用,那么这个变量的值为null
arrayRefVar = new int [arraySize]
这条语句做了两件事情:1、使用new int [arraySize]创建了一个数组空间。2、把这个新创建的数组的引用赋值给变量arrayRefVar
声明一个数组变量、创建数组、将数组引用赋值给变量这三个步骤可以合并在一条语句里:double [] myList = new double [10]
即声明了一个指向double型数组的引用变量,开辟了double型size为10的数组,将该数组的首地址给了myList
当给数组分配空间时。必须指定数组的大小,且数组创建后大小就不能变了,当创建数组后,它的元素被赋予默认值:数值型基本数据类型的默认值为0,char型的默认值为'\u0000',boolean型的默认值为false。
list2 = list1 并不能将list1引用的数组内容复制给list2,而只是将list1的引用值复制给了list2,使两个都指向了一个数组,list2原先的数组不能再引用,它就变成了垃圾,被Java虚拟机自动收回,要复制数组,最好的方法是逐个复制元素。
1.1.3 初始化数组
方法一:myList[0] = 5.6;
myList[1] = 4.5;
方法二:double[]myList = {1.9,2.9,3.4,3.5}(必须将声明、创建和初始化数组都放到一条语句中,否则会发生语法错误)
1.1.4 增强for语句
for(数组类型 单个对象在for语句中的代名:数组名){
}
1.1.5 将数组传递给方法
给方法不仅仅可以传递基础的数据类型,也可以给方法传递数组,例如下面:
public static void printArray(int[] array) {
}
这是一个给方法传数组的例子,一个int型数组的引用变量传给方法使用。而因为传给方法的值是引用值,所以在方法中程序也会直接跟着引用值找到存储这个数据的地方去进行动作,而不是像普通的变量一样,重新创建一个自己的空间放到在自己的堆栈中进行使用,不影响原来的值。引用变量会影响原来的值,要注意这一点。
方法返回数组:当方法返回数组时,数组的引用被返回(相当于返回了数组)
1.1.6 可变长参数
为什么会有可变长参数呢?看一个例子:
类型名...参数名(可变长参数声明)
public class Qutient{
public static void main(String[] args) {
printMax(34,3,3,2,56.5);
printMax(new double[] {1,2,3});
}
public static void printMax(double...numbers) {
if(numbers.length==0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for(int i = 1;i<numbers.length;i++) {
if(numbers[i]>result) {
result = numbers[i];
}
}
System.out.println("The max value is "+result);
}
}
求输入了的numbers里面的最大的那个数。Java将可变长参数当成数组对待,可以将一个数组或数目可变的参数传递给可变长参数,当用数目可变的参数调用方法时,Java会创建一个数组并把参数传给它。
1.2 数组的查找(常用)
1.2.1 线性查找法
将要查找的关键字key与数组中的元素逐个进行比较,直到找到关键字,如果匹配成功,则返回下标,如果没有匹配成功,则返回-1.优点:思想简单,缺点:效率低。
package com.lanhuigu.algotithm.arr;
/**
* 基于数组的线性查找
*/
public class SearchArrTest {
public static void main(String[] args) {
// 定义数组
int[] arr = {2, 4, 9, 8, 3, 6, 7};
// 目标元素
int target = 9;
// 目标元素的下标,默认为-1,表示没有找到元素
int index = -1;
// 查找目标元素,返回目标元素的下标
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
index = i;
}
}
// 打印目标元素的下标
System.out.println("index:" + index);
}
}
1.2.2 二分查找法
使用二分查找法的前提是数组中的元素必须已经排好序,接下来讨论算法思想:
假设数组已按升序排列。二分查找法首先将关键字与数组的中间元素进行比较,比较结果有以下三种情况:
(1)如果关键字小于中间元素,只需要在数组的前一半元素中继续查找关键字。
(2)如果关键字等于中间元素,查找成功。
(3)如果关键字大于中间元素。只需要在数组的后一半元素中继续查找关键字。
package other;
public class BinarySearch {
/*
* 循环实现二分查找算法arr 已排好序的数组x 需要查找的数-1 无法查到数据
*/
public static int binarySearch(int[] arr, int x) {
int low = 0;
int high = arr.length-1;
while(low <= high) {
int middle = (low + high)/2;
if(x == arr[middle]) {
return middle;
}else if(x <arr[middle]) {
high = middle - 1;
}else {
low = middle + 1;
}
}
return -1;
}
//递归实现二分查找
public static int binarySearch(int[] dataset,int data,int beginIndex,int endIndex){
int midIndex = (beginIndex+endIndex)/2;
if(data <dataset[beginIndex]||data>dataset[endIndex]||beginIndex>endIndex){
return -1;
}
if(data <dataset[midIndex]){
return binarySearch(dataset,data,beginIndex,midIndex-1);
}else if(data>dataset[midIndex]){
return binarySearch(dataset,data,midIndex+1,endIndex);
}else {
return midIndex;
}
}
public static void main(String[] args) {
int[] arr = { 6, 12, 33, 87, 90, 97, 108, 561 };
System.out.println("循环查找:" + (binarySearch(arr, 87) + 1));
System.out.println("递归查找"+binarySearch(arr,3,87,arr.length-1));
}
}
1.3 数组的排序(常用:选择排序法)
思想:先找到数列里面最小的数,和第一个进行交换;除了第一个再进行查找剩余最小的数,放到第二个位置中,以此类推进行排序。
1.4 Arrays类
要点:很常用的类,java.util.Arrays类包括一些实用的静态方法用于常见的数组操作,比如排序和查找。
使用与说明如下代码:
public static void main(String[] args) {
double[] numbers = {6.0,4.4,1.9,2.9,3.4,3.5};
Arrays.sort(numbers);//通过Array里面的方法对numbers进行排序
for(double number:numbers) {
System.out.println(number);
}
Arrays.binarySearch(numbers, 4.4);//二分查找numbers里的4.4,返回的是查找到的数组下标
char[] chars = {'a','A','4','F','D','P'};
Arrays.sort(chars, 1,3);//从char[1]到char[3-1]的部分数组排序
Arrays.equals(chars, chars);//判断两个数组是否严格相等
System.out.println(Arrays.toString(chars));//将数组里的数打印出来
}
2.1 二维数组基础
2.1.1 声明二维数组变量并创建二维数组
声明二维数组的语法: 数据类型[][] 数组名;(int[][] matrix;) 数据类型 数组名 [][];(int matrix[][];)
给第二行第一列的元素赋值为7语法:matrix[2][1]=7(每个下表都要放到一对方括号中,而不是[2,1])
2.1.2 获取二维数组的长度
二维数组实际上是一个其中每个元素都是一个一维数组的数组。假如x = new int[3][4] ,那么x[0]、x[1]、x[2]都是一维数组,每个数组都包含四个元素(x.length = 3 x[0].length = 4)(二维数组是一个一维数组,它的每个元素是另一个一维数组)
不规则数组(两种声明方式):
int[][]triangleArray = {
{1,2,3,4,5},
{2,3,4,5},
{3,4,5},
{4,5},
{5}
};
int [][]triangle = new int[5][];
triangle[0] = new int[5];
triangle[1] = new int[4];
triangle[2] = new int[3];
triangle[3] = new int[2];
triangle[4] = new int[1];
triangle[0][3] = 4;
triangle[4][0] = 5;
2.2 处理二维数组
要点:嵌套for循环常用于遍历处理二维数组
for(int row = 0;row<matrix.length;row++) {
for(int column = 0;column<matrix[row].length;column++) {
要调用的二维数组的语句;
}
}
将二维数组传递给方法
public static int[][] getArrays(int [][] m){
return m;
}
方法中的调用与return如上图所示。
2.3 多维数组
要点:二维数组由一些一维数组的数组组成,那么三维数组可以认为由一些二维数组的数组组成,以此类推,进行推广。
声明格式:double [][][] scores = new double[6][5][2]
不再赘述。