数组
1.什么是数组?
数组是存储多个变量(元素)的东西(容器),这多个变量的数据类型要一致。
数组定义格式
格式1: 数据类型[] 数组名;
格式2: 数据类型 数组名[];
2.什么是数组的初始化?
Java中的数组必须先初始化,然后才能使用。
就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。
3.初始化的分类:
a:动态初始化: 只指定长度,由系统给出初始化值
b:静态初始化: 给出初始化值,由系统决定长度
注意事项: 这两种方式,只能使用一种,不能进行动静结合
动态初始化的格式:
数据类型[] 数组名 = new 数据类型[数组长度];
数组长度其实就是数组中元素的个数。只指定长度,由系统给出初始化值
Java中的内存分配以及栈和堆的区别
1.栈: 存放的是局部变量
局部变量:在方法定义中或者方法声明上的变量都是局部变量;
2.堆: 存放的是所有new出来的东西
a: 每一个new出来的东西都会为其分配一个地制值;
b: 每一个变量都有一个默认的值;
c: 使用完毕就变成了垃圾,等待垃圾回收器对其回收;
3.方法区:(面向对象部分讲解)
4.本地方法区:(和系统相关)
5.寄存器:(cpu使用)
package demo;
public class demo10 {
public static void main(String[] args) {
//数组:你可以一个容器,他用来存储一组相同类型的数据。
//数组的定义语法
//方式1:动态的定义方式,由我们规定数组的长度,由系统赋默认值
//创建一个int类型的数组
//当我们创建好了数组后,系统会给分配索引(角标)从0开始
int [] arr = new int[10];
//往数组中放入数据 通过数组的索引往里面存数据
arr[0]=10;
arr[1]=21;
arr[2]=32;
//取数组中的元素
int num = arr[2];
System.out.println(num);
System.out.println(arr[1]);
//语法
boolean b[] = new boolean[2];
b[0] = true;
System.out.println(b[0]);
}
}
静态初始化的格式:
格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
给出初始化值,由系统决定长度。
关于数组中堆栈以及方法区的关系
package org.westos.demo4;
public class ArrayDemo2 {
public static void main(String[] args) {
int[] arr1 = new int[3];
arr1[0]=10;
arr1[2]=200;
int[] arr2 = new int[3];
arr2[0]=11;
arr2[1]=19;
int[] arr3=arr1; //把arr1的地址赋给arr3,所以其实还是两个数组,只是其中的值改变了!!!
arr3[0]=108;
arr3[1]=106;
arr1[1]=177;
System.out.println(arr1[0]); // 108
System.out.println(arr1[1]); // 177
System.out.println(arr1[2]); // 200
System.out.println(arr2[0]); // 11
System.out.println(arr2[1]); // 19
System.out.println(arr2[2]); // 0
System.out.println(arr3[0]); // 108
System.out.println(arr3[1]); // 177
System.out.println(arr3[2]); // 200
}
}
public class ArrayDemo {
public static void main(String[] args) {
//数组静态初始化,由我们赋值,由系统计算长度
//数组一旦定义号,长度就固定了
int[] arr = new int[]{10, 20, 30};
boolean[] arr2 = new boolean[]{true, false, true, true};
char[] arr3 = new char[]{'a', 100, 'b'};
byte[] bytes = new byte[]{127, 100, 0, -128};
long[] longs = new long[]{1L, 100L};
float[] floats = new float[]{1F, 2.9F};
//静态初始化的简写方式
int[] arr6 = {10, 20, 30};
//数组有一个长度属性
int length = arr.length;
System.out.println(length);
int length1 = arr2.length;
System.out.println(length1);
// 数组中最后一个元素的索引=数组长度-1;
int num=bytes[bytes.length-1];
System.out.println(num);
//关于数组的一些一异常
arr[3]=100;
// System.out.println(arr[3]); //ArrayIndexOutOfBoundsException 数组角标越界异常
}
}
package demo;
public class demo11 {
public static void main(String[] args) {
int[] arr={10,20,50,40,102};
//数组的遍历
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("---------------------------");
//数组反向遍历
for(int i=arr.length-1;i>=0;i--){
System.out.println(arr[i]);
}
}
}
package demo;
public class demo12 {
public static void main(String[] args) {
//获取数组中的最大值或最小值
int[] arr = {6,10, 20, 50, 40, 102,123};
int max = getMax(arr);
System.out.println("最大值是:"+max);
int min = getMin(arr);
System.out.println("最小值是:"+min);
}
private static int getMin(int[] arr) {
int max = arr[0];
for(int i=0;i<arr.length;i++){
if(arr[i]>max){
max = arr[i];
}
}
return max;
}
private static int getMax(int[] arr) {
int min = arr[0];
for(int i=0;i<arr.length;i++){
if(arr[i]<min){
min = arr[i];
}
}
return min;
}
}
public class demo13 {
public static void main(String[] args) {
//数组元素反转(就是把元素对调)
int[] arr = {10, 20, 30, 40, 50}; //50 40 30 20 10
rverseArr(arr);
showArr(arr);
}
private static void showArr(int[] arr) {
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
private static void rverseArr(int[] arr) {
//首尾元素值交换,遍历一半***
for(int i=0;i<arr.length/2;i++){
//采用中间变量进行值交换
int tmp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = tmp;
}
}
}
二维数组
二维数组格式1
数据类型[ ][ ] 变量名 = new 数据类型[m][n];
m表示这个二维数组有多少个一维数组 必须写上;
n表示每一个一维数组的元素个数 可不写;
举例:int[ ][ ] arr = new int[3][2];
a:数据类型 数组名[][] = new 数据类型[m][n];
b:数据类型[] 数组名[] = new 数据类型[m][n];
这两种格式不推荐使用
二维数组遍历
外循环控制的是二维数组的长度,其实就是一维数组的个数。
内循环控制的是一维数组的长度。
public class ArrayDemo {
public static void main(String[] args) {
int[][] arr = {{2, 4}, {10, 30}, {10, 30, 40}, {10, 1}};
//二维数组的遍历
for (int i = 0; i < arr.length; i++) {
//System.out.println(arr[i]); //一维数组
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}
}
}
打印杨辉三角
public class ArrayDemo {
public static void main(String[] args) {
//需求:打印杨辉三角形(行数可以键盘录入)
//1
//1 1
//1 2 1
//1 3 3 1
//1 4 6 4 1
//1 5 10 10 5 1
//
/**
* 分析规律:
* 1.每一行的第一个数和最后一个数都是1
* 2.从第三行开始,中间的数等于我上一行的前一列的数和我上一行本列的数之和
*/
Scanner sc = new Scanner(System.in);
System.out.println("请输入行数");
int n = sc.nextInt();
//通过二维数组,存储这种行列结构的数据
//你要打印出三角形
//1.第一个数和最后一个数都是1
//2.第三行开始,中间的数等于我上一行的前一列的数和我上一行本列的数之和
int[][] arr=new int[n][n]; //定义一个数组,行列数都一样
for (int i = 0; i < arr.length; i++) {
arr[i][0]=1; //将每一行的第一个数,置成1
arr[i][i]=1; //将三角形的每一行的最后一个元素置成1
}
//计算中间元素
for (int i =2; i <=arr.length; i++) {
for (int j =1; j <= i-1; j++) {
//第三行开始,中间的数等于我上一行的前一列的数和我上一行本列的数之和
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 <=i; j++) {
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}
递归
方法定义中调用方法本身的现象。
注意: 要有出口,否则就是死递归;
次数不能太多,否则就内存溢出;
需求:兔子问题(斐波那契数列)
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?
由此可见兔子对象的数据是:1 , 1 , 2 , 3 , 5 , 8 …
public class MyTest {
public static void main(String[] args) {
月份 兔子的对数
// 1 1
// 2 1
// 3 2
// 4 3
// 5 5
// 6 8
// 7 13
// 8 21
// 1 1 2 3 5 8 13 21 从第三个数开始,这个数等于前两个数之和 (斐波那契数列)
//采用普通方法来做,到第20个月有多少对兔子
int[] arr=new int[20];
arr[0]=1;
arr[1]=1;
for (int i =2; i < arr.length; i++) {
arr[i]=arr[i-1]+arr[i-2];
}
System.out.println("兔子的对数"+arr[19]);
}
}
采用递归的方法:
public class MyTest2 {
public static void main(String[] args) {
// 1 1 2 3 5 8 13 21 从第三个数开始,这个数等于前两个数之和 (斐波那契数列)
//递归来做
int sum = sumRabbit(20);
System.out.println("兔子的对数" + sum);
}
private static int sumRabbit(int i) {
if (i == 1 || i == 2) {
return 1;
} else {
return sumRabbit(i - 1) + sumRabbit(i - 2);
}
}
}