文章目录
1.数组
1.1 数组简介
数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
double[] hens = {3, 5, 1, 3.4, 2.5, 8, 7};
double totalWeight = 0;
for(int i = 0; i < hens.length; i++) {
totalWeight += hens[i];
}
System.out.println("总体重=" + totalWeight+ " 平均体重=" + (totalWeight / hens.length) );
1.2 数组的使用
【注】double scores[] <=> double[] scores
1.2.1 动态初始化
第一种动态分配方式
double scores[] = new double[5];
第二种动态分配方式, 先声明数组,再 new 分配空间
double scores[] ; //声明数组, 这时 scores 是 null
scores = new double[5]; //分配内存空间,可以存放数据
数组的引用 / 使用 / 访问 :
数组名[下标],如a[2]表示数组a的第3个元素
double scores[] = new double[5];
Scanner myScanner = new Scanner(System.in);
for(int i=0; i < scores.length; i++) {
System.out.println("请输入第"+ (i+1) +"个元素的值");
scores[i] = myScanner.nextDouble( );
}
System.out.println("==数组的元素/值的情况如下:===");
for(int i=0; i<scores.length; i++){
System.out.println("第"+ (i+1) +"个元素的值=" + scores[i]);
}
1.2.2 静态初始化
int a[] = {1, 2, 3, 4, 5};
1.2.3 数组使用细节
-
数组是多个相同类型数据的组合。
int[] arr = {1, 2, 3, 60, 1.1};//错误 double -> int int[] arr1 = {1, 2, 3, 60,"hello"};//错误 String -> int double[] arr2 = {1.1, 2.2, 3.3, 60.6, 100};//正确 int -> double
-
数组元素可以是 基本类型 或 引用类型。
String[] arr3 = {"北京","jack","milan"};
-
数组创建后,如果没有赋值,有默认值 int 0,short 0,byte 0,long 0,float 0.0,double 0.0,char \u0000,boolean false,String null。
-
数组下标必须在指定范围内使用,否则报错:下标越界异常(运行时报错)。
-
数组属于引用类型,数组型数据是对象(object)。
【例】创建一个 char 类型的 26 个元素的数组,分别放置’A’~‘Z’。使用 for 循环访问所有元素并打印出来。
char[] chars = new char[26];
for( int i = 0; i < chars.length; i++) {
//'A' + i 是 int , 且不是具体数值,需要强制转换再赋值
chars[i] = (char)('A' + i);
}
//循环输出
for( int i = 0; i < chars.length; i++) {
System.out.print(chars[i] + " ");
}
1.3 数组赋值机制
基本数据类型是值传递。下面 n2 的变化,不会影响到 n1 的值,因为拷贝的是值。
int n1 = 10;
int n2 = n1;
n2 = 80;
System.out.println("n1=" + n1);//10
System.out.println("n2=" + n2);//80
数组在默认情况下是引用传递,赋的值是地址。下面arr1的变化会影响arr2,因为拷贝的是地址。
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;//把arr1赋给arr2
arr2[0] = 10;
//arr1的值
System.out.println(" ====arr1的元素====");
for(int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
运行结果:
原理示意图:
既然把arr1直接赋给arr2时,会使两者指向同一片空间的地址,改变其中一个数组,另一个也随之改变;那么,如果要求改变新数组arr2时不影响原数组arr1,则需要另选方案,可以进行数组拷贝。
1.4 数组拷贝
将 int[] arr1 = {10, 20, 30}; 拷贝到 arr2 数组,要求数据空间是独立的。
int[] arr1 = {10,20,30};
//创建一个新的数组 arr2,开辟新的空间
//大小 arr1.length;
int[] arr2 = new int[arr1.length];
for(int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i];
}
1.5 数组反转
把数组 {11,22,33,44,55,66} 反转。
int[] arr = {11, 22, 33, 44, 55, 66};
for(int i = 0; i < arr.length/2; i++) {
int t = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = t;
}
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
1.6 数组扩容 / 缩减
将 arr{1, 2, 3} 扩充为 arr{1, 2, 3, 4}
int[] arr = {1, 2, 3};
int[] arrNew = new int[arr.length + 1];
for (int i=0; i<arr.length; i++)
{
arrNew[i] = arr[i];
}
arrNew[arrNew.length - 1] = 4;
arr = arrNew;
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
用户可以向 arr{1, 2, 3} 追加元素,并且可以不断追加,直至按下 “n”。
int[] arr = {1, 2, 3};
Scanner myScanner = new Scanner(System.in);
do
{
int[] arrNew = new int[arr.length + 1];
for (int i=0; i<arr.length; i++){
arrNew[i] = arr[i];
}
System.out.print("请输入要追加的元素:");
arrNew[arrNew.length - 1] = myScanner.nextInt();
arr = arrNew;
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.print("是否要继续追加元素(y/n):");
char ch = myScanner.next().charAt(0);
if (ch == 'n'){
break;
}
}while (true);
缩减数组,每次缩减最末尾的一个元素,直至用户按下“n”,或者数组中只剩一个元素时提醒不能再缩减。
int[] arr = {1, 2, 3, 4, 5};
Scanner myScanner = new Scanner(System.in);
do
{
int[] arrNew = new int[arr.length - 1];
for(int i=0; i<arrNew.length; i++){
arrNew[i] = arr[i];
}
arr = arrNew;
System.out.println("缩减后的数组为:");
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
System.out.print("是否要继续缩减数组(y/n):");
char ch = myScanner.next().charAt(0);
if(ch == 'n'){
break;
}else if(ch == 'y' && arr.length == 1){
System.out.println("当前数组长度为1,不能再继续缩减");
break;
}
}while (true);
2. 排序
2.1 排序的分类
内部排序:所有数据都加载到内存中进行排序。包括(交换式排序法、选择式排序法和插入式排序法);
外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
2.2 冒泡排序
int[] arr = {6, 3, 5, 7, 0};
for (int i=0; i<arr.length-1; i++)
{
for (int j=0; j<arr.length-i-1; j++)
{
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("===第"+(i+1)+"轮交换后的结果===");
for (int j=0; j<arr.length; j++)
{
System.out.print(arr[j]+" ");
}
System.out.print("\n");
}
3. 查找
在 java 中,我们常用的查找有两种:
(1) 顺序查找
(2) 二分查找【放在算法部分讲解】
猜数游戏中有这些名字:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王:从键盘中任意输入一个名字,判断其中是否包含此名字。 要求:如果找到了,就提示找到,并给出下标值。(采用顺序查找)
String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};
System.out.print("请输入要搜索的名字:");
Scanner myScanner = new Scanner(System.in);
String s = myScanner.next();
int index = -1;
for (int i=0; i<names.length; i++)
{
if(s.equals(names[i])){
index = i;
break;
}
}
if(index != -1){
System.out.println("该名字在第"+index+"个位置上");
}else{
System.out.println("该名字不存在");
}
4. 二维数组
4.1 二维数组内存布局
4.2 静态初始化
int[][] arr = {{1,1,1}, {8,8,9}};
【例】用二维数组输出如下矩阵:
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
//二维数组定义和赋初值
int[][] arr = { {0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 2, 0, 3, 0, 0},
{0, 0, 0, 0, 0, 0}
};
//二维数组遍历
//arr.length表示二维数组中有多少一维数组
//arr[i].length表示内含的一维数组有多少个元素
for (int i=0; i<arr.length; i++)
{
for (int j=0; j<arr[i].length; j++)
{
System.out.print(arr[i][j]+" ");//二维数组元素访问
}
System.out.println();
}
【注】若有int[][] arr = {{1,1,1}, {8,8,9}, {100}},其中的第三个一维数组不能直接写成 100,因为它应该是 int[] 类型。
4.3 动态初始化
使用方式 1:
int a[][]=new int[2][3];
使用方式 2:
int arr[][];
arr = new int[2][3];
上面两种操作进行之后,arr = {{0, 0, 0}, {0, 0, 0}}。
使用方式 3:创建列数不确定的二维数组
例:动态创建下面的二维数组,并输出。
1
2 2
3 3 3
//创建二维数组,内含3个一维数组,
//但每个一维数组还未开辟空间
int[][] arr = new int[3][];
for (int i=0; i<arr.length; i++)
{
//给每个一维数组开辟空间
//未给一维数组new空间时,arr[i]是null
arr[i] = new int[i+1];
//遍历一维数组,并给一维数组的每个元素赋值
for (int j=0; j<arr[i].length; j++)
{
arr[i][j] = i+1;
}
}
for (int i=0; i<arr.length; i++)
{
for (int j=0; j<arr[i].length; j++)
{
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
4.3 杨辉三角
使用二维数组打印 10 行的杨辉三角。
int[][] arr = new int[10][];
for (int i=0; i<arr.length; i++)
{
arr[i] = new int[i+1];
for (int j=0; j<arr[i].length; j++)
{
if (j==0 || j==arr[i].length-1)//每行第一个和最后一个
{
arr[i][j] = 1;
}else{
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
}
}
}
for (int i=0; i<arr.length; i++)
{
for (int j=0; j<arr[i].length; j++)
{
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
4.4 使用细节和注意事项
- 一维数组的声明方式有:
int[] x
或int x[]
- 二维数组的声明方式有:
int[][] y
或int[] y[]
或int y[][]
- 二维数组实际上由多个一维数组组成,其中的一维数组长度可以相同,也可以不同。比如:
int map [][] = {{1,2},{3,4,5}}
。map[0] 是含有2个元素的一维数组,map[1] 是含有3个元素的一维数组,map 也称为列数不等的二维数组。