一、概念
1、数组的定义
数组:同一种类型数据的集合。
2、数组的好处
可以自动给数组中的元素从0开始编号,方便操作这些元素。
3、数组的内存结构
Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
1)栈内存
2)堆内存
(1)数组和对象,通过new建立的实例都存放在堆内存中。
(2)每一个实体都有内存地址值
(3)实体中的变量都有默认初始化值
(4)实体不在被使用,会在不确定的时间内被垃圾回收器回收
4、垃圾回收机制
Java本身成长于C++,它优化了C++语言的一些特性,而变得更简单易学、易懂,尤其在内存这一块,要比C++做得好,C++的特点在于,我们写程序,会在内存中开辟空间。当实体越来越多时,比较占用内存空间,由程序员手动地调用一个功能把程序清除掉。如果程序员忘了做,这些程序运行时间越长,运行越慢,甚至最后会死机。而JAVA把这部分优化了,程序员不用手动清除。只要对象和实体在堆内存中已经变成垃圾,Java虚拟机会自动地帮我们启动垃圾回收机制,将堆内存中不再被使用的实体清除掉。
二、格式一
格式1:
元素类型[ ]数组名 = new 元素类型[元素个数或数组长度];
示例:int [ ] arr = new int [5]
格式2:
元素类型[ ] 数组名 = new 元素类型[ ]{元素,元素,……};
Int[ ] arr = new int [ ] {3,5,1,7};
Int[ ] arr = {3,5,1,7};
三、常见错误
1、出现ArrayIndexOutofBoundsException
操作数组时,访问到了数组中不存在的角标。
2、出现 NullPointerException
空指针异常。当引用没有任何指向值为null的情况,该引用还在用于操作实体。
四、常见操作
1、遍历
/*思路:1.定义变量,让其与数组长度比较,构成循环。
2.构建打印数组格式,并排列好字符。
*/
class shuzu
{
public static void main(String[] args)
{
int [] arr={1,3,5,7,9,11};
printArray(arr);
}
public static void printArray(int[] arr)
{
System.out.print("[");//先打印个[
for (int x=0;x<arr.length ;x++ )//用for语句来循环
{
if(x!=arr.length-1)//用if来控制,个数
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");//最后打印]
}
}
}
结果输出:
2、获取最值
/*思路:1.定义变量作为存放最大值,并与数组中的元素进行比较。若元素大,取元素。反之。
2.用for构建循环,遍历找出最大值
*/
class max1
{
public static int getMax(int[] arr)//创建选取最大值函数
{
int max =arr[0];
for (int x=1;x<arr.length ; x++)//遍历
{
if(max<arr[x])//条件比较选取
max=arr[x];
}
return max;
}
public static void main(String[] args)//定义主函数
{
int[] arr=new int[]{7,9,11,3,5,19,8};
int max =getMax(arr);
System.out.println("max="+max);
}
}
结果输出:
可不可以将临时变量初始化为0呢?可以。这种方式,其实是在初始化为数组中任意一个角标。
public class forfor {
/**
*
* @param args
*/
public static void main(String[] args) {
//创建数组
int[] arr=new int[]{1,78,34,5,68};
//调用函数
getMax(arr);
//提取返回值
int max=getMax(arr);
//打印
System.out.println(max);
}
public static int getMax(int[] arr){
//定义变量
int max=0;
//循环比较
for (int i = 1; i < arr.length; i++) {
if(arr[max]<arr[i]){
max=i;
}
}
return arr[max];
}
}
3、选择排序
/*需求:对给定数组进行排序
[1,9,5,8,3,12,2]
思路:1.整体分模块,一个为主函数,一个为打印数组,一个为排序。
2.排序:一对多遍历对比,得出最值后互换位置,借用第三方变量存储来实现。
3.循环遍历,用到for语句;用if条件控制。
*/
class select1
{
public static void selectSort(int[] arr)//排序模块
{
for (int x=0;x<arr.length-1; x++)//前面排序完了,最后一个只能和自己排序,没必要。所以length-1
{
for (int y=x+1;y<arr.length ;y++)//x对y为一前多后
{
if(arr[x]>arr[y])//设置条件,借用第三方变量完成元素置换
{
int temp =arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
}
}
}
public static void main(String[] args)//主函数模块
{
int[] arr=new int[]{1,9,8,3,12,2};
printArray(arr);//打印未排序的数组
selectSort(arr);//排序数组
printArray(arr);//打印排序后的数组
}
public static void printArray(int[] arr)//打印模块
{
System.out.print("[");
for (int x=0;x<arr.length;x++)//用for来控制循环
{
if(x!=arr.length-1)//控制,的个数
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
结果输出:
4、冒泡排序
/*需求:对给定数组进行排序
[1,9,5,8,3,12,2]
思路:1.整体分模块,一个为主函数,一个为打印数组,一个为排序。
2.排序:两两比较,小的左移,大的右移,第一次能在右边得到一个最大值,借用第三方变量存储来实现。
3.循环遍历,用到for语句;用if条件控制。
*/
class select1
{
public static void bubbleSort(int[] arr)//排序模块
{
for (int x=0;x<arr.length-1; x++)//前面排序完了,最后一个只能和自己排序,没必要。所以length-1
{
for (int y=0;y<arr.length-x-1;y++)//-x:让每次比较的元素减少;-1:防止角标越界。
{
if(arr[y]>arr[y+1])//设置条件,借用第三方变量完成元素置换
{
int temp =arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
}
public static void main(String[] args)//主函数模块
{
int[] arr=new int[]{1,9,8,3,12,2};
printArray(arr);//打印未排序的数组
bubbleSort(arr);//冒泡排序数组
printArray(arr);//打印排序后的数组
}
public static void printArray(int[] arr)//打印模块
{
System.out.print("[");
for (int x=0;x<arr.length;x++)//用for来控制循环
{
if(x!=arr.length-1)//控制,的个数
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
结果输出:
public class select {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义数组
int[] arr=new int[]{12,24,35,57,23,253,1};
//调用函数
selectDemo(arr);
printArray(arr);
}
public static void selectDemo(int[] arr){
//外循环控制行
for(int x=0;x<arr.length-1;x++){
//内循环控制列的内容
for(int y=x+1;y<arr.length;y++){
if(arr[x]<arr[y]){
//元素互换
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
}
}
}
public static void printArray(int[] arr){
System.out.print("[");
for(int x=0;x<arr.length;x++){
//如果不为末尾元素
if(x!=arr.length-1){
System.out.print(arr[x]+",");
}
else
System.out.print(arr[x]+"]");
}
}
}
我的总结:选择排序和冒泡排序有相似的代码块,只要把第二版新代码选择排序内循环的变量int y=x+1改为int y=1,y=arr.length改为arr.length-x-1,即可变为冒泡排序。
5、位置置换功能抽取
/*需求:对给定数组进行排序
[1,9,5,8,3,12,2]
思路:1.整体分模块,一个为主函数,一个为打印数组,一个为排序。
2.排序:两两比较,小的左移,大的右移,第一次能在右边得到一个最大值,借用第三方变量存储来实现。
3.循环遍历,用到for语句;用if条件控制。
*/
class select1
{
public static void bubbleSort(int[] arr)//排序模块
{
for (int x=0;x<arr.length-1; x++)//前面排序完了,最后一个只能和自己排序,没必要。所以length-1
{
for (int y=0;y<arr.length-x-1;y++)//-x:让每次比较的元素减少;-1:防止角标越界。
{
if(arr[y]>arr[y+1])//设置条件,借用第三方变量完成元素置换
{
/*int temp =arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
*/
swap(arr,y,y+1);//封装代码
}
}
}
}
public static void main(String[] args)//主函数模块
{
int[] arr=new int[]{1,9,8,3,12,2};
printArray(arr);//打印未排序的数组
bubbleSort(arr);//冒泡排序数组
printArray(arr);//打印排序后的数组
}
public static void printArray(int[] arr)//打印模块
{
System.out.print("[");
for (int x=0;x<arr.length;x++)//用for来控制循环
{
if(x!=arr.length-1)//控制,的个数
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
public static void swap(int[] arr,int a,int b)
{
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
}
结果输出:
6、折半查找
/*需求:有一个有序的数组,想要将一个元素8插入这个数组种,还要保证这数组时有序的。
思路:1.将该元素与数组中的中间值比较
2.当max<min时,这元素可插在mid的位置。
*/
class halfsearch
{
public static void main(String[] args)
{
int[] arr=new int[]{1,3,6,8,10,45,67,90};
int index=getIndex(arr,8);
System.out.println("index="+index);
}
public static int getIndex(int[] arr,int key)
{
int min=0,max=arr.length-1,mid;//定义三变量协助寻找8的位置
while(min<=max)//终止循环条件
{
mid=(max+min)/2;
if(key>arr[mid])//选右半边继续找
min=mid+1;
else if(key<arr[mid])//选左半边继续找
max=mid-1;
else
return mid;
}
return min;
}
}
结果输出:
7、进制转换
/*需求:把十进制数转换为二进制数、八进制数、十六进制数
思路:1.不论转换为二、八、十六进制都有共通部分,所以把共同部分封装做成一个函数
2.制表存数
3.建立求余循环;建立指针打印循环。
*/
class hi
{
public static void main(String[] args)
{
toBin(60);
}
public static void toBin(int num)//十进制转二进制
{
trans(num,1,1);
}
public static void toOct(int num)//十进制转八进制
{
trans(num,7,3);
}
public static void toHex(int num)//十进制转十六进制
{
trans(num,15,4);
}
public static void trans(int num,int base,int offset)//封装的公共部分
{
if(num==0)//特殊情况:0值
{
System.out.println(0);
return ;
}
char[] chs={'0','1','2','3','4',//建表作为存储容器
'5','6','7','8',
'9','A','B','C',
'D','E','F'};
char[] arr=new char[32];//32位足够装
int pos=arr.length;//指针由后向前
while(num!=0)//打印有效位
{
int temp=num & base;//求余
arr[--pos]=chs[temp];//查表得对应值
num=num >>> offset; //移位
}
for (int x=pos;x<arr.length;x++)//指针的循环部分,打印有效位
{
System.out.print(arr[x]);
}
}
}
结果输出:
八、二维数组
格式1:int[ ][ ] arr=new int[3][2];
a. 定义了名称为arr的二维数组
b. 二维数组中有3个一位数组
c. 每一个一位数组中有2个元素
d. 一维数组的名称分别为arr[0],arr[1],arr[2]
e. 给第一个一维数组1脚标位赋值为78写法是:arr[0][1]=78
格式2:int[ ][ ] arr=new int[3][ ];
a. 二位数组中有3个一位数组
b. 每个以为数组都是默认初始化值null
c. 可以对这个三个一维数组分别进行初始化
arr[0]=new int[3];
arr[1]=new int[1];
arr[2]=new int[2];