如果说现在要求你定义100个整型变量,那么如果按照之前的做法,可能现在定义的的结构如下:
int i1, i2, i3, ... i100;
但是这个时候如果按照此类方式定义就会非常麻烦,因为这些变量彼此之间没有任何的关联,也就是说如果现在突然再有一个要求,要求你输出这100个变量的内容,意味着你要编写System.out.println()语句100次。
如何解决这个问题,Java语言提供了数组(Array)的数据结构,是一个容器可以存储相同数据类型的元素,可以将100个数存储到数组中。
/*
* 为什么要使用数组?
* */
public class ArrayTest01 {
public static void main(String[] args) {
/*
* 为什么要定义数组:
* 比如我们定义一批数据的时候,无论是存,还是取都非常麻烦; (10000)
* i1 - i10000 存: 向内存存储, 有10000个变量名 和 10000个变量值;1、非常浪费内存
* i1 - i10000 取: 从内存中取值,比如打印输出,10000次输出语句; 2、代码复用性低
*
* */
int i1 = 1;
int i2 = 2;
int i3 = 3;
int i4 = 4;
int i5 = 5;
for (int i = 1; i <= 5; i++) {
// 我们要输出i1 - i5变量对应的值
System.out.println("i" + i); //i1 - i5,输出的是i1-i5的字符串
//System.out.println("i1");
//System.out.println(i1); // 调用变量值
}
/*
* 如果要存储有关联的一批次的数据
* 商品1: 图片1,辣椒炒肉,18.5,1200
* 商品2: 图片2,西红柿鸡蛋,8.5,1500
* 3、变量之间的关联是松散的,不便于集中管理,不符合命名规范
* */
String goodsImg1 = "images/XX.jpg";
String goodsName1 = "辣椒炒肉";
double goodsPrice1 = 18.5;
int goodsSale1 = 1200;
String goodsImg2 = "images/YY.jpg";
String goodsName2 = "西红柿鸡蛋";
double goodsPrice2 = 8.5;
int goodsSale2 = 1500;
/*
* 总结:
* 1、通过一个数组名,可以存储n个值,节省内存空间
* 2、在我们遍历数据的时候,可以通过循环结合下标来快速实现遍历,提高代码复用性
* 3、数组存储数据,让我们数据便于集中管理,加强数组的关联性;
* */
}
}
数组概述:
数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
数组相关概念:
数组名:数组的名称,用于区分不同的数组,数组只有一个名称,即标识符,要符合标识符规范。
元素类型:数组要存储的元素的数据类型。
数组元素:向数组中存放的数据/元素。
元素下标:对数组元素进行编号,元素下标标明了元素在数组中的位置,从0开始;数组中的每个元素都可以通过下标来访问。
数组长度:数组长度固定不变,避免数组越界。
数组的特点:
数组是有序排列的集合。
数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
数组的元素的类型,必须一样。
创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
数组的长度是固定的,长度一旦确定,就不能修改。
我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
数组的分类:
按照维数:一维数组、二维数组、三维数组、...
注: 从二维数组开始,我们都称之为多维数组。
按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)。
声明数组的语法格式1:
元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
声明数组的语法格式2:
元素类型[] 数组名 = new 元素类型[]{元素,元素,……};
声明一个变量就是在内存空间划出一块合适的空间,声明一个数组就是在内存空间划出一串连续的空间。
注:
[]在元素类型后 或 数组名后都可以。
Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; //非法
数组初始化分类:
动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行
int[] arr = new int[3];
arr[0] = 3;
arr[1] = 9;
arr[2] = 8
静态初始化:在定义数组的同时就为数组元素分配空间并赋值。
int arr[] = new int[]{ 3, 9, 8}; 或 int[] arr = {3,9,8};
new关键字:
Java中使用关键字new来创建数组。
定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
示例代码:
public class LinearArrayTest01 {
public static void main(String[] args) {
// 变量声明
int num;
// 变量初始化
num = 10;
// 变量声明 + 初始化
int id = 1001;
// 数组声明
int[] ids;
// 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001, 1002, 1003, 1004};
// 动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
// 错误的写法:
// int[] arr1 = new int[];
// int[5] arr2 = new int[5];
// int[] arr3 = new int[3]{1,2,3};
//也是正确的写法:
int[] arr4 = {1, 2, 3, 4, 5};// 类型推断
// 总结:数组一旦初始化完成,其长度就确定了。
}
}
数组元素的引用方式:数组名[数组元素下标],如boy[0],boy[1]等。
数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2]
需要注意的是索引从0开始,到数组的长度-1结束。
示例代码:
public class LinearArrayTest02 {
public static void main(String[] args) {
// 创建一个长度为5的数组,用来存储学生的姓名
String[] names = new String[5];
// 给数组的指定位置赋值
names[0] = "张三";
names[1] = "李四";
names[2] = "王五";
names[3] = "马六";
names[4] = "田七";
// 数组长度5,下标从0开始,到4结束,使用下标5会抛出异常。
// names[5] = "钱八";
// 调用数组的指定位置的元素
System.out.println("下标2的学生的姓名是:" + names[2]);
}
}
每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)。
数组一旦初始化,其长度是不可变的。
示例代码:
public class LinearArrayTest03 {
public static void main(String[] args) {
int[] ids = new int[]{1001, 1002, 1003, 1004};
String[] names = new String[5];
System.out.println(names.length);// 5
System.out.println(ids.length);// 4
}
}
通过for循环,结合下标索引实现数组的遍历。
示例代码:
public class LinearArrayTest04 {
public static void main(String[] args) {
String[] names = {"张三", "李四", "王五", "马六", "田七"};
/*System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
System.out.println(names[3]);
System.out.println(names[4]);
*/
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
}
}
增强for循环:
foreach语句是java5的新特征之一,在遍历数组、集合方面,foreach为开发人员提供了极大的方便。
foreach语句是for语句的特殊简化版本,但是foreach语句并不能完全取代for语句,然而,任何的foreach语句都可以改写为for语句版本。
foreach的语句格式:
for(元素类型 元素变量x : 数组/集合){
引用了x的java语句;
}
public class LinearArrayTest05 {
public static void main(String[] args) {
String[] names = {"张三", "李四", "王五", "马六", "田七"};
for (String name : names) {
System.out.println(name);
}
}
}
练习题:
对数据进行处理:计算5位学生的平均分
public class LinearArrayTest06 {
public static void main(String[] args) {
int[] score = {60, 80, 90, 70, 85};
double avg;
avg = (score[0] + score[1] + score[2] + score[3] + score[4]) / 5;
// 上述写法虽说也可以实现,但是如果10个或100个学生呢?
}
}
public class LinearArrayTest07 {
public static void main(String[] args) {
// 通过遍历数组叠加求和,最后除以数组长度得到平均分。
int[] score = {60, 80, 90, 70, 85};
int sum = 0;
for (int i = 0; i < score.length; i++) {
sum += score[i];
}
double avg = sum / score.length;
}
}
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。
对于基本数据类型而言,默认初始化值各有不同。
对于引用数据类型而言,默认初始化值为null(注意与0不同!)
数组元素类型 | 元素默认初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | 0 或写为:’\u0000’(表现为空) |
boolean | false |
引用类型 | null |
示例代码:
public class LinearArrayTest08 {
public static void main(String[] args) {
int[] arr = new int[4];
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("------------------------");
short[] arr1 = new short[4];
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
System.out.println("------------------------");
float[] arr2 = new float[5];
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
System.out.println("------------------------");
char[] arr3 = new char[4];
for (int i = 0; i < arr3.length; i++) {
System.out.println("----" + arr3[i] + "----");
}
if (arr3[0] == 0) {
System.out.println("char类型的默认值是0,但是表现为空");
}
System.out.println("------------------------");
boolean[] arr4 = new boolean[5];
System.out.println(arr4[0]);
System.out.println("------------------------");
String[] arr5 = new String[5];
System.out.println(arr5[0]);
if (arr5[0] == null) {
System.out.println("引用类型的默认类型是null,不是null字符串!");
}
}
}
内存的简化结构:
栈(stack):存放基本类型的变量数据、局部变量和对象的引用,但对象本身不存放在栈中。
堆(heap):存放由new创建的对象和数组以及对象的实例变量。
静态存储区(static storage):又叫方法区:包含的都是在整个程序中永远唯一的元素,如class,static变量。
常量存储区(constant storage):常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。
静态区/静态域(static storage):随着类的加载而加载并初始化,存在于方法区内存中的字节码文件的静态区域中。
内存解析:
我们设定代码运行在main()中。
第一行代码:int[] ids = new int[4]; ids位于main()中,属于局部变量,存储在栈空间;new int[4],new 出来的都是存储在堆空间,并且开辟四个连续的区域存储默认值;把new出来的数组的首地址赋值给栈空间的ids变量;
第二到四行代码:覆盖数组的默认初始值;
第五行代码:String[] names = {...},虽说是静态赋值,但是流程和第一行代码类似,只是创建完数组就把默认值给覆盖了;
第六行代码:覆盖names数组下标1的值;
第七行代码:在堆内存中开辟两个连续的区域存储默认值,把新数组的首地址赋值给names,然后使用小黑、小明覆盖默认初始值;
注:字符串值其实不会存储在图上的位置,而是放在常量池,这个暂且不解析;
第八行代码:当我们调用names[0]的时候,肯定不会找0x2222,而是找0x3333,因为0x2222没有任何变量指向它,就会在某个不确定的时间被jvm回收。还要注意的是:当main()执行完毕,names-》ids出栈,0x3333和0x1111就没有任何变量指向它,也会在某个不确定的时间被jvm回收。
地址引用:
数组属于引用型变量,因此两个相同类型的数组且具有相同的引用,它们就有完全相同的元素。
例如,对于int a[] = {1,2,3}, b[ ]= {4,5};数组变量a和b分别存放着引用0x35ce36和0x757aef。
如果使用了下列赋值语句(a和b的类型必须相同)a=b;那么,a中存放的引用和b的相同,这时系统将释放最初分配给数组a的元素,使得a的元素和b的元素相同。
Java 语言里提供了支持多维数组的语法。
如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像Excel中的表格一样。
二维数组本质上是以数组作为数组元素的数组,即“数组的数组”,其实,从数组底层的运行机制来看,其实没有多维数组。
声明二位数组的语法格式1(动态初始化):int[][] arr = new int[3][2];
定义了名称为arr的二维数组
二维数组中有3个一维数组
每一个一维数组中有2个元素
一维数组的名称分别为arr[0], arr[1], arr[2]
给第一个一维数组1下标位赋值为78写法是:arr[0][1] = 78;
声明二位数组的语法格式1(动态初始化):int[][] arr = new int[3][];
二维数组中有3个一维数组。
每个一维数组都是默认初始化值null (注意:区别于格式1)
可以对这个三个一维数组分别进行初始化
arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2];
注:
int[][]arr = new int[][3]; //非法
声明二位数组的语法格式3(静态初始化):int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
定义一个名称为arr的二维数组,二维数组中有三个一维数组
每一个一维数组中具体元素也都已初始化
第一个一维数组 arr[0] = {3,8,2};
第二个一维数组 arr[1] = {2,7};
第三个一维数组 arr[2] = {9,0,1,6};
第三个一维数组的长度表示方式:arr[2].length;
注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。
Java中多维数组不必都是规则矩阵形式。
示例代码:
public class MultiArrayTest01 {
public static void main(String[] args) {
// 二维数组的声明和初始化
int[] arr = new int[]{1, 2, 3};//一维数组
// 静态初始化
int[][] arr1 = new int[][]{{1, 2, 3}, {4, 5}, {6, 7, 8}};
// 动态初始化1
String[][] arr2 = new String[3][2];
// 动态初始化2
String[][] arr3 = new String[3][];
// 错误的情况
// String[][] arr4 = new String[][4];
// String[4][3] arr5 = new String[][];
// int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};
//也是正确的写法:
int[] arr4[] = new int[][]{{1, 2, 3}, {4, 5, 9, 10}, {6, 7, 8}};
int[] arr5[] = {{1, 2, 3}, {4, 5}, {6, 7, 8}};
}
}
数组元素的引用方式:数组名[一维数组下标][二维数组下标],如boy[0][1],boy[1][1]等。
需要注意的是索引从0开始,到数组的长度-1结束。
示例代码:
public class MultiArrayTest02 {
public static void main(String[] args) {
int[][] arr1 = new int[][]{{1, 2, 3}, {4, 5}, {6, 7, 8}};
String[][] arr2 = new String[3][2];
String[][] arr3 = new String[3][];
System.out.println(arr1[0][1]);// 2
System.out.println(arr2[1][1]);// null
// 这样调用报错,因为没有给arr3[1]进行赋值操作,出现空指针异常
// System.out.println(arr3[1][0]);
arr3[1] = new String[4];
System.out.println(arr3[1][0]);
}
}
示例代码:
public class MultiArrayTest03 {
public static void main(String[] args) {
int[] arr4[] = new int[][]{{1, 2, 3}, {4, 5, 9, 10}, {6, 7, 8}};
System.out.println(arr4.length);// 3
System.out.println(arr4[0].length);// 3
System.out.println(arr4[1].length);// 4
}
}
规定:二维数组分为外层数组的元素,内层数组的元素
int[][] arr = new int[4][3];
外层元素:arr[0],arr[1]等
内层元素:arr[0][0],arr[1][2]等
System.out.println(arr[0]);//[I@15db9742
System.out.println(arr[0][0]);//0
示例代码:
public class MultiArrayTest04 {
public static void main(String[] args) {
//声明二维数组并赋值 int arr[][] = {{},{},{}}
int arr[][] = {{1, 2, 3}, {11, 12, 13, 14}, {22, 33, 44, 55, 66, 77}, {1}};
// arr 是数组
// arr[i] 还是数组
for (int i = 0; i < arr.length; i++) {
int ewArr[] = arr[i]; //二维数组里面的每个数组
for (int j = 0; j < ewArr.length; j++) {
System.out.print(ewArr[j] + "\t");
}
System.out.println();
}
System.out.println("--------------------------------");
// 增强for循环遍历
for (int ewArr[] : arr) {
for (int x : ewArr) {
System.out.print(x + "\t");
}
System.out.println();
}
}
}
针对于初始化方式一:比如:int[][] arr = new int[4][3];
外层元素的初始化值为:地址值
内层元素的初始化值为:与一维数组初始化情况相同
针对于初始化方式二:比如:int[][] arr = new int[4][];
外层元素的初始化值为:null
示例代码:
public class MultiArrayTest05 {
public static void main(String[] args) {
int[][] arr = new int[4][3];
System.out.println(arr[0]);//[I@15db9742
System.out.println(arr[0][0]);//0
// System.out.println(arr);//[[I@6d06d69c
System.out.println("*****************");
float[][] arr1 = new float[4][3];
System.out.println(arr1[0]);//地址值
System.out.println(arr1[0][0]);//0.0
System.out.println("*****************");
String[][] arr2 = new String[4][2];
System.out.println(arr2[1]);//地址值
System.out.println(arr2[1][1]);//null
System.out.println("*****************");
double[][] arr3 = new double[4][];
System.out.println(arr3[1]);//null
// System.out.println(arr3[1][0]);//报错
}
}
练习题1:
杨辉三角,是二项式系数在三角形中的一种几何排列。在欧洲,这个表叫做帕斯卡三角形。帕斯卡是在1654年发现这一规律的,比杨辉要迟393年,比贾宪迟600年。杨辉三角是中国古代数学的杰出研究成果之一,它把二项式系数图形化,把组合数内在的一些代数性质直观地从图形中体现出来,是一种离散型的数与形的结合 。
使用二维数组打印一个 10 行杨辉三角。
【提示】
1. 第一行有 1 个元素, 第 n 行有 n 个元素
2. 每一行的第一个元素和最后一个元素都是 1
3. 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
public class YangHuiTest {
public static void main(String[] args) {
// 1、声明并初始化二维数组
int[][] yangHui = new int[10][];
// 2、给数组的元素赋值
for(int i = 0;i < yangHui.length;i++){
yangHui[i] = new int[i + 1];
// 给首末元素赋值
yangHui[i][0] = yangHui[i][i] = 1;
// 给每行的非首末元素赋值
if(i > 1){
for(int j = 1;j < yangHui[i].length - 1;j++){
yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
}
}
}
// 3、遍历二维数组
for(int i = 0;i < yangHui.length;i++){
for(int j = 0;j < yangHui[i].length;j++){
System.out.print(yangHui[i][j] + " ");
}
System.out.println();
}
}
}
练习题2:
创建一个长度为6的int型数组,要求取值为1-30,同时元素值各不相同
public class ArrayRandom {
public static void main(String[] args) {
int[] arr = new int[6];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 30) + 1;
for (int j = 0; j < i; j++) {
if (arr[i] == arr[j]) {
i--;
break;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
要求:所有随机数都是两位数。
import java.util.Scanner;
public class ArrayOperation {
public static void main(String[] args) {
int[] arr = new int[10];
// 随机10 - 99的整数
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * (100 - 10) + 10);
}
// 遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
// 求数组元素的最大值
int maxValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (maxValue < arr[i]) {
maxValue = arr[i];
}
}
System.out.println("最大值为:" + maxValue);
// 求数组元素的最小值
int minValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (minValue > arr[i]) {
minValue = arr[i];
}
}
System.out.println("最小值为:" + minValue);
// 求数组元素的总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("总和为:" + sum);
// 求数组元素的平均数
int avgValue = sum / arr.length;
System.out.println("平均数为:" + avgValue);
}
}
使用简单数组
(1)创建一个名为ArrayCopy的类,在main()方法中声明array1和array2两个变量,它们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值 (如array[0]=0,array[2]=2)。打印出array1。
思考:array1和array2是什么关系?
public class ArrayCopy {
public static void main(String[] args) { //alt + /
int[] array1, array2;
array1 = new int[]{2, 3, 5, 7, 11, 13, 17, 19};
//显示array1的内容
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
//赋值array2变量等于array1
//不能称作数组的复制。
array2 = array1;
//修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
for (int i = 0; i < array2.length; i++) {
if (i % 2 == 0) {
array2[i] = i;
}
}
System.out.println();
//打印出array1
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
// array1和array2是什么关系?array1和array2地址值相同,都指向了堆空间的唯一的一个数组实体。
}
}
解析:
拓展:修改题目,实现array2对array1数组的复制
public class ArrayCopy {
public static void main(String[] args) { //alt + /
int[] array1, array2;
array1 = new int[]{2, 3, 5, 7, 11, 13, 17, 19};
//显示array1的内容
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
//数组的复制:
array2 = new int[array1.length];
for (int i = 0; i < array2.length; i++) {
array2[i] = array1[i];
}
//修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
for (int i = 0; i < array2.length; i++) {
if (i % 2 == 0) {
array2[i] = i;
}
}
System.out.println();
//打印出array1
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
}
}
把如下数组进行反转:
String arr[] = new String[]{"AA","BB","CC","DD","EE","FF","GG"};
public class ArrayReverse01 {
public static void main(String[] args) {
String arr[] = new String[]{"AA", "BB", "CC", "DD", "EE", "FF", "GG"};
for (int i = 0; i < arr.length / 2; i++) {
String temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
//遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
public class ArrayReverse02 {
public static void main(String[] args) {
String arr[] = new String[]{"AA", "BB", "CC", "DD", "EE", "FF", "GG"};
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
String temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
线性查找又叫顺序查找,就是遍历整个列表,逐个元素与给定值比较,若某个元素和给定值相等,则查找成功。如果直到最后一个元素和给定值比较都不相等,则查找失败。
public class ArraySequentialSearch {
public static void main(String[] args) {
String arr[] = new String[]{"AA", "BB", "CC", "DD", "EE", "FF", "GG"};
String findStr = "BB";
findStr = "QQ";
boolean isFlag = true;
for(int i = 0;i < arr.length;i++){
if(findStr.equals(arr[i])){
System.out.println("找到了指定的元素,位置为:" + i);
isFlag = false;
break;
}
}
if(isFlag){
System.out.println("很遗憾,没有找到你要查询的元素!");
}
}
}
什么是二分查找呢?二分查找的基本思想是:在有序表中,取中间元素作为比较对象,若给定值与中间元素相等,则查找成功;若给定值小于中间元素,则在中间元素的左半区继续查找;若给定值大于中间元素,则在中间元素的右半区继续查找。不断重复上述过程,直到找到为止。
从二分查找的定义我们可以看出,使用二分查找有两个前提条件:
(1)待查找的列表必须有序。
(2)必须使用线性表的顺序存储结构来存储数据。
接下来我们来介绍一下折半查找的原理,并自己用代码实现折半查找。
在查找前对数组进行折半操作 (初始化指针位置)
折半公式 = (最大索引+最小索引)/ 2
首先我们可以利用指针思想,假设有一个指针指向最大值(MAX),有一个指针指向最小值(MIN),还有一个指针指向的是最大值和最小值之间的索引(MID)。我把这个过程称为初始化指针位置.
折半后的指针索引和被查找元素比较
若被查找元素的值(12)大于中间索引上的值(10),我们就把最小值指针(MIN)移动到中间指针(MID)索引的下一个索引位置,如下图:
若没有匹配到就继续折半后的指针索引和被查找元素比较。
若被查找元素的值(12)小于中间索引上的值(15),我们就把最大值指针(MAX)移动到中间指针(MID)索引的上一个索引位置,如下图:
若没有匹配到就继续折半后的指针索引和被查找元素比较
若被查找元素的值(12)小于中间索引上的值(13),我们就把最大值指针(MAX)移动到中间指针(MID)索引的上一个索引位置,如下图:
若没有匹配到就继续折半后的指针索引和被查找元素比较。
当小指针(MIN)的索引(4)超过了大指针(MAX)的索引(3)时,就需要停止查找了,如果真有这种情况发生,说明没有查到被查找元素的值(12),此时会返回一个负数(-1),当然如果查找到了就返回其在数组中的索引即可。
数组的折半查找代码实现
public class ArrayBinarySearch {
public static void main(String[] args) {
int[] arr = new int[]{1, 4, 7, 10, 13, 15, 21, 25};
int findNum = 21;
// 初始的最小索引
int min = 0;
// 初始的末索引
int max = arr.length - 1;
boolean isFlag = true;
while (min <= max) {
int mid = (min + max) / 2;
if (findNum == arr[mid]) {
System.out.println("找到了指定的元素,位置为:" + mid);
isFlag = false;
break;
} else if (arr[mid] > findNum) {
max = mid - 1;
} else {//arr[middle] < findNum
min = mid + 1;
}
}
if (isFlag) {
System.out.println("很遗憾,没有找到你要查询的元素!");
}
}
}
冒泡概述
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
实现原理
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
实现思路
(1)第一次比较:首先比较第一和第二个数,将小数放在前面,将大数放在后面。
(2)比较第2和第3个数,将小数 放在前面,大数放在后面。
......
(3)如此继续,知道比较到最后的两个数,将小数放在前面,大数放在后面,重复步骤,直至全部排序完成
(4)在上面一趟比较完成后,最后一个数一定是数组中最大的一个数,所以在比较第二趟的时候,最后一个数是不参加比较的。
(5)在第二趟比较完成后,倒数第二个数也一定是数组中倒数第二大数,所以在第三趟的比较中,最后两个数是不参与比较的。
(6)依次类推,每一趟比较次数减少依次
实例解析
排序数组:[10,1,35,61,89,36,55]
冒泡代码
/*
* 使用冒泡排序实现升序排列
* 冒泡排序(升序)的原理:
* 两两比较,如果前面的值比后面的值大,则交换位置
* 外层i 0 1 2 3 4
* 原数组 第一轮 第二轮 第三轮 第四轮 第五轮 外层循环5次 arr.length-1 6 - 1
* 98 78 56 44 23 6
* 78 56 44 23 6 23
* 56 44 23 6 44 44
* 44 23 6 56 56 56
* 23 6 78 78 78 78
* 6 98 98 98 98 98
*
* 次数 5 4 3 2 1
* 内层 arr.length-1-i
* 第一轮得到一个最大值,这个最大值
* 1.外层循环初始变量i为0,判断依据 i < arr.length - 1
* 2.内存循环初始边框j为0,判断依据 j < arr.length - i - 1
* 3.判断谁大或谁小,然后交换位置
*/
int arr[] = {32,5,100,9,78,1};
for(int i = 0;i < arr.length - 1;i++) { //用来决定轮数 5
for(int j = 0; j < arr.length - i -1;j++) { //用来决定每轮比较的次数
if(arr[j] > arr[j+1]) {
//temp保存哪个值无所谓,但是保存哪个值,就要先给哪个值赋值
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
System.out.println("冒泡升序排列之后:"+Arrays.toString(arr));
选择排序(Selection sort)是一种简单直观的排序算法。
它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
实例解析
第1趟比较:拿第1个元素依次和它后面的每个元素进行比较,如果第1个元素大于后面某个元素,交换它们,经过第1趟比较,数组中最小的元素被选出,它被排在第一位
第2趟比较:拿第2个元素依次和它后面的每个元素进行比较,如果第2个元素大于后面某个元素,交换它们,经过第2趟比较,数组中第2小的元素被选出,它被排在第二位
......
第n-1趟比较:第n-1个元素和第n个元素作比较,如果第n-1个元素大于第n个元素,交换它们.
选择代码
/*
* 选择排序 - 升序排列:
* 使用指定位置的值,跟所有的值进行比较;如果前面的值大于后面的值,则交换位置
*
* 外层循环变量 0 1 2 3
* 原数组 第一轮 第二轮 第三轮 第四轮 比较了四次,外层循环 arr.length - 1
* 120 10 10 10 10
* 89 120 18 18 18
* 32 89 120 32 32
* 18 32 89 120 89
* 10 18 32 89 120
*
* 次数 4 3 2 1 看似: arr.length - i - 1
*
* 1. 外层循环初始变量i为0,小于arr.length - 1
* 2. 内层循环初始变量j为i,小于arr.length - 1
* j = 0 < 4
* j = 1 < 4
* j = 2 < 4
*/
int arr[] = {32,2,78,6,44,100};
for(int i = 0;i < arr.length - 1;i++) {
for(int j = i; j < arr.length - 1;j++) {
/*
* i = 0 arr[i] = 2
* j = 0 32 2 --> 2 arr[j+1] = 32
*/
if(arr[i] > arr[j+1]) {
int temp = arr[j+1];
arr[j+1] = arr[i];
arr[i] = temp;
}
}
}
System.out.println("选择排序之后的数组:"+Arrays.toString(arr));
所在包:java.util.Arrays
类的定义:
public class Arrays extends Object
此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。
除非特别注明,否则如果指定数组引用为 null,则此类中的方法都会抛出 NullPointerException。
Arrays类里面的方法全部都是静态方法;
static
Arrays.asList的作用是将数组转化为list,一般是用于在初始化的时候,设置几个值进去,简化代码,省去add的部分。
参数:
1、直接定义n个具体的数据。
2、传递非基本数据类型的数组,如果是基本数据类型,那么使用包装类数组。
也可以是数组[但是数组类型不能是(byte,short,int,long,float,double,boolean),如果是基本数据类型的数组,会把数组作为一个整体],可以是Integer等包装类。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArraysTest01 {
public static void main(String[] args) {
// List ebsCodes = Arrays.asList("USERNAME","REAP","NLS");
List ebsCodes = Arrays.asList(12, 22, 33); //存储包装类Integer
// 把数组转换为集合,数组不能是基本类型的数组
String[] s = {"aa", "bb", "cc"};
List strlist = Arrays.asList(s);
//上述代码等价于(但是又存在不同之处):
List ebsCodes = new ArrayList();
ebsCodes.add("USERNAME");
ebsCodes.add("REAP");
ebsCodes.add("NLS");
}
}
注意:
(1)该方法不适用于基本数据类型(byte,short,int,long,float,double,boolean),可以是包装类。
(2)该方法将数组与列表链接起来,当更新其中之一时,另一个自动更新。
(3)不支持add和remove方法。
最重要的一点就是,不支持add和remove,如果不需要改变长度可以使用Arrays.asList()。
调用Arrays.asList()生产的List的add、remove方法时报java.lang.UnsupportedOperationException异常,这是由Arrays.asList() 返回的是Arrays的内部类ArrayList, 而不是java.util.ArrayList。
static void sort(参数数据 arr) 对指定类型数组按数字升序进行排序。
参数介绍:
arr - 要搜索的数组(byte/short/int/long/float/double/char/Object)
static void sort(参数数据 arr, int fromIndex, int toIndex) 对指定 byte 型数组的指定范围按数字升序进行排序。
参数介绍:
arr - 要搜索的数组(byte/short/int/long/float/double/char/Object);
fromIndex - 要排序的第一个元素的索引(包括);
toIndex - 要排序的最后一个元素的索引(不包括);
import java.util.Arrays;
public class ArraysTest02 {
public static void main(String[] args) {
//static void sort(int[] a) 对指定的 int 型数组按数字升序进行排序。
int arr[] = {31, 89, 9, 2, 77, 6, 100};
Arrays.sort(arr); //对原数组进行排序
//Arrays.toString(数组) 把数组的内容输出
System.out.println(Arrays.toString(arr)); //已经升序排列 [2, 6, 9, 31, 77, 89, 100]
/*
* 在Arrays这个API里面,没有给我们提供降序排列的方法
*/
/*
* 反转数组
* 七个值: 3次
* 八个值: 4次
*
* 数组长度/2
* 0 6
* 1 5
* 2 4
*
*/
//对数组进行逆序排列
for (int i = 0; i < arr.length / 2; i++) {
//先得定义一个临时变量来存储某个值
int temp = arr[i];
//把后面的赋值给前面的
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
System.out.println(Arrays.toString(arr)); //通过自己代码实现数组的逆序排列
}
}
static int binarySearch(参数数组 arr, 对应数组的key) 使用二分搜索法来搜索指定类型数组,以获得指定的值。必须在进行此调用之前对数组进行排序(通过 sort(byte[]) 方法)。如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个。
参数介绍:
arr - 要搜索的数组(byte/short/int/long/float/double/char/Object);
key - 要搜索的值;
返回值介绍:
如果它包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入数组的那一点:即第一个大于此键的元素索引,如果数组中的所有元素都小于指定的键,则为 a.length。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
static int binarySearch(参数数组 arr, int fromIndex, int toIndex, 对应数组的key) 使用二分搜索法来搜索指定类型数组的范围,以获得指定的值。
参数介绍:
arr - 要搜索的数组(byte/short/int/long/float/double/char/Object);
fromIndex - 要搜索的第一个元素的索引(包括);
toIndex - 要搜索的最后一个元素的索引(不包括);
key - 要搜索的值;
返回值介绍:
如果它包含在数组的指定范围内,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入数组的那一点:即范围中第一个大于此键的元素索引,如果范围中的所有元素都小于指定的键,则为 toIndex。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
public class ArraysTest03 {
public static void main(String[] args) {
int[] arr3 = new int[]{-98, -34, 2, 34, 54, 66, 79, 105, 210, 333};
int index = Arrays.binarySearch(arr3, 210);
if (index >= 0) {
System.out.println(index);
} else {
System.out.println("未找到");
}
}
}
static 参数类型数组 copyOf(参数数组 arr, int newLength) 复制指定的数组,截取或用默认值填充(如有必要),以使副本具有指定的长度。
参数介绍:
original - 要复制的数组(byte/short/int/long/float/double/char/Object/boolean);
newLength - 要返回的副本的长度;
返回:
原数组的副本,截取或用默认值元素填充以获得指定的长度;
默认值:
数值类型 - 0/0.0;
布尔类型 - false;
字符类型 - 空字符;
引用类型 - null;
抛出:
NegativeArraySizeException - 如果 newLength 为负;
NullPointerException - 如果 original 为 null;
public class ArraysTest04 {
public static void main(String[] args) {
int[] arr1 = new int[]{1, 2, 3, 4};
// 复制的长度超过原数组长度,默认值填充
int[] newArr1 = Arrays.copyOf(arr1, 7);
// 复制的长度不超过原数组长度,截取
int[] newArr2 = Arrays.copyOf(arr1, 2);
// 输出
System.out.println(Arrays.toString(newArr1));
System.out.println(Arrays.toString(newArr2));
}
}
static 参数类型数组 copyOfRange(参数数组 arr, int from, int to) 将指定数组的指定范围复制到一个新数组。
参数介绍:
original - 要复制的数组(byte/short/int/long/float/double/char/Object/boolean);
from - 要复制的范围的初始索引(包括);
to - 要复制的范围的最后索引(不包括)。(此索引可能位于数组范围之外)。
返回:
包含取自原数组指定范围的新数组,截取或用默认值元素填充以获得所需长度;
抛出:
ArrayIndexOutOfBoundsException - 如果 from < 0 或 from > original.length();
IllegalArgumentException - 如果 from > to;
NullPointerException - 如果 original 为 null;
static String toString(参数数组 arr) 返回指定数组内容的字符串表示形式。
参数数组 arr: 任意数据类型的数组
static String deepToString(参数数组 arr) 返回指定数组“深层内容”的字符串表示形式。
返回指定数组“深层内容”的字符串表示形式。如果数组包含作为元素的其他数组,则字符串表示形式包含其内容等。此方法是为了将多维数组转换为字符串而设计的。
static boolean equals(参数数组 arr1,参数数组 arr2) 如果两个指定类型数组彼此相等,则返回 true。
参数介绍:
arr1 - 将测试其相等性的一个数组;
arr2 - 将测试其相等性的另一个数组;
如果两个指定的 boolean 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。此外,如果两个数组引用都为 null,则认为它们是相等的。
import java.util.Arrays;
public class ArraysTest05 {
public static void main(String[] args) {
// boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1, 2, 3, 4};
int[] arr2 = new int[]{1, 3, 2, 4};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);
}
}
static void fill(参数数组 arr1, 参数类型 val) 将指定类型的值分配给指定类型数组的每个元素。
参数:
arr1 - 要填充的数组;
val - 要存储在数组所有元素中的值;
static void fill(参数数组 arr1, int fromIndex, int toIndex, 参数类型 val) 将指定类型的值分配给指定类型数组指定范围中的每个元素。
参数:
arr1 - 要填充的数组;
fromIndex - 要使用指定值填充的第一个元素的索引(包括);
toIndex - 要使用指定值填充的最后一个元素的索引(不包括);
val - 要存储在数组所有元素中的值;
抛出:
IllegalArgumentException - 如果 fromIndex > toIndex;
ArrayIndexOutOfBoundsException - 如果 fromIndex < 0 或 toIndex > a.length;
public class ArraysTest06 {
public static void main(String[] args) {
int[] arr1 = new int[]{1, 2, 3, 4};
// void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1, 10);
System.out.println(Arrays.toString(arr1));
}
}
数组脚标越界异常(ArrayIndexOutOfBoundsException)。
int[] arr = new int[2];
System.out.println(arr[2]);
System.out.println(arr[-1]);
访问到了数组中的不存在的脚标时发生。
空指针异常(NullPointerException)。
int[] arr = null;
System.out.println(arr[0]);
arr引用没有指向实体,却在操作实体中的元素时。
1、某小区单间短期出租4个月,550元/月(水电煤公摊,网费35元/月),空调、卫生间、厨房齐全。屋内均是IT行业人士,喜欢安静。所以要求来租者最好是同行或者刚毕业的年轻人,爱干净、安静。电话如下代码:
public class ArrayTest {
public static void main(String[] args) {
int[] arr = new int[]{8, 2, 1, 0, 3};
int[] index = new int[]{2, 0, 3, 2, 4, 0, 1, 3, 2, 3, 3};
String tel = "";
for (int i = 0; i < index.length; i++) {
tel += arr[index[i]];
}
System.out.println("联系方式:" + tel); // 联系方式:18013820100
}
}
2、从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
成绩>=最高分-10 等级为’A’
成绩>=最高分-20 等级为’B’
成绩>=最高分-30 等级为’C’
其余 等级为’D’
提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
import java.util.Scanner;
public class ScoreTypes {
public static void main(String[] args) {
//1.使用Scanner,读取学生个数
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生人数:");
int number = scanner.nextInt();
//2.创建数组,存储学生成绩:动态初始化
int[] scores = new int[number];
//3.给数组中的元素赋值
System.out.println("请输入" + number + "个学生成绩:");
int maxScore = 0;
for (int i = 0; i < scores.length; i++) {
scores[i] = scanner.nextInt();
//4.获取数组中的元素的最大值:最高分
if (maxScore < scores[i]) {
maxScore = scores[i];
}
}
// for(int i = 0;i < scores.length;i++){
// if(maxScore < scores[i]){
// maxScore = scores[i];
// }
// }
//5.根据每个学生成绩与最高分的差值,得到每个学生的等级,并输出等级和成绩
char level;
for (int i = 0; i < scores.length; i++) {
if (maxScore - scores[i] <= 10) {
level = 'A';
} else if (maxScore - scores[i] <= 20) {
level = 'B';
} else if (maxScore - scores[i] <= 30) {
level = 'C';
} else {
level = 'D';
}
System.out.println("student " + i +
" score is " + scores[i] + ",grade is " + level);
}
}
}
3、获取arr数组中所有元素的和。
提示:使用for的嵌套循环即可。
public class ArraySum {
public static void main(String[] args) {
int[][] arr = new int[][]{{3, 5, 8}, {12, 9}, {7, 0, 6, 4}};
// 记录总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j];
}
}
System.out.println("总和为:" + sum);
}
}
4、回形数格式方阵的实现:
从键盘输入一个整数(1~20),则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。
例如: 输入数字2,则程序输出:
1 2
4 3
输入数字3,则程序输出:
1 2 3
8 9 4
7 6 5
输入数字4, 则程序输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
import java.util.Scanner;
class RectangleTest01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入一个数字");
int len = scanner.nextInt();
int[][] arr = new int[len][len];
int s = len * len;
/*
* k = 1:向右 k = 2:向下 k = 3:向左 k = 4:向上
*/
int k = 1;
int i = 0, j = 0;
for (int m = 1; m <= s; m++) {
if (k == 1) {
if (j < len && arr[i][j] == 0) {
arr[i][j++] = m;
} else {
k = 2;
i++;
j--;
m--;
}
} else if (k == 2) {
if (i < len && arr[i][j] == 0) {
arr[i++][j] = m;
} else {
k = 3;
i--;
j--;
m--;
}
} else if (k == 3) {
if (j >= 0 && arr[i][j] == 0) {
arr[i][j--] = m;
} else {
k = 4;
i--;
j++;
m--;
}
} else if (k == 4) {
if (i >= 0 && arr[i][j] == 0) {
arr[i--][j] = m;
} else {
k = 1;
i++;
j++;
m--;
}
}
}
// 遍历
for (int m = 0; m < arr.length; m++) {
for (int n = 0; n < arr[m].length; n++) {
System.out.print(arr[m][n] + "\t");
}
System.out.println();
}
}
}
import java.util.Scanner;
class RectangleTest02 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入一个数字");
int n = scanner.nextInt();
int[][] arr = new int[n][n];
int count = 0; // 要显示的数据
int maxX = n - 1; // x轴的最大下标
int maxY = n - 1; // Y轴的最大下标
int minX = 0; // x轴的最小下标
int minY = 0; // Y轴的最小下标
while (minX <= maxX) {
for (int x = minX; x <= maxX; x++) {
arr[minY][x] = ++count;
}
minY++;
for (int y = minY; y <= maxY; y++) {
arr[y][maxX] = ++count;
}
maxX--;
for (int x = maxX; x >= minX; x--) {
arr[maxY][x] = ++count;
}
maxY--;
for (int y = maxY; y >= minY; y--) {
arr[y][minX] = ++count;
}
minX++;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
String space = (arr[i][j] + "").length() == 1 ? "0" : "";
System.out.print(space + arr[i][j] + " ");
}
System.out.println();
}
}
}
1、声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:
a ) x[0] = y; no
b) y[0] = x; yes
c) y[0][0] = x; no
d) x[0][0] = y; no
e) y[0][0] = x[0]; yes
f) x = y; no
提示:
一维数组:int[] x 或者int x[]
二维数组:int[][] y 或者 int[] y[] 或者 int y[][]
2、下面数组定义正确的有:
A.String strs[] = {"a" "b" "c"};
B.String[] strs = {"a", "b", "c"};
C.String[] strs = new String{"a" "b" "c"};
D.String strs[] = new String[]{"a", "b", "c"};
E.String[] strs = new String[3]{"a", "b", "c"};
正确:B D
3、分析程序,并写出执行结果
public class Test{
public static void main(String[] args){
int i,s= 0;
int a[] = {10,20,30,40,50,60,70,80,90};
for(i=0;i
1、为什么要使用数组?
当我们定义一批有关联的数据的时候,Java变量的局限性导致无论存还是取都比较麻烦;
1.非常浪费内存
2.代码复用性低
3.变量之间的关联是松散的,不便于集中管理
2、什么是数组以及Java数组的特点?
数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
1.数组是有序排列的集合。
2.数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
3.数组的元素的类型,必须一样。
4.创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
5.数组的长度是固定的,长度一旦确定,就不能修改。
6.我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
3、数组的基本要素?
数组名:数组的名称,用于区分不同的数组,数组只有一个名称,即标识符,要符合标识符规范。
元素类型:数组要存储的元素的数据类型。
数组元素:向数组中存放的数据/元素。
元素下标:对数组元素进行编号,元素下标标明了元素在数组中的位置,从0开始;数组中的每个元素都可以通过下标来访问。
数组长度:数组长度固定不变,避免数组越界。
4、数组的分类?
按照维数:一维数组、二维数组、三维数组、...
注: 从二维数组开始,我们都称之为多维数组。
按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)。
5、数组元素/成员变量的默认值?
数组元素类型 | 元素默认初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | 0 或写为:’\u0000’(表现为空) |
boolean | false |
引用类型 | null |
6、如何获取数组的长度?
每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)。
7、数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。String有length()这个方法。
8、Java能动态分配数组吗?
可以。
9、Java中的任何数据类型都可以使用System.out.pritln方法显示吗?
对基本数据类型而言,输出的往往是变量的值;
对于像数组这一类复杂的数据类型,输出的是其堆空间中存储位置的hashCode值;
10、二维数组的本质?
二维数组本质上是以数组作为数组元素的数组,即“数组的数组”。
11、一维数组和二维数组内存分析?
见课件。
12、通过代码实现数组反转?
String arr[] = new String[]{"AA", "BB", "CC", "DD", "EE", "FF", "GG"};
System.out.println("反转之前:");
for (String str : arr) {
System.out.print(str + "\t");
}
System.out.println("\n-------------------------------------------");
/*
* 分析:
* 长度7 奇数 7/2 = 3
* 0 6
* 1 5
* 2 4
* 长度6 偶数 6/2 = 3
*
* 交换的次数: 数组长度 / 2
* */
/*for(int i = 0;i < arr.length / 2;i++){
// 定义临时变量
String temp = arr[i]; // 临时变量保存的是哪个,就先给哪个赋值
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}*/
for(int i = 0,j = arr.length - 1;i < j;i++,j--){ // i = 3 j = 3
// 定义临时变量
String temp = arr[i]; // 临时变量保存的是哪个,就先给哪个赋值
arr[i] = arr[j];
arr[j] = temp;
}
System.out.println("反转之后:");
for (String str : arr) {
System.out.print(str + "\t");
}