哈喽,大家好!我是白夜,今天给大家聊聊数组。
一、概念
计算机在内存区域分配的一段连续的区域(空间) ,用来存储同种类型的多个数据
简单的理解,数组就是一堆盒子,同一时间,可以保存多个相同数据类型的数据
- 数组名 :数组的名字
- 数组元素:就是存放在数组里面的数据
- 数组索引:就是数组里面连续存储空间的编号,从0开始
- length :数组的属性长度,数组名.length拿到数组的长度
作用:
可以解决同时保存多个数据的问题
二、声明与赋值、取值、遍历
2.1、数组的声明
java
int[] ages;// 表示声明一个int类型数组ages,这个数组只能装int类型元素
String[] names;// 表示声明一个String类型数组names,这个数组只能装String类型元素
2.2、数组的初始化赋值
数组在定义后,必须**初始化【赋值】**才能使用。所谓初始化,就是在堆内存中给数组分配存储空间,并为每一 个元素赋上初始值,有两种方式:
2.2.1、动态创建
**语法:**数据类型[] 数组名 = new 数据类型[长度];// 长度不能为负数,且是int类型 最大就是int最大值
java
// 数组声明: 动态创建,语法 :数据类型[] 数组名 = new 数据类型[长度];
//长度不能为负数,且是int类型 最大就是int最大值
int[] arr = new int[3];// 动态创建了一个int类型的数组arr,长度3
2.2.2、静态创建
**语法:**数据类型[] 数组名 = {元素1, 元素2}
java
// 数组声明:静态创建,语法 :数据类型[] 数组名 = {元素1, 元素2, 元素3....};
int[] arr2 = {6, 9, 69};
怎么选择用动态创建还是静态创建?
根据实际情况确定,知道具体的数据,用静态创建,不知道用动态创建。
2.3、数组的赋值、取值
2.3.1、赋值
java
语法:数组名[下标] = 值;
//2 数组赋值:语法,数组名[下标] = 值;
arr[0] = 1;// 给数组arr第1个元素赋值1
arr[1] = 2;// 给数组arr第2个元素赋值2
arr[2] = 3;// 给数组arr第3个元素赋值3
2.3.2、取值
**语法:**数组名 [下标];
取值后,主要用于:
- 直接打印输出
- 赋值给另外一个变量
- 直接计算
- 作为方法参数使用
java
// 数组取值:语法,数组名[下标]; 直接打印元素即可
System.out.println("第1个元素 : " + arr[0]);// 直接打印第1个元素
System.out.println("第2个元素 : " + arr[1]);// 直接打印第2个元素
System.out.println("第3个元素 : " + arr[2]);// 直接打印第3个元素
2.4、数组的遍历
2.4.1、for循环遍历
java
数组遍历【将所有元素取出来就是遍历】
// 先打印数组arr所有下标
for (int i = 0; i < arr.length; i++) {
// 打印下标:i
System.out.println("下标:" + i);
// 打印元素:arr[i]【通过下标获取对应元素】
System.out.println("元素==== :" + arr[i]);
}
2.4.2、foreach
概念: 增强for循环就是类似for循环的结构,专业称呼为foreach
**作用:**只是用来简化遍历数组和集合的过程;
缺点: 没有索引,凡是涉及有索引相关操作还是用普通for循环;
java
for (int e : arr) {// arr是数组名, int 是元素类型 e变量是每一个元素
System.out.println("元素 :" + e);
}
三、数组内存分析
java
/**
* 数组内存分析图【理解】
* 基本类型具体的值在栈帧中
* 引用类型具体的值在堆中
*/
public class _05StackHeap {
public static void main(String[] args) {
int[] arr2 = {1, 2, 5};
int[] arr = new int[3];
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr);
arr[0] = 1;
arr[1] = 9;
arr[2] = 6;
// arr[3] = 5;// ArrayIndexOutOfBoundsException 数组下标越界异常。证明下标超过了数组有效范围
int a = 1;
int b = 1;
a = 2;
}
}
四、数组的注意事项、小练习
4.1注意事项
java
1 数组的下标范围是[0,arr.length-1],使用数组的时候,超过下标范围会报错ArrayIndexOutOfBoundsException 数组下标越界异常。
例如:数组长度是3个,但是现在操作第4个元素arr[3]就会报这个错误。
2 数组动态创建可以分为两步:
2.1. int[] arr;//只是声明一个int类型的数组,还没有创建(即,还没有分配内存空间)
2.2. arr = new int[长度];//分配内存空间,动态创建数组
3 数组静态创建可以分为两步:
3.1. int[] arr;//只是声明一个int类型的数组,还没有创建(即,还没有分配内存空间)
3.2. arr = new int[]{1,2,43};// 分配内存空间,动态创建数组
不能直接这样写:arr = {1,2,43};// 语法错误
4 数组一旦创建,长度就固定不变了。
如果长度不够或者长度多了,就需要创建新数组,将原来数组中元素复制到新数组中。int[] arr = {1,2,43};
arr = new int[]{1,43};//开辟新的内存区域,重新创建新的数组扩容、缩容
5 数组是引用数据类型,直接打印数组名是打印的地址
6 动态创建,没有给数组元素赋值,则系统会分配默认值
(byte/short/int/long)整数类型默认值:0
(float、double)小数类型默认值:0.0
boolean类型:false
char类型默认值:空字符
7 空指针异常:NullPointerException,操作了一个尚未初始化或者没有分配内存空间的数组,即,没有只是声明,但是没有创建的数组
4.2小练习
java
1. 用for循环求1-35的7的倍数的和
int sun = 0;
for (int i = 1; i <= 35; i++) {
if (i %7 == 0){
sun += i;
}
}
System.out.println(sun);
2. 请打印出int[] arr = {1, 9, 96, 9, 6, 66}; 数组中最小的一个数和最大的一个数
int[] arr = {1, 9, 96, 9, 6, 66};
int max = arr[0];
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
if(arr[i] < min){
min = arr[i];
}
}
System.out.println("最大值:"+ max);
System.out.println("最小值:"+ min);
3.已知数组:int[] arr = {1,9,96,9,6,66};现有新数组:int[] newArr = new int[4];
请将数组arr从第2个元素开始的4个元素复制到新数组newArr中。(即复制:9,96,9,6 到新数组newArr中)
int[] arr = {1, 9, 96, 9, 6, 66};
int[] newArr = new int[4];
for (int i = 0; i < arr.length; i++) {
if(i >= 1 && i <= arr.length -2){
newArr[i-1] = arr[i];
System.out.println(newArr[i-1]);
}
}
4.现有如下的数组 int[] oldArr = {1,3,4,5,6,6,0,5,6,7,0,5};取出以上数组不为0的值,然后将不为0的值存入一个新的数组,生成新的数组为:int[] newArr = {1,3,4,5,6,6,5,6,7,5};
int[] oldArr = {1, 3, 4, 5, 6, 6, 0, 5, 6, 7, 0, 5};
int count = 0;
for (int i = 0; i < oldArr.length; i++) {
if(oldArr[i] != 0){
count++;
}
}
int[] newArr = new int[count];
int index = 0;
for (int i = 0; i < oldArr.length; i++) {
if(oldArr[i] != 0){
newArr[index] = oldArr[i];
index++;
}
}
for (int i = 0; i < newArr.length; i++) {
System.out.println(newArr[i]);
}
5.现在给出两个数组,数组arr1: "1,7,9,11,13,15,17,19";数组arr2:"2,4,6,8,10",两个数组合并之后数组arr
int[] arr1 = {1, 7, 9, 11, 13, 15, 17, 19};
int[] arr2 = {2, 4, 6, 8 ,10};
int newArrLength = arr1.length + arr2.length;
int[] newArr = new int[newArrLength];
int index = 0;
for (int i = 0; i < arr1.length; i++) {
newArr[index] = arr1[i];
index++;
}
for (int i = 0; i < arr2.length; i++) {
newArr[index] = arr2[i];
index++;
}
for (int i = 0; i < newArr.length; i++) {
System.out.println(newArr[i]);
}
6.输出斐波那契数列的前 10 项
方法一:
int a = 0;
int b = 1;
int c = 1;
System.out.println(a+ "");
System.out.println(b+ "");
for(int i=2; i < 10; i++){
System.out.println(c + "");
int m = c;
a = b;
b = m;
c = a + b;
}
方法二:
int[] arr = new int[10];
arr[0] = 0;
arr[1] = 1;
for(int i = 2; i < arr.length; i++){
arr[i] = arr[i-1]+arr[i-2];
}
for (int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
7.冒泡排序
int[] scores = {11, 34, 76, 77, 88, 99, 58, 97, 56};
for(int i=0; i <scores.length; i++){
for(int j = 0 ; j < scores.length-i-1; j++){
if(scores[j] > scores[j+1]){
int temp = scores[j];
scores[j] = scores[j+1];
scores[j+1] = temp;
}
}
}
for (int e : scores) {
System.out.println(e + "");
}