目录
一、数组
1.1数组的概念
数组在内存中是一块 连续的空间 ,可以保存 相同类型 多个数据的容器
1.2数组的特点
- 数组中保存数据必须是相同的数据类型
- 数组是定长的(数组一旦定义不能改变长度)
二、数组的创建
2.1静态初始化
静态初始化(已经知道了数组中存放的元素)
* 语法1:数据类型[] 数组名={数据1,数据2,...};
* 语法2:数据类型 数组名[]={数据1,数据2,...};
* 语法3:数据类型[] 数组名=new 数据类型[]{数据1,数据2,...};
代码展示:
//1、定义数组
int[] arr={1,2,3,4};
//如果定义数组,直接输出数组那么输出的是数组的地址
System.out.println(arr);//[I@1b6d3586
//int arr[]={1,2,3,4};
//存值 静态初始化的数组,已经赋好了值,如果再进行赋值,就会覆盖原来的数据
arr[0]=120;
//取值
System.out.println("数组中第一个元素为"+arr[0]);
//获取数组长度
System.out.println("数组的长度为:"+arr.length);
2.2动态初始化
动态初始化(不知道数组中需要存放什么元素)
* 语法1:数据类型[] 数组名=new 数据类型[数组的长度];
* 语法2:数据类型 数组名[]=new 数据类型[数组的长度];
代码展示:
String arr1[]=new String[3];
//存值
arr1[0]="张三";
arr1[1]="尼古拉斯";
arr1[2]="rose";
//arr1[3]="rose"; 数组下标越界错误
//取值
System.out.println("arr1数组中的第一个元素为:"+arr1[0]);
//获取数组长度
System.out.println("arr1数组的长度为:"+arr1.length);
2.3数组的相关概念
1、数组中的每一个数据称之为一个元素
2、数组中的元素通过下标(索引)进行访问 数组名[下标]
3、数组的下标范围为 (0~数组的长度-1)
4、数组的长度可以通过数组名.length属性获取
5、如果数组的下标超过了范围会报错 ArrayIndexOutOfBoundsException下标越界异常
注意点:数组在定义的时候就需要确定长度
三、数组遍历
遍历:获取、保存数据中每一个元素(循环)
代码展示:
//遍历数组----->取值
int arr[]={1,3,5,7,9,13,35,57,79};
for (int i = 0; i < arr.length; i++) {//i---->利用i当作是数组的下标
System.out.println(arr[i]);
}
//遍历数组----->存值
Scanner sc=new Scanner(System.in);
int[] arr1=new int[6];
for (int i = 0; i < arr1.length; i++) {
System.out.println("请输入第"+(i+1)+"个数");
//给数组中的每一个元素赋值
arr1[i] = sc.nextInt();
}
//遍历数组进行输出
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
四、数组的默认值
整数型的默认值:0
byte,short,int,long
浮点型的默认值:0.0
float,double
字符型的默认值:0 ‘ ’ "\u0000"
char
布尔型的默认值:false
boolean
所有引用数据类型的默认值:null
String
null:在java中是一个特殊的值,它表示一个空的指向
代码展示:
int arr[]=new int[4];
System.out.println(arr[0]);//0
float arr1[]=new float[3];
System.out.println(arr1[0]);//0.0
char arr2[]=new char[3];
System.out.println(arr2[0]);//空格
boolean arr3[]=new boolean[3];
System.out.println(arr3[0]);//false
String arr4[]=new String[3];
System.out.println(arr4[0]);//null
五、数组的应用
案例1:从键盘录入五个名字到数组中,遍历数组输出这五个名字(不允许重复)
代码展示:
public class Test01 {
//1、从键盘录入五个名字到数组中,遍历数组输出这五个名字(不允许重复)
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String names[]=new String[5];
for (int i = 0; i <names.length ; i++) {
System.out.println("请输入第"+(i+1)+"个名字");
String name = sc.next();
//将输入的姓名保存到数组中(在存入名字之前,先判断一下数组中是否已经存在此姓名) 方法
if(existName(name,names)){//表示存在
i--;//让循环再走一次
continue;//结束本次循环,继续下次循环
}
names[i]=name;
}
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
}
//判断一下数组中是否已经存在此姓名,如果存在返回true,否则返回false
public static boolean existName(String name,String names[]){
for (int i = 0; i <names.length ; i++) {
if(name.equals(names[i])){
return true;
}
}
return false;
}
}
案例2:给定一个数组,求数组的最大值 ,求数组的最小值, 求数组的平均值
代码展示:
int[] nums={10,20,40,76,19};
//假设一个最大值,数组中的第一个元素是最大值
int max=nums[0];
//假设一个最小值,数组中的第一个元素是最小值
int min=nums[0];
//定义一个变量表示总和
double sum=0;
//遍历数组,将最大值和每一个元素作比较
for (int i = 0; i < nums.length; i++) {
if(nums[i]>max){
max=nums[i];
}
if(nums[i]<min){
min=nums[i];
}
sum+=nums[i];
}
System.out.println("max="+max);
System.out.println("min="+min);
System.out.println("平均值="+(sum/nums.length));
六、数组的扩容
6.1实现数组的扩容和缩容
数组的扩容和缩容
步骤1:定义一个新数组,然后新数组的长度比原数组增加或者是减小
步骤2:将原来数组的元素拷贝到新数组中
步骤3:将原数组的变量指向新数组
代码展示:
int[] arr={2,3,4};
//定义一个新数组
int[] newArr=new int[arr.length+1];
//将原数组中的元素拷贝到新数组中
for (int i = 0; i < arr.length; i++) {
newArr[i]=arr[i];
}
//将数组名指向新数组的地址
arr=newArr;
//扩容为了什么?放数据
arr[3]=100;
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
6.2数组拷贝
数组的拷贝有三种方式:
- 通过自定义循环将原数组中的元素拷贝到新数组中
- System类提供数组拷贝方法
- Arrays类提供数组拷贝方法
代码展示:
//1、system类中提供的数组拷贝的方法
int[] arr={11,12,13};
int[] newArr=new int[arr.length+5];
//参数说明:
// src:原数组
// srcPos:指定原数组的起始位置
// dest:目标数组
// destPos:目标数组起始位置
// length:拷贝元素的个数
System.arraycopy(arr,0,newArr,0,arr.length);
for (int i = 0; i <newArr.length ; i++) {
System.out.print(newArr[i]+"\t");
}
//2、Arrays类中提供的数组拷贝的方法
int[] arr={11,12,13};
//参数1:原数组 参数2:新数组的长度 返回值:新数组
int[] newArr= Arrays.copyOf(arr,arr.length+5);
for (int i = 0; i < newArr.length; i++) {
System.out.print(newArr[i]+"\t");
}
七、数组排序
7.1冒泡排序
冒泡排序的思想:
将相邻的两个元素作比较,如果前面一个比后面的元素大,就交换位置(将最大的元素放到最后面)
代码展示:
public static int[] sort3(int[] arr) {
for (int j = 0; j < arr.length - 1; j++) { //轮数
//假设这一轮已经拍好序了
boolean flag = true;
for (int i = 0; i < arr.length - 1 - j; i++) {//每一轮次数
if(arr[i] > arr[i+1]) {
flag = false;
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
if(flag) {
break;
}
}
return arr;
}
7.2选择排序
选择排序:
每一轮将当前位置上的元素,去与后面的每一个元素作比较,如果后面有元素更小,先保存下来,这一轮结束之后交换
代码展示:
int[] arr={12,3,45,6,1,18,90,89};
for (int i = 0; i < arr.length-1; i++) {//选择的轮数
//选择下标为i的位置
//假设i为最小值下标
int min=i;
//将最小值与后面的每一个元素作比较
for (int j = i+1; j <arr.length; j++) {
if(arr[j]<arr[min]) {
min = j;
}
}
//循环结束之后找到最小值
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
//遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
7.3 Arrays工具类排序方法
Arrays工具类提供的排序方法(只能升序)
代码展示:
int[] arr={12,3,45,6,1,18,90,89};
Arrays.sort(arr);
//遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
八、二分查找法
二分查找法(折半查找法)
前提:数组中的元素是有序的
思路:
- 首先找到数组中的中间的元素,与要查找元素进行比较,如果相等,那么就直接找到了
- 如果比中间的元素大,那么表示查找元素在中间值的右边。所以最小值的下标等于中间 值的下标+1
- 如果比中间的元素小,那么表示查找元素在中间值的左边。所以最大值的下标等于中间 值的下标-1
代码展示:
public class Demo04 {
public static void main(String[] args) {
int[] arr={1,2,3,4,5,6,7,8,9};
int num=7;
int index=getIndex(num,arr);
System.out.println(index);
}
public static int getIndex(int num,int[] arr){
//定义最小值的下标
int min=0;
//定义最大值的下标
int max=arr.length-1;
//循环的折半
while(min<=max){
//获得中间值的下标
int middle=(min+max)/2;
//将中间值与要查找的元素比较
if(num>arr[middle]){//说明元素在右边
min=middle+1;
}else if(num<arr[middle]){//说明元素在左边
max=middle-1;
}else{
return middle;
}
}
return -1;//表示要查找的元素不存在
}
}
九、二维数组
- 一维数组中的每一个元素,存储的是一个数据
- 二维数组中的每一个元素,存储的是一个一维数组
9.1创建二维数组
静态初始化:
语法1:数据类型[][] 数组名 = {{元素1,元素2,...},{元素1,元素2,...},.....};
语法2:数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,...},{元素1,元素2,...},.....};
动态初始化
语法:数据类型[][] 数组名 = new 数据类型[ 二维数组的长度] [一维数组的长度];
注意:二维数组的长度必须要定义,一维数组的长度可以暂时不定义
代码展示:
//静态初始化
int[][] arr={{1,2,3},{11,22,33,44},{123,124}};
//使用数组
System.out.println("二维数组中的第一个一维数组中的第一个元素:"+arr[0][0]);
System.out.println("二维数组中的第二个一维数组中的第三个元素:"+arr[1][2]);
//动态初始化
int[][] arr2=new int[2][];
//此时此刻,arr[0]这个一维数组还没有定义
//arr[0][0]=11;//报错NullPointerException
arr2[0]=new int[2];
arr2[0][0]=11;
arr2[0][1]=12;
arr2[1]=new int[1];
arr2[1][0]=13;
System.out.println("二维数组中的第一个一维数组中的第一个元素:"+arr2[0][0]);
System.out.println("二维数组中的第二个一维数组中的第一个元素:"+arr2[1][0]);
System.out.println("二维数组的长度"+arr2.length);
//二维数组的遍历
int[][] arr1={{1,2,3},{11,22,33,44},{123,124}};
for (int i = 0; i <arr1.length ; i++) {//遍历出每一个一维数组 行数
//此处的arr[i]表示的就是每一个一维数组
for (int j = 0; j <arr1[i].length ; j++) {//遍历出每一个一维数组中的元素 列数
System.out.print(arr1[i][j]+"\t");
}
System.out.println();
}
9.2 二维数组的应用
使用二维数组实现杨辉三角
代码展示:
//定义一个二维数组保存杨辉三角中的值
int[][] yh=new int[5][];
//就是给二维数组进行赋值
for (int i = 0; i < yh.length; i++) {
//需要定义一维数组
yh[i]=new int[i+1];
for (int j = 0; j < yh[i].length; j++) {
if(j==0||j==i){
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]+"\t");
}
System.out.println();
}
十、可变参数
语法: 数据类型... 参数名
特点:
1、带有可变参数方法的调用的时候,实参个数,可以是0个或者是多个
2、可变参数只能放在参数列表的最后(一个方法只能有一个可变参数)
3、可变参数可以当做数组来使用,也可以将数组作为参数 场景:不确定参数个数的时候
代码展示:
public static void main(String[] args) {
//m1(1,2,3,4,5);
int[] arr={12,3,4,5};
m1(arr);
add(10,20,40);
}
public static void add(int... nums){
int sum=0;
for (int i = 0; i < nums.length; i++) {
sum+=nums[i];
}
System.out.println("和为"+sum);
}
public static void m1(int... a){
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+"\t");
}
}
十一、值传递和引用传递
值传递和引用传递
- 值传递:传递的是值,所以原来的值本身不会改变,所有的基本类型+String都属于值传递
- 引用传递:传递的是地址,所以会对原来的内容有影响,所有引用数据类型都属于引用传递
代码展示:
// int i=10;
// System.out.println("i的值为"+i);//10
// m1(i);
// System.out.println("i的值在传递之后为"+i);//10
// String s="hello";
// System.out.println("s的值为"+s);//hello
// m2(s);
// System.out.println("s的值在传递之后为"+s);//hello
int[] arr={1,2,3};
System.out.println("arr[0]的值为"+arr[0]);//1
m3(arr);
System.out.println("arr[0]的值在传递之后为"+arr[0]);//12
}
public static void m3(int[] arr){
arr[0]=12;
}
public static void m2(String s){
s="asdfg";
}
public static void m1(int i){
i=20;