javaSE— 数组、冒泡排序、方法
javaSE_day04
目录
1. 数组
1.1 什么是数组
数组:存储相同数据类型的容器
1.2 特点
- 相同数据类型
- 有序(下标从0开始)
- 长度不可变(length属性)
1.3 声明数组
格式:数据元素的类型[ ] 数组名; (数组名是引用变量)
(1)int[ ] nums;
(2)int nums [ ];
其他定义方式:
(3)int [ ] nums1 = new int[10];
(4)int[ ] nums2 = {1,2,3,4};
/*int[ ] nums3;
nums = {1,2}; //error
*/
(5)int[ ] nums3 = new int[ ] {1,2,3}; //方括号内不能写长度
}
1.4 创建数组(申请内存)
格式:数组名 = new 数据元素的数组类型 [ 长度 ] ;
nums = new int [10]; // 4*10的连续内存空间
1.5 存放数据
eg:
nums [0] = 1;
nums [9] = 2;
1.6 使用数组
-
System.out.println(nums[0]); // 方法一:使用下标
-
for(int i = 0;i<= nums.length;i++){
System.out.println(nums[i]);
} -
for(int n : nums){ // 方法二 增强for循环(只能实现遍历功能)
System.out.println(n);
} -
Arrays.toString(nums);// 方法三
for循环:可遍历、可表示在数组中的位置
增强for循环:只可遍历
补充:堆、栈
- 内存五大区域: 堆、栈、方法区、本地方法栈、寄存器
存储内容 | 分配和释放 | 移除 | 优点 | 缺点 | |
---|---|---|---|---|---|
栈 | 函数的参数值、局部变量、引用变量 、基本数据类型(临时性的东西) | 编译器自动分配和释放 | 调用完后立即移除 | 效率高 | 空间小 |
堆 | 数组、对象 | 程序员分配 | 不是立即回收移除 ,由虚拟机的垃圾回收机制不定时的回收 | 空间大 | 效率低 |
eg:
int[ ] nums;
nums = new int[10]; // nums在栈,new在堆
main() {
int b; //栈
char s[ ] = “abc”; //栈
char *p2; //栈
char *p3 = “123456”; // 123456/0在常量区,p3在栈
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//分配得来得10和20字节的区域就在堆区。
}
1.7 main方法的args数组的使用
- 练习:求数组元素的和
//练习:求数组元素的和
public static void main(String[] args) { //args存储的是内存地址
/*int sum = 0;
for (int i = 0; i < args.length; i++) { //方法一
sum += Integer.parseInt(args[i]);
}
System.out.println(sum);
}*/
int sum = 0;
for (String str :args) { //方法二 增强for循环
sum += Integer.parseInt(str);
}
System.out.println(sum);
}
1.8 数组的拷贝和扩容
-
数组拷贝
arraycopy(src, srcPos, dest, destPos, length) 方法
* 第一个参数:原数组
* 第二个参数:原数组元素的起始位置
* 第三个参数:目标数组
* 第四个数组:目标数组元素的起始位置
* 第五个参数:拷贝元素的长度
eg:
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
int[] b = new int[10]; //默认值都是0
// 想要得到 b = {1,2,3,0,0......}
//数组拷贝
//arraycopy
System.arraycopy(a, 0, b, 0, 3); //system的静态方法
System.out.println(Arrays.toString(b));
}
-
数组扩容
copyof(original, newLength) 方法
* 第一个参数:原数组(拷贝)
* 第二个参数:扩容之后的长度eg:
String[] names = {"张三"};
names = Arrays.copyOf(names, names.length+1); //扩容后新的默认值是null
names[1] = "李四";
System.out.println(Arrays.toString(names));
1.9 数组元素的排序
1.9.1 冒泡排序
原理:两两比较,大的沉下去,小的浮上来,最终结果是从小到大
eg:
//冒泡排序
/* 循环次数i-1 比较次数=4-i-1
23,56,22,15 i: 0 j: 3
23,22,15,56 1 2
22,15,23 2 1
15,22
*/
public static void main(String[] args) {
int[] nums = {23,56,22,15};
for (int i = 0; i <nums.length-1; i++) { //外层循环 控制循环多少次
for (int j = 0; j < nums.length -i-1; j++) { //内层循环 控制每一趟的循环次数
//注意 j < nums.length -i-1 没有=,否则nums[j+1]会越界
if (nums[j]>nums[j+1]) {
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
System.out.println("排序后的数组为:"+Arrays.toString(nums));
}
1.9.2 选择排序
原理:选择一个元素和其他所有的进行比较
eg:
//选择排序
/* 23,56,22,15
56,23,22,15
23,22,15
22,15
*/
public static void main(String[] args) {
int[] nums = {23,56,22,15};
for (int i = 0; i <nums.length-1; i++) {
for (int j = i+1; j < nums.length; j++) {
if (nums[i]<nums[j]) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
System.out.println("排序后的数组为:"+Arrays.toString(nums));
}
2. 二维数组
有几个[ ]就是几维数组
2.1 声明
- int[ ][ ] arrays; // 第一个[ ]表示行 第二个[ ]表示列
- int[ ] arrays[ ];
- int arrays[ ][ ];
二维数组的其他定义方式:
- int[ ][ ] nums = new int[2][3]; //列可以不写长度
- int[ ][ ] nums2 = {{1,2,3},{4,5,6}};
- int[ ][ ] nums3 = new int[ ][ ]{{1,2,3,},{4,5,6}};
- num[0] = null //未申请内存。 二维数组对应一维数组的对象,所以默认值是null
eg:
int[ ] a[ ],b; // a是二维数组 b是一维数组
int[ ] c = new int[2];
int[ ][ ] d = new int[2][3];
//判断以下定义是否正确
a=c ; //err
b=c ; //ok
a=d ; //ok
b=d ; //err
a[0]=c ; //ok
a[0]=d ; //err
2.2 创建
eg: arrays = new int[2][3];
2.3 赋值
eg: arrays[0][2] = 1;
2.4 使用数组元素
使用嵌套循环
eg:
public static void test2() {
int[][] nums;
nums = new int[2][3];
nums[1][1] = 1; //赋值
for(int i = 0;i<nums.length;i++){
for(int j = 0;j<nums[i].length;j++){ //nums[i].length 防止每行的个数不同
System.out.print(nums[i][j]+"\t");
}
System.out.println();
}
}
//不规则的二维数组
public static void test3() {
int [][] nums = new int[3][]; //行的个数必须写 不能只写列数
nums[0] = new int[3];
nums[1] = new int[1];
nums[2] = new int[5];
for(int i = 0;i<nums.length;i++){
for(int j = 0;j<nums[i].length;j++){ //nums[i].length 防止每行的个数不同
System.out.print(nums[i][j]+"\t");
}
System.out.println();
}
}
练习
1. 对角线求和
1 2 3
1 2 2
3 2 2
//对角线求和
public static void test1() {
int[][] nums = {{1,2,3},{1,2,2},{3,2,2}};
int sum = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j<nums[i].length; j++) {
if (i==j || i+j==2) {
sum += nums[i][j];
}
}
}
System.out.println(sum);
}
2. 矩阵转置
1 2 3
4 5 6
得到:
1 4
2 5
3 6
//矩阵转置
public static void test2() {
int[][] a = {{1,2,3},{4,5,6}};
int[][] b = new int[a[0].length][a.length];
for (int i = 0; i < a.length; i++) {//第一个嵌套循环实现转置操作
for (int j = 0; j < a[0].length; j++) {
b[j][i] = a[i][j];
}
}
for (int i = 0; i < b.length; i++) {//第二个嵌套循环实现输出
for (int j = 0; j < b[0].length; j++) {
System.out.print(b[i][j]+"\t");
}
System.out.println();
}
}
3. 杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 1
特点:每一行的开始和结束都是1;其余位置的元素是计算:
arr[ i ][ j ] = arr[ i - 1][ j ] + arr[ i - 1][ j - 1];
//杨辉三角
public static void test3() {
Scanner sc = new Scanner(System.in);
System.out.println("input n:");
int n = sc.nextInt();
int[][] nums = new int[n][];
for (int i = 0; i < nums.length; i++) {
nums[i] = new int[i+1]; //外层循环决定内层循环的列数
for (int j = 0; j <nums[i].length; j++) {
if (j==0 || i==j) {
nums[i][j] = 1;
}else {
nums[i][j] = nums[i-1][j-1] + nums[i-1][j];
}
System.out.print(nums[i][j]+"\t");
}
System.out.println();
}
}
3. 方法
目的:让代码可以重复使用
3.1方法的定义
格式:
[ 访问修饰符 修饰符 ] 方法返回类型 方法名(形参列表){方法体;}
-
访问修饰符: private、 default (没有修饰符 eg: void f(){} ) 、protected、public 范围从小到大
-
修饰符:static
-
方法返回类型:无返回值 void、有返回值(任何数据类型)
-
void 里可以有return ,表示方法结束。但return后不可以有值。
public static void sum(){ System.out.pritln("求和"); return ; //表示方法结束 }
-
如果方法有返回值,那么必须有 return 返回值,值和方法返回类型兼容。
eg:
-
public static double sum(){
return 1+2.0;
}
public static int[] f(){ return new int[1];}
- 方法名:同变量名 3个法则
- 形参列表:同变量定义 (数据类型 变量名) 多个参数用逗号隔开
- 方法体:就是方法完成的功能代码
3.2 方法的调用
格式:方法名(实参列表)
- 练习:
//练习:定义返回int类型的方法,参数为int类型的一维数组
// 方法完成的功能:找出数组中最大的元素,返回
//测试:调用方法
public static int getMax(int[] num) {
int max = num[0];
for (int i = 1; i < num.length; i++) {
if (max<num[i]) {
max = num[i];
}
}
return max;
}
public static void main(String[] args) {
int[] num = {2,3,55};
System.out.println(getMax(num));
}
3.3 方法的重载
定义:方法名相同、参数列表不同(个数、类型、顺序)的一组方法
和方法的返回类型无关
适用于 :同一个类、继承关系
public void f(int x){}
publuc int f(int y){return 1;} //参数类型不同
public void f(int x,int y){return x+y;} //参数个数不同
3.4 值传递
java中只有值传递。
java将值传递和地址传递统称为值传递。(将地址看作值)
-
值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不影响到实际参数。
-
地址传递:指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将会影响到实际参数。
- 如果传递的是基本数据类型,方法内改变,原值不变。
- 如果传递的是地址(数组),若地址不变,数据发生变化,原值也发生变化
package cn.tedu.demo;
/**
* 值传递
* @author Dell
*
*/
public class Demo9 {
public static void f(int n) {
n = 3;
}
public static void f2(int [] a) {
a[0] = 9;
}
public static void f3(int [] a1) {
a1 = new int[5];
a1[0] = 9;
}
public static void main(String[] args) {
int n = 5;
f(n);
System.out.println(n); //5 值传递 值不变
int a[] = {1,2,3,4,5};
f2(a);
System.out.println(a[0]); //9 地址传递 地址不变 会改变原值
int a1[] = {1,2,3,4,5};
f3(a1);
System.out.println(a1[0]); //1 地址变化,原值不变
}
}
f():
f2():
f3():
本文地址:https://blog.csdn.net/weixin_46439070/article/details/107470580
上一篇: Java Lock详解
下一篇: jdk1.8的安装环境配置详细步骤