# 大数据学习笔记第6天 - 数组 #
## 回顾
方法的重载:为了方法名的重用。遵守两同、一不同原则(同类同方法名,不同的参数个数或参数类型)。
## 大纲
### 第一节课
- 知识点回顾
- 数组概述
- 数组模拟打分实例
### 第二节课
- 方法调用的值传递原理
### 第三节课
- 二维数组
- 二维数组的遍历
- 二维数组计数求和
### 第四节课
- 二维数组练习
- 二维数组打印杨辉三角
## 数组基础
概念:同一种类型数据的集合,可以是基本的数据类型,也可以是引用数据类型。
![](./img/06/03.jpg)
### 特点
1. 数组存储的都是相同数据类型的元素。
2. 数组的长度也就是数组中元素的个数。
3. 元素从0开始编号,编号也称为索引\index\下标。
4. 数组中元素的访问方式是通过数组名+索引的方式。
### 数组的定义格式
基本数据类型变量的定义:int x;
数组类型变量的定义:int[] arr;
![](./img/06/01.jpg)
### 数组的初始化
初始化方式1:
动态初始化:数组的创建和元素的赋值分开进行;
格式:元素类型[] 数组名=new 元素类型[数组长度];
int[] arr = new int[3];
初始化方式2:
静态初始化:数组创建时就给数组元素赋值;
格式:元素类型[] 数组名=new 元素类型[]{元素1,元素2,...};
int[] arr = new int[]{1,2,3}
静态初始化的简写方式:int[] arr = {1,2,3}
直接打印数组类型的变量,会发现结果是一段看不懂的字符串,这就是引用数据类型变量的特点;它实际上代表的是一段内存空间的十六进制表示形式,真正的数据在JVM的堆内存空间中。
### 代码实例
public class ArrayDemo{
public static void main(String[] args){
// 动态初始化
int[] arr1 = new int[3];
System.out.println(arr1); //打印的是包含了十六进制的字符串,实际上代表的是数组的地址
// 静态初始化
int[] arr2 = new int[]{1,2,3};
int[] arr3 = {4,5,6};
System.out.println(arr2);
System.out.println(arr3);
}
}
![](./img/06/2018-07-22_223242.png)
## 内存结构
Java程序在运行时,为了提高运行效率,对内存进行了不同区域的划分,每一种区域都有特定的处理数据的方式和内存管理方式。
如图:
![](./img/06/02.jpg)
- 栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放;
- 堆内存:存放数组和对象,通过new建立的实例都存放在堆内存中;
- 每一个实例都有内存地址值;
- 实例中的变量都有默认初始值;
- 当实例不再被使用,会在不确定的时间被垃圾回收器回收;
- 方法区:存放类文件和方法(面向对象部分再阐述)
![](./img/06/06.jpg)
本地方法栈:供本地方法使用,与操作系统有关。
程序计数器:对字节码文件计数;
## 常见异常
1. 数组索引越界异常
2. 空指针异常
### 代码实例
public class ArrayDemo2{
public static void main(String[] args){
int[] arr = new int[2];
// arr[2] = 1; //java.lang.ArrayIndexOutOfBoundsException
arr=null;
System.out.print(arr[0]); //java.lang.NullPointerException
}
}
![](./img/06/2018-07-22_224258.png)
## 案例:数组模拟打分
从键盘录入5个分数作为评分,然后去除一个最高分,去除一个最低分,用剩余的数据的平均分作为最终的评分;
代码:
import java.util.Scanner;
public class Demo01{
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int[] score = new int[5];
System.out.println("请输入第1个评分");
score[0] = s.nextInt();
System.out.println("请输入第2个评分");
score[1] = s.nextInt();
System.out.println("请输入第3个评分");
score[2] = s.nextInt();
System.out.println("请输入第4个评分");
score[3] = s.nextInt();
System.out.println("请输入第5个评分");
score[4] = s.nextInt();
double res = getScore(score);
System.out.println("最终的评分是:" + res);
}
public static int getMax(int[] arr){
int max = arr[0];
for(int i=0; i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
}
return max;
}
public static int getMin(int[] arr){
int min = arr[0];
for(int i=0; i < arr.length; i++){
if(arr[i] < min){
min = arr[i];
}
}
return min;
}
public static double getScore(int[] arr){
int max = getMax(arr);
int min = getMin(arr);
int sum = 0;
for(int i=0; i<arr.length; i++){
sum += arr[i];
}
double score = (sum - max - min) / (arr.length - 2.0);
return score;
}
}
![](./img/06/2018-07-22_224436.png)
## 方法调用的值传递原理
Java中参数传递(实参->形参)的问题:
- 参数是基本数据类型,传递的是数值的副本;
- 参数是引用数据类型,传递的是引用的副本;
![](./img/06/04.jpg)
### 代码实例
// 参数是基本数据类型,传递的是数值的副本;
public class Demo02{
public static void main(String[] args){
int x=10;
int y=20;
change(x, y);
System.out.println("x=" + x + ", y=" + y);
}
public static void change(int x, int y){
System.out.println("方法内部x=" + x + ", y=" + y);
x = 0;
y = 0;
System.out.println("方法内部x=" + x + ", y=" + y);
}
}
![](./img/06/2018-07-22_225512.png)
//参数是引用数据类型,传递的是引用的副本;
public class Demo03{
public static void main(String[] args){
int[] arr = {1,2,3};
change(arr);
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]+" ");
}
}
public static void change(int[] arr){
for(int i=0; i<arr.length; i++){
arr[i]=0;
}
System.out.print("方法内部数组元素是:");
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
![](./img/06/2018-07-22_230507.png)
## 杨辉三角
![](./img/06/05.jpg)
- 端点的数为1.
- 每个数等于它上方两数之和。
- 每行数字左右对称,由1开始逐渐变大。
- 第n行的数字有n项。
- 第n行数字和为2^(n-1)。
- 每个数字等于上一行的左右两个数字之和。可用此性质写出整个杨辉三角。即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和,这也是组合数的性质之一。
...
![](./img/2018-08-18_150213.png)