JavaSE学习历程
第一章:Java初识
第二章:Java语言基础
第三章:选择结构与分支结构
第四章:循环结构
第五章:方法/函数
第六章:数组
1 数组的概念
概念:一组连续的存储空间,存储多个相同的数据类型的值
特点:
1. 数组是序排列的
2. 数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型,同一数组内各个元素的数据类型相同
3. 创建数组对象会在内存中开辟一整块连续的空间
4. 数组的长度一旦确定,就不能修改。
2 数组的组成
数组中的每个数据格被称为“数据元素”;
对每个数据元素进行赋值或取值的操作称为“元素的访问”;
访问元素时,需要使用下标,且数组的下标从0开始;
访问语法:数组名[下标];例:存:a[0] = 10;取:a[0];
3 数组的声明与赋值
先声明、再分配空间:
数据类型[] 数组名;
数组名 = new 数据类型[长度];
声明并分配空间:
数据类型[] 数组名 = new 数据类型[长度];
声明并赋值(繁):
数据类型[] 数组名 = new 数据类型[]{value1,value2,value3,…};
声明并赋值(简):
数据类型[] 数组名 = {value1,value2,value3,…}; (显示初始化,注意:不可换行)。
在没有为数组元素赋值的情况下,数组依旧可以正确访问,数组有默认值
数组的默认值:
整数:0
小数:0.0
字符:\u0000 (空字符)
布尔:false
其他:null :注意String不能使用null的值引用方法或属性,会爆出空指针异常
空指针异常,找最近的错误行数,找 .属性 再一步步向上查找错误位置!
public class TestCreates{
public static void main(String[] args){
//先声明、再分配空间
int[] array1;
array1 = new int[4];
//System.out.println( array1[0] );
//声明并分配空间
int[] array2 = new int[4];
//声明并赋值(繁)
int[] array3;
array3 = new int[]{ 11 , 22 , 33};
for(int i = 0 ; i < array3.length ; i++){
System.out.println( array3[i] );
}
//声明并赋值(简)
int[] array4 = { 66,77,88,99 };//不支持换行书写
for(int i = 0 ; i < array4.length ; i++){
System.out.println( array4[i] );
}
}
}
4 数组的遍历
遍历:从头到尾,逐一对数组的每个元素进行访问。
public class Test{
public static void main(String[] args){
//1.创建数组
int [] a = new int[5];
//2.赋值,数组下标最大为数组长度-1
a[0]=5;a[1]=3;a[2]=4;a[3]=5;a[4]=6;
/*3.数组遍历(取出数组中的元素)
数组下标从0开始,故i初始值为0,数组名.length可动态获取数组的长度
*/
for(int i=0;i>a.length;i++){
System.out.println(a[i]);
}
}
}
5 数组的扩容
5.1 数组的扩容
原因:数组空间太小,无法容纳更多的数据,数组在创建之后不可更改长度
扩容思路:1.创建大于原数组的新数组,2.将原数组中元素依次复制到新数组
5.2 复制的方式
1.利用数组的遍历,将鸠数组的元素逐一赋值给新数组
2.System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);
3.java.util.Arrays.copyOf(原数组,新长度);//返回带有原值的新数组
5.3 地址的替换
数组作为引用类型之一,其变量中存储的是数组的地址。
完成元素复制后,需将新数组地址,赋值给原变量进行替换。
5.4 案例
数组的扩容;数组地址的替换;数组类型的参数与返回值.
package com.xx;
import java.util.Scanner;
/**
* @Title: Array04.java
* @Description: TODO:创建数组长度为5,然后长度扩容为10
* 采用三种复制方式完成数组的扩容.
* @since JDK1.8
*/
public class Array04 {
public static void main(String[] args) {
// 调用方法,创建长度为5的数组
int[] a = arrInt(5);
// 数组赋值
a = arrAss(a);
// 输出数组初始值:
arrOut(a);
// 扩容
arrOut(arrExp1(a));
arrOut(arrExp2(a));
arrOut(arrExp3(a));
}
/**
*
* 数组的扩容方法1: 利用数组的遍历,将旧数组的元素逐一赋值给新数组
*/
public static int[] arrExp1(int[] nums) {
// 1.创建比原数组大的新数组
int[] newNums = new int[nums.length * 2];
// 2.复制原数组中的所有数据到新数组
for (int i = 0; i < nums.length; i++) {
newNums[i] = nums[i];
}
// 方法的参数是原数组,返回的是新数组,这就利用方法完成了数组新旧地址的替换
return newNums;
}
/**
*
* 数组的扩容方法2: System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);
*/
public static int[] arrExp2(int[] nums) {
// 1.创建比原数组大的新数组
int[] newNums = new int[nums.length * 2];
// 2.使用System.arraycopy(原数组,原数组起始下标,新数组,新数组的起始存储下标,需要赋值的个数或长度);
System.arraycopy(nums, 0, newNums, 0, nums.length);
return newNums;
}
/**
*
* 数组的扩容方法3: java.util.Arrays.copyOf(原数组,新长度);返回带有原值的新数组
*/
public static int[] arrExp3(int[] nums) {
// 1.创建新数组、复制元素====将带有原值的新数组返回给我们
int[] newNums = java.util.Arrays.copyOf(nums, nums.length * 2);
return newNums;
}
/**
*
* 数组的创建
*/
public static int[] arrInt(int n) {
int[] a = new int[n];
return a;
}
/**
*
* 数组的赋值,
*/
public static int[] arrAss(int[] x) {
Scanner input = new Scanner(System.in);
for (int i = 0; i < x.length; i++) {
System.out.println("请输入数组第" + (i + 1) + "位的值(整数):");
x[i] = input.nextInt();
}
return x;
}
/**
*
* 一维数组的输出方法
*/
public static void arrOut(int[] x) {
for (int i = 0; i < x.length; i++) {
System.out.print(x[i]);
System.out.print("\t");
}
System.out.println();
}
}
6 数组类型的参数
6.1 数组类型的参数
方法调用时,将nums中的地址赋值给oneArray,此时二者指向同一个数组。
传递参数时:基本类型传递的是变量中的值;引用类型传递的是变量中的地址。
1. 基本数据类型的传递,是“值”的传递,一方改变,不会影响另一方
2. 引用数据类型的传递,是“地址”的传递,一方改变,会影响另一方
3. 3.String是特殊的引用类型,作为参数传递时与基本类型一致.不会对原值造成影响
6.2 数组类型的返回值
调用数组类型返回值的方法时,方法执行后,返回的是数组的地址。
6.3 案例
基本数据类型的传递;引用数据类型的传递;特殊的引用类型String的传递
package com.xx;
/**
* @Title: ArgPas.java
* @Description: TODO: 1.基本数据类型的传递,是“值”的传递,一方改变,不会影响另一方
* 2.引用数据类型的传递,是“地址”的传递,一方改变,会影响另一方
* 3.String是特殊的引用类型,作为参数传递时与基本类型一致.不会对原值造成影响
* @since JDK1.8
*/
public class ArgPas {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 基本类型,以int整型为例
int a = 3;
System.out.println("基本类型传递前值:" + a);// 3
intPas(a);
System.out.println("基本类型传递后值:" + a);// 3
// 引用类型,以数组为例
int[] arr = { 1, 2, 3, 4, 5 };
System.out.println("引用类型传递前数组第一个值:" + arr[0]);// 1
arrPas(arr);
System.out.println("引用类型传递后数组第一个值:" + arr[0]);// 100
// 特殊的引用类型.String
String str = "啦啦啦";
System.out.println("String类型传递前值:" + str);// "啦啦啦"
strPas(str);
System.out.println("String类型传递后值:" + str);// "啦啦啦"
}
// 基本类型传递是值的传递,不影响原值;以int类型为例
public static void intPas(int x) {
System.out.println("传递改变前值:" + x);// 3
// 改变传入的值
x = 5;
System.out.println("传递改变后值:" + x);// 5
}
// 引用类型传递,传递的是内存地址,会影响原值;以数组为例
public static void arrPas(int[] x) {
System.out.println("传入数组的内存地址值:" + x);// [I@15db9742
// 改变传入数组的第一个元素的值
x[0] = 100;
// System.out.println(x[0]);//100
System.out.println("传入数组的内存地址改变后值:" + x);// [I@15db9742
}
// String类型参数传递,值不会发生改变
public static void strPas(String x) {
System.out.println("传入String类型改变前值:" + x);// "啦啦啦"
// 改变传入的值
x = x + "弘一呀";
System.out.println("传入String类型改变改变后值:" + x);// "啦啦啦弘一呀"
}
}
7 可变长参数
7.1 可变长参数
概念:可接收多个同类型实参,个数不限,使用方式与数组相同。
语法:数据类型… 形参名 必须定义在形参列表的最后,且只能有一个。
package com.xx;
import java.util.Scanner;
/**
* @Title: Array06.java
* @Description: TODO:使用可变长参数的方法,创建数组,计算不同长度数组的总和
* @since JDK1.8
*/
public class Array06 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建数组
int[] a = {1,2,3,4,5,6};
int[] b = {1,2,3};
//利用可变长参数获取数组的总和
int asum = intArr(a);
arrOut(a);
System.out.println("数组长度:" + a.length + "\t总和:" + asum);
int bsum = intArr(b);
arrOut(b);
System.out.println("数组长度:" + b.length + "\t总和:" + bsum);
}
/**
*
* 使用可变长参数的方法,创建数组,计算总和
* */
public static int intArr(int... arr) {
int sum = 0;
for(int i=0;i<arr.length;i++) {
sum += arr[i];
}
return sum;
}
/**
*
* 一维数组的输出方法
*/
public static void arrOut(int[] x) {
for (int i = 0; i < x.length; i++) {
System.out.print(x[i]);
System.out.print("\t");
}
System.out.println();
}
}
8 数组的排序
8.1 冒泡排序
概念:相邻的两个数组比较大小,互换位置.
8.2 选择排序
概念:固定值与其他值依次比较大小,互换位置
8.3 Java提供的排序方法
基于内存的排序–>Arrays.sort(数组名)
8.4 案例
package com.xx;
import java.util.Arrays;
import java.util.Scanner;
/**
* @Title: Array07.java
* @Description: TODO:数组的排序,创建长度为5的数组,并循环输入值,再进行排序,冒泡排序、选择排序、Array.sort 3种方式。
* @since JDK1.8
*/
public class Array07 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建数组,长度为5
int[] arr = intArr(5);
// 数组赋值
arrAss(arr);
// 数组格式化输出,仅适用于测试使用
String ans = Arrays.toString(arr);
System.out.println("排序前:" + ans);
// 冒泡排序
// 使用数组复制方法把旧数组复制给新数组,避免因为排序后造成原数组元素位置的改变,影响其它排序结果
int[] arr2 = bubbleSort(Arrays.copyOf(arr, arr.length));
System.out.println("冒泡排序后:" + Arrays.toString(arr2));
System.out.println("=====================");
// 选择排序
int[] arr3 = selectSort(Arrays.copyOf(arr, arr.length));
System.out.println("选择排序后:" + Arrays.toString(arr3));
// 系统提供的排序方法
Arrays.sort(Arrays.copyOf(arr, arr.length));
String ans2 = Arrays.toString(arr);
System.out.println("Arrays.sort方法排序后:" + ans2);
}
/**
*
* 一维数组的创建
*/
public static int[] intArr(int n) {
int[] j = new int[n];
return j;
}
/**
*
* 数组的赋值,Array assignment
*/
public static int[] arrAss(int[] x) {
Scanner input = new Scanner(System.in);
for (int i = 0; i < x.length; i++) {
System.out.println("请输入数组第" + (i + 1) + "位的值(整数):");
x[i] = input.nextInt();
}
// 关闭资源
input.close();
return x;
}
/**
*
* 一维数组的输出方法
*/
public static void arrOut(int[] x) {
for (int i = 0; i < x.length; i++) {
System.out.print(x[i]);
System.out.print("\t");
}
System.out.println();
}
/**
*
* 冒泡排序--->bubble sort
*/
public static int[] bubbleSort(int[] x) {
// 定义临时变量用于比较时存储比较值
int temp = 0;
for (int i = 0; i < x.length - 1; i++) {
for (int j = 0; j < x.length - i - 1; j++) {
// 比较j和j+1的大小:一轮排序后,找到一个最大值放在本轮最后一位
if (x[j] > x[j + 1]) {
temp = x[j];
x[j] = x[j + 1];
x[j + 1] = temp;
}
}
System.out.println("第" + (i+1) + "轮排序后结果:" + Arrays.toString(x));
}
return x;
}
/**
*
* 选择排序--->Select the sort
*/
public static int[] selectSort(int[] x) {
for (int i = 0; i < x.length - 1; i++) {
// 比较i和j的大小:一轮排序后,找到一个最小值放在本轮第一位
for (int j = i + 1; j < x.length; j++) {
if (x[i] > x[j]) {
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
System.out.println("第" + (i+1) + "轮排序后结果:" + Arrays.toString(x));
}
return x;
}
}
9 二维数组
9.1 二维数组
概念:一维数组中的一维数组;数组中的元素还是数组.
9.2 二维数组的赋值与访问
使用双下标访问二维数组中的元素,
第一个下标代表:行号(高维下标);
第二个下标代表:列号(低维下标).
二维数组的访问:
访问低维长度:
array[0].length;//首个低维数组的长度
访问低维数组元素:
array[0][0];//首个低维数组的首个元素
高维数组中的每个元素,保存了低维数组的地址.访问array[0]等价于访问低维第一个数组(第一行)的内存地址.
9.3 二维数组的创建语法
- 先声明、再分配空间:
- 数据类型[][] 数组名;
- 数组名 = new 数据类型[高维长度][低维长度];
- 声明并分配空间:
- 数据类型[][] 数组名 = new 数据类型[高维长度][低维长度];
- 声明并赋值(繁):
- 数据类型[][] 数组名 = new 数据类型[高维长度][]; (不规则数组,自行new低维数组)。
- 声明并赋值(简):
- 数据类型[][] 数组名 = { {v1,v2,v3},{v4,v5},{v6,v7,v8,v9} }; (显示初始化)。
9.4 案例
使用数组,保存3个班,每个班5人的成绩,并进行输出, 计算每个班级平均成绩,三个班总平均成绩
package com.xx;
import java.util.Scanner;
/**
* @Title: Array08.java
* @Description: TODO:使用数组,保存3个班,每个班5人的成绩,并进行输出, 计算每个班级平均成绩,三个班总平均成绩
* @since JDK1.8
*/
public class Array08 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建三行5列的二维数组,用来存储3个班级每班5位同学的成绩.
int[][] arr = creatArr(3, 5);
// 输入每班每位同学的成绩
arr = arrAss(arr);
// 输出每班每位同学的成绩
arrOut(arr);
// 单个班级的平均成绩
int ave1 = ave(1, arr);
System.out.println("第一个班级平均成绩:" + ave1);
int ave2 = ave(2, arr);
System.out.println("第二个班级平均成绩:" + ave2);
int ave3 = ave(3, arr);
System.out.println("第三个班级平均成绩:" + ave3);
int aves = ave(arr);
System.out.println("三个班级总平均成绩:" + aves);
}
/**
*
* 二维数组的创建
*/
public static int[][] creatArr(int x, int y) {
int[][] a = new int[x][y];
return a;
}
/**
*
* 二维数组的赋值
*/
public static int[][] arrAss(int[][] arr) {
Scanner input = new Scanner(System.in);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println("请输入第" + (i + 1) + "个班级第" + (j + 1) + "位同学的成绩:");
arr[i][j] = input.nextInt();
}
}
input.close();
return arr;
}
/**
*
* 二维数组的输出
*/
public static void arrOut(int[][] arr) {
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.print("\t");
}
// 输出一行数据后,换行
System.out.println();
}
}
/**
*
* 计算单个班级平均成绩
*/
public static int ave(int num, int[][] arr) {
int ave = 0;
int sum = 0;
int count = 0;
// 计算单个班级的成绩,外层循环一次,内层循环<arr[i].length次
for (int i = num - 1; i <= num - 1; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum = sum + arr[i][j];
}
// 统计人数,人数即内层循环的次数
count += arr[i].length;
}
ave = sum / count;
return ave;
}
/**
*
* 计算三个班总平均成绩
*/
public static int ave(int[][] arr) {
int ave = 0;
int sum = 0;
int count = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum = sum + arr[i][j];
}
// 统计人数,人数即内层循环的次数
count += arr[i].length;
}
ave = sum / count;
return ave;
}
}
总结
数组一旦创建,长度不可更改.
基本类型传递–>值传递;引用类型传递–>内存地址传递