1.数组
1.1 数组的定义(了解)
数组是相同类型数据的有序集合。数组描述的是相同类型的若干数据。按照一定的先后次序排列组合。其中每一个数据称为元素,每个元素都可以通过数组的索引或者下标(角标)来定位。
1.2 数组的特点(掌握)
1 数组本身是引用数据类型,而数组中的元素可以使任意类型(基本类型/引用类型)
2 创建数组对象会在内存中开辟一块空间,他的空间是连续的。而数组名中引用的是这块连续空间的首地址。
3 数组的长度一但确定 就不能修改。
4 数组中存储的数据的类型必须是相同的 不能出现混合类型
1.3 数组的分类(了解)
维度: 一维数组 二维数组 三维数组 多维数组…
数据类型: 基本类型的数组(整形数组 浮点型数组 字符型数组 布尔型数组) 引用类型的数组
2.一维数组
2.1 数组的创建和初始化
(java中的数组必须先进行初始化,才能使用)
2.1.1 数组的定义格式:
格式一: 数据类型[] 变量名 int[] arr; 定义了一个int类型的一维数组 数组名称为arr (掌握)
格式二: 数据类型 变量名[] int arr[]
2.1.2 数组的初始化:
java中的数组必须先初始化,然后才能使用。
所谓初始化:就是为数组中的元素分配内存空间,并为每一个元素赋值
2.1.3 数组的初始化方式
- 静态初始化
- 动态初始化
动态初始化:
数组声明和数组元素的分配空间及赋值分开进行。
格式: 数据类型[] 变量名 = new 数据类型[数组的长度]
new不可省略
int[] arr = new int[5] 表示声明了一个长度为5的整型数组
等号的左边:
int 数组的类型
[] 表示这是一个数组
arr 是这个数组的名称
等号的右边:
new: 为数组开辟内存空间
int 数组的数据类型 制定了数组中每个元素的空间大小
[] 表明这是一个数组
5 表示数组的长度
为数组中的元素赋值:
arr[0] = 3;
arr[1] = 5;
arr[4] = 9;
取值: arr[0] arr[1]
public static void main(String[] args) {
int[] arr = new int[5];
//赋值操作
arr[0]= 2;
arr[1]= 5;
arr[3] = 8;
//取值操作
int a1 = arr[0];
int a2 = arr[1];
int a3 =arr[3];
int a4 = arr[4];
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
System.out.println(a4);
}
public static void main(String[] args) {
String[] arr = new String[6];//声明了一个长度为6的字符串类型的数组
arr[0]= "马云";
arr[1]= "马化腾";
arr[2] = "雷军";
System.out.println(arr[0]+"----" +arr[1]+"---"+arr[2]);
}
静态初始化:在定义数组的同时就位数组元素分配空间并赋值
数据类型[] 变量名 = new 数据类型[]{数据1,数据2,数据3,...,数据n}
此时在声明数组的时候 不需要的指定长度系统会根据给出的数据自动分配长度
其中数据之间使用逗号分割
简化格式:
数据类型[] 变量名 = {数据1,数据2,数据3,...,数据n}
//静态初始化:
int[] arrInt = new int[]{2,1,3,5,2,1,5,6};
String[] arrStr = {"aaa" ,"bbbb " , "cccc"};
2.2. 数组的默认值
数组元素 即使我们没有赋值 每个元素都存在一个默认的值
byte shot int 默认值是 0 long类型的默认值0L
float double 默认值是0.0 char类型的默认值他是"\u0000"
boolean 类型为false String为代表的引用类型为null
2.3 数组的长度
//数组的长度 数组拥有一个属性 length
System.out.println(arr.length);
System.out.println(arr1.length);
for(int i = 0 ; i < arr1.length;i++){
System.out.println(arr1[i]);
}
}
}
当数组的索引超过数组的长度 length-1 之后 就会发生一个异常:
升景坊单间短期出租4个月, 550元/月(水电煤公摊,网费35元/月),空调、卫生间、厨房齐全。屋内均是IT行业人士,喜欢安静。所以要求来租者最好是同行或者刚毕业的年轻人,爱干净、安静。
3 内存管理
程序向jvm申请内存 jvm向操作系统申请内存
计算的内存是非常重要的组件,程序要运行 必须加载到内存中才可以运行。但是由于内存空间有限,当运行结束之后,必须清空内存。
java虚拟机要运行程序,必须对内存进行空间的分配和管理。
3.1 java中的内存分配
堆区:存储对象或者数组 new出来的都在对内存中。如果申请不到空间 则会抛出内存溢出异常。
虚拟机栈:栈里面是一个一个的“栈帧” 每个栈帧对应一次方法的调用。栈帧中存放了局部变量表(基本类型数据的变量和对象的引用)。操作数栈,方法出口以及其他的信息。 当栈调用的深度大于jvm所允许的范围,也会发生一个异常。
4 数组使用中需要注意的两个问题
4.1 数组下标越界异常
在使用数组的下标访问数组元素的时候 不能超过数组的长度范围 index < length
ArrayIndexoutOfBoundsException 解决方案:
将越界的数组索引修改到正常范围即可。
4.2 空指针异常
空指针异常:意味着引用类型的变量不指向任何对象(引用类型的变量没有引用到任何数据)
解决方案:给引用类型的变量一个真正的堆内存空间引用即可。
5 数组的常见操作
常见操作主要包括:遍历 拷贝 最值
5.1. 遍历
遍历:就是获取数组中的每一个元素。
public static void main(String[] args) {
int[] arr = {2,3,52,11,4,5,43,2,1};
for(int i = 0 ; i < arr.length;i++){
System.out.println(arr[i]);
}
}
增强for循环(jdk1.5新增):专门用户读取数组或集合中所有的元素(遍历数组或集合)
/*
*增强for 第一部分 遍历的数组或集合中的元素的类型
* 第二部分 a 用来存储每一次获取的元素
* 第三部分 arr 表示要便利的数组或者集合对象
*/
for (int a : arr){
System.out.println(a);
}
增强for循环 在整体遍历时 相对于普通for更见简洁
普通for循环 可以通过索引精确控制到每一个元素 而增强for 则不可以。
5.2 数组的拷贝
public static void main(String[] args) {
int[] arrSrc = {2,3,52,11,4,5,43,2,1};
int[] arrDest = new int[arrSrc.length];// 新数组的长度 必须大于等于原数组
for(int i = 0 ; i < arrDest.length;i++){
arrDest[i] = arrSrc[i];
}
for(int a : arrDest){
System.out.println(a);
}
}
public static void main(String[] args) {
int[] arrSrc = new int[5];
int[] arrNew=null;
int count=0;
for(int i = 0 ; i< 100;i++ ){
if(count < arrSrc.length){//当数组中的元素的个数小于数组的长度 则可以保存数据到数组中
arrSrc[i]=i;//给数组添加元素
}else{//数组中的数据的个数大于等于了数组的长度
arrNew = new int[arrSrc.length +(int)(arrSrc.length * 0.75)];
for (int j = 0 ; j < arrSrc.length;j++){
arrNew[j]= arrSrc[j];
}
arrSrc = arrNew;
arrSrc[i]=i;//给数组添加元素
}
count++;//统计数组中数据的个数
}
//遍历
for(int a : arrNew){
System.out.println(a);
}
}
5.3 获取数组中的最大值和最小值
记录元素的值
public static void main(String[] args) {
int[] arr = {2,52,26,22,12,3,223,22,91,81};
// 获取数组中的最大元素
int max = arr[0];//假设第一个元素是最大的
for(int a : arr){
if(a > max){
max = a;
}
}
System.out.println(max);
}
记录元素的位置
public static void main(String[] args) {
int[] arr = {2,52,26,22,12,3,223,22,91,81};
// 获取数组中的最大元素
int maxIndex=0;
for(int i = 0 ; i < arr.length;i++){
if(arr[i] > arr[maxIndex]){
maxIndex = i;
}
}
System.out.println(arr[maxIndex]);
}
练习:获取数组中的最小值 两种方式。
6. 二维数组
6.1 二维数组的初始化
动态初始化:int[][] arr = new int[3][5];
arr[0][0] = 23;
arr[0][1]=34;
定义了一个三行五列的二维数组
动态初始化: int[][] arr = new int[3][];
arr[0]= new int[3];
arr[1] = new int[5];
arr[2]= new int[4];
静态初始化:int[][] arr = {{2,1,4},{3,1,4,2,1},{3}};
int[][] arr =new int[][]{{2,1,4},{3,1,4,2,1},{3}};
在java中 二维数组 不必恃规则的矩阵形式。
int[][] arr = new int[3][5];
arr[0][0] = 32;
arr[2][4] = 54;
//遍历
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.println();//每一行结束 换行
}
}
内存结构:
面试考点:杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
第一行 1个元素 第n行 n个元素
每一个的第一个和最后一个元素都是1
从第三行开始 对于非第一个和最后一个的元素
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j]
public static void main(String[] args) {
int[][] yh = new int[5][];
for(int i = 0 ; i < yh.length; i++){
yh[i] = new int[i+1];
for(int j = 0; j < i + 1;j++){
if(j==0 || i==j){
yh[i][j]= 1;
}else{
yh[i][j] = yh[i-1][j-1] + yh[i-1][j];
}
}
}
for(int i = 0 ; i < yh.length;i++){
for(int j = 0 ; j < yh[i].length; j++){
System.out.print(yh[i][j]+" ");
}
System.out.println();
}
}
7.方法
方法 就是将具有独立功能的代码库组织成为一个整体,使其具有特殊功能的代码集。
注意:
方法必须先创建才可以使用,过程就成为方法的定义
方法定义之后不能直接运行 需要手动的调用 才可以执行。过程称为方法的调用。
7.1 定义方法
7.1.1 无参方法的定义和调用
public static void 方法名称(){
方法体;
}
方法的调用
方法名称();
public static void main(String[] args) {
//方法的调用
getMax();
getMax();
getMax();
}
// 获取两个整数中的较大者
public static void getMax(){
int a = 10;
int b = 20;
if(a > b ){
System.out.println("两个的较大者为:" + a);
}else{
System.out.println("两个的较大者为:" + b);
}
}
方法的调用过程
每个方法在被调用执行的时候 都会被加载到栈内存,并且拥有自己独立的内存空间,方法内部的代码执行完毕之后,会从栈内存中出栈 释放空间
7.1.2 带参方法的定义和调用
public static void 方法名称(参数类型 参数名称,参数类型 参数名称,。。。。)
调用:
方法名称(参数1,参数2,参数3,....,参数n)
方法调用时,传入的参数的数量和类型必须和方法定义中的类型和数量相匹配。否则 程序就会报错。
形参:方法定义是的参数
实参:方法调用时传递进来的参数
形参和实参的功能就是传递数据,发生方法调用时, 实参的值会传递给形参
形参和实参的区别和联系
- 形参变量只有在方法被调用时才会分配内存,调用结束后 就会被立即释放。所以形参变量只在方法内部有效,不能再方法的外部使用。
- 实参可以是常量 变量 表达式 方法等。无论实参是何种类型的数据,在进行方法的调用时,都必须有确定的值。
- 实参和形参在数量上 类型上 顺序上都必须严格一致。当然在其中,能够自动类型转化的除外。
- 方法调用中,发生的数据的传递时单向。只能有实参传递给形参,而不能把形参反向传递给实参。一旦参数的传递完成,则实参和形参将不会有任何的关系。在方法的调用过程中,形参的值的改变不会影响实参。
public static void main(String[] args) {
yh(10);//此时的8 就是实参
}
public static void yh(int row){ //row 就是形参 需要客户告传递给你的数据
int[][] yh = new int[row][];
for(int i = 0 ; i < yh.length; i++){
yh[i] = new int[i+1];
for(int j = 0; j < i + 1;j++){
if(j==0 || i==j){
yh[i][j]= 1;
}else{
yh[i][j] = yh[i-1][j-1] + yh[i-1][j];
}
}
}
for(int i = 0 ; i < yh.length;i++){
for(int j = 0 ; j < yh[i].length; j++){
System.out.print(yh[i][j]+" ");
}
System.out.println();
}
}
public static void main(String[] args) {
//方法的调用
getMax(15,33);
}
// 获取两个整数中的较大者
public static void getMax(int a , int b){
if(a > b ){
System.out.println("两个的较大者为:" + a);
}else{
System.out.println("两个的较大者为:" + b);
}
}
}
public static void main(String[] args) {
int x = 56;
int y = 67;
change(x,y);
System.out.println(x+"---"+y);
}
// 交换两个整数的值
public static void change(int a, int b){
int temp;
temp = a;
a = b;
b=temp;
System.out.println(a+"---"+b);
}
7.1.3 带返回值的方法的定义和调用
public static 返回值类型 方法名称(参数列表){
方法体;
return 数据;(返回的数据的数据类型必须和返回值类型匹配)
}
public static void main(String[] args) {
int s = sum(10);
System.out.println(s);
}
// 计算 1-N之间整数的和
public static int sum(int n){
int sum = 0;
for(int i = 0 ; i < n; i++){
sum += i;
}
return sum;//return 表示将数据返回给方法的调用者
}
注意:return 后不要存在任何语句 是执行不到的
当一个方法的返回值类型是void 的时return;候 能不能写return?
可以 但是写法 return;
7.2 方法的注意事项
1 方法不能嵌套定义 方法和方法之间是平行关系 方法只能调用方法
2 void 表示无返回值 可以省略return 也可以单独属性 后边不跟任何数据
3 方法必须被调用才能执行 方法不调用是不会执行的。
7.3 方法使用引用类型作为形参和返回值
public static void main(String[] args) {
yh(10);//此时的8 就是实参
}
public static void yh(int row){ //row 就是形参 需要客户告传递给你的数据
int[][] yh = new int[row][];
for(int i = 0 ; i < yh.length; i++){
yh[i] = new int[i+1];
for(int j = 0; j < i + 1;j++){
if(j==0 || i==j){
yh[i][j]= 1;
}else{
yh[i][j] = yh[i-1][j-1] + yh[i-1][j];
}
}
}
// 调用遍历数组的方法
printArr(yh);
}
// 遍历任意的二维数组
public static void printArr(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.println();
}
}
public static void main(String[] args) {
int[] arr = {3,2,1,5,7,9};
swap(arr,1,3);
printArr(arr);
}
/* 交换数组中两个元素的位置
arr 我们操作的目标数组
index1 和index2 就是要交换的两个元素的索引
*/
public static void swap(int[] arr,int index1,int index2 ){
int temp = arr[index1];
arr[index1] = arr[index2];
arr[index2]= temp;
printArr(arr);
}
// 遍历数组
public static void printArr(int[] arr){
for(int a : arr){
System.out.print (a + " ");
}
System.out.println();
}
方法的参数传递:
值传递: 传递的数据本身
引用传递:传递的地址 传递的是一个引用 所以引用的只要是同一个地址空间,那么任何地方对空间内容的修改,都将引起整个的变化。
7.4 方法的重载
public class MethodDemo5 {
public static void main(String[] args) {
int sum = add(2,1,7,8);
System.out.println(sum);
}
public static int add(int a , int b){
return a + b;
}
public static int add(int a , int b, int c){
return a + b + c;
}
public static int add(int a , int b, int c,int d){
return a + b + c + d;
}
构成方法的重载的条件:
1 形参的个数不同
2 参数的类型不同
3 不同类型的参数 如果顺序不同 也构成重载
特别注意:方法的返回值类型 不能作为方法是否重载的判断依据。
练习:
定义一个方法 处理迟到情况的处罚:
1 根据迟到时间和月薪 的不同 ,进行不同的处罚:
2 处罚的逻辑:
迟到1-10分钟 警告
迟到 11–20 分钟 罚款100
迟到21–30分钟 罚款200
迟到30分钟以上 扣除半天工资‘
迟到1小时以上 按照旷工处理 扣除3天工资
根据迟到时间和月薪 来计算员工应缴罚款的金额。
方法中 需要明确:
1 方法是否需要参数 如果需要 需要几个 每个参数什么类型
2 方法是否有返回值 如果有 什么类型 如果没有 就是void
上述练习:
参数 需要 迟到时间 (int) 月薪(double)
返回值 有 罚款金额 double
对于日工资的计算 月薪 /21天
import java.util.Scanner;
public class Homework {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int time=sc.nextInt();
double fine=sc.nextDouble();
fine(time,fine);
}
public static void fine(int time,double fine) {
Scanner sc=new Scanner(System.in);
int times=sc.nextInt();
for (int day = 1; day <=times ; day++) {
if (time > 0 && time <= 10) {
fine = 100 ;
} else if (time > 10 && time <= 20) {
fine = 200;
} else if (time > 20 && time <= 30) {
fine = (fine / 21) / 2;
} else if (time > 30 && time <= 60) {
fine = (fine / 21) * 3;
} else {
System.out.println();
}
System.out.println("罚款金额为:" + fine);
return;
}
}
}