数组概念
同一种类型数据的集合。其实,数组就是一个容器。
数组的操作
数组类型是引用数据类型的一种
获取数组中的元素.通常要用到遍历
定义数组的三种形式:
int[] arr = new int[]{2,4,5};
int[] arr = new int[3];(容量为3的数组)
int[] arr = {1,3,5,4,343};
数组脚标越界异常(ArrayIndexOutOfBoundsException):访问到了数组中的不存在的脚标。
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = new int[3];
System. out.println(arr[3]);
}
}
空指针异常(NullPointerException):当引用型变量没有指向任何实体时,用其操作实体,就会发生该异常
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = null;
System. out.println(arr[0]);
}
}
直接打印数组的引用变量,打印出来的结果是数组初始地址的哈希值。
class ArrayDemo
{
public static void main(String[] args)
{
int [] arr = new int [3];
System.out.println(arr);
}
}
数组中有一个属性可以直接获取到数组元素个数。length
使用方式:数组名称.length
定义功能:打印数组中的元素,元素间用“,”隔开
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.println(arr[x]+"]");
}
}
练习:
给定一个数组{33,5,7,3,35,6,0}
获取数组的最大值和最小值
获取数组的最大值
思路:
1,获取最值需要比较,每一次都会有一个较大的值。因为该值不确定,
通过一个变量进行临时存储
2,让数组中的每一个元素都和这个变量中的值进行比较 如果大于了变量中的值。就用该变量记录较大的值
3,当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值
步骤:
1,定义一个变量,初始化为数组中任意一个元素即可
2,通过循环语句对数组进行遍历
3,在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量
需要定义一个功能来完成,以便提高复用性
1,明确结果,数组中的最大元素 int
2,未知内容:一个数组。int[]
public static int getmax(int[] arr)
{
int max = arr[0];
for(int x=1;x<arr.length;x++)
{
if(arr[x]>max)
max=arr[x];
}
return max;
}
获取最大值的另一种方式
可不可以将临时变量初始化为0呢
这种方式是在初始化为数组的任意一个角标
这种方法在取最小值中体现出来
public static int getmin(int[] arr)
{
int min = 0;
for(int x=1;x<arr.length;x++)
{
if(arr[x]<arr[min])
min = x;
}
return arr[min];
}
排序方式
1,选择排序
思路:
1、首先拿数组第一个元素依次与除其自身外的其他每个元素顺序比较,如果第一个元素大于剩下的某个元素,就互换内容。
2、经过第一轮比较之后,此时,第一个元素就是数组中最小的元素。然后再拿第二个元素与除第一个元素和其自身的元素进行比较,如果第二个元素大于剩下的某个元素,就互换内容。此时,第二个元素就是数组中倒数第二小的元素。
3、依次类推,直到最后一个元素。
练习:
按大小排列数组中元素的顺序{2,23,5,6,9,1}
从小到大排列
内循环结束一次,最值出现在头角标位上
选择排序
public static void selectsort(int[] arr)
{
for(int x=0;x<arr.length-1;x++)
{
for(int y=x+1;y<arr.length;y++)
{
if(arr[y]<arr[x])
{
swap(arr,x,y);//换位置
}
}
}
}
//打印数组
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.println(arr[x]+"]");
}
}
//换位置操作
public static void swap(int[] arr,int a,int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public static void main(String[] args)
{
int[] arr={2,23,5,6,9,1};
selectsort(arr);//选择排序
printArray(arr);//打印数组
}
2,冒泡排序
相邻的两个元素相互比较,如果符合条件换位
第一圈,最大值出现在最后位
第二圈,次大值出现在倒数第二位
……
最终,最小值出现在第一位
public static void bubblesort(int[] arr)
{
for(int x=0;x<arr.length-1;x++)
{
for(int y=0;y<arr.length-x-1;y++)//-x让每一次比较的元素减少。-1避免角标越界
{
if(arr[y]>arr[y+1])
{
swap(arr,y,y+1);
}
}
}
}
public static void swap(int[] arr,int a,int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = 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.println(arr[x]+"]");
}
}
public static void main(String[] args)
{
int[] arr={2,23,5,6,9,1};
bubblesort(arr);
printArray(arr);
}
发现无论什么排序都需要对满足条件的元素进行位置置换
所以可以把这部分相同的代码提取出来,单独封装成一个函数
public static void swap(int[] arr,int a,int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
在真实开发中,是不可能让我们自己去写这些排序算法的,因为JDK中已经提供好了API可以直接供我们调用。
import java.util.Arrays;//必须导包
class ArrayTest2
{
public static void main(String[] args)
{
int[] arr= {2,23,36,8,16};
System.out.print("排序前数组:" );
printArray(arr);
Arrays.sort(arr);//系统的排序方法
System.out.print("排序后数组:" );
printArray(arr);
}
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.println(arr[x] + "]" );
}
}
}
数组的查找操作。
此方法获取的是key第一次在数组中出现的位置
如果返回值为-1,则表示这个数在数组中不存在
class ArrayTest4
{
public static void main(String[] args)
{
int[] arr = {2,3,8,7,8,6,9};
int index = getIndex(arr,8);
System.out.println("index="+index);
}
public static int getIndex(int[] arr,int key)
{
for(int x=0;x<arr.length;x++)
{
if(arr[x]==key)
return x;
}
return -1;
}
}
折半查找
折半查找可以提高效率,但必须保证数组有序
class ArrayTest4
{
public static void main(String[] args)
{
int[] arr= {1,3,4,6,7,9};
int index = halfsearch(arr,8);
System.out.println("index="+index);
}
public static int halfsearch(int[] arr,int key)
{
int min,max,mid;
min = 0;
max = arr.length-1;
mid = (max+min)/2;
while(arr[mid] != key)
{
if(key>arr[mid])
min = mid+1;
else if(key<arr[mid])
max = mid-1;
if(min>max)
return -1;
mid = (max+min)/2;
}
return mid;
}
}
折半的第二种方式
class ArrayTest4
{
public static void main(String[] args)
{
int[] arr= {1,3,4,6,7,9};
int index = halfsearch2(arr,3);
System.out.println("index="+index);
}
public static int halfsearch2(int[] arr,int key)
{
int min = 0,max = arr.length-1,mid;
while(min<=max)
{
mid = (max+min)>>1;//就是(max+min)/2
if(key>arr[mid])
min = mid+1;
else if(key<arr[mid])
max = mid-1;
else
return mid;
}
return -1;
}
}
有一个有序的数组,将一个数插入到该数组中,
还要保证该数组是有序的。如何获取该元素在数组中的位置。
就是折半的更深一层理解
public static int getIndex2(int[] arr,int key)
{
int min = 0,max = arr.length-1,mid;
while(min<=max)
{
mid = (max+min)>>1;
if(key>arr[mid])
min = mid+1;
else if(key<arr[mid])
max = mid-1;
else
return mid;
}
return min;
}
进制转换
十进制–>二进制
public static void toBin(int num)
{
StringBuffer sb = new StringBuffer();//一个容器,有反转功能
while(num>0)
{
//System.out.println(num%2);
sb.append(num%2);
num = num/2;
}
System.out.println(sb.reverse());
//reverse是容器具备的功能
}
十进制–>十六进制
public static void toHex(int num)
{
StringBuffer sb = new StringBuffer();
for(int x=0;x<8;x++)
{
int temp=num&15;
if(temp>9)
//System.out.println((char)(temp-10+'A'));
sb.append((char)(temp-10+'a'));
else
//System.out.println(temp);
sb.append(temp);
num= num>>>4;
}
System.out.println(sb.reverse());
}
查表法:
将所有的元素临时存储起来,建立对应关系
每一次&15后的值作为索引查建立好的表,可以找到对应的元素
通过数组的形式建立。
class ArrayTest6
{
public static void main(String[] args)
{
//toHex(-900);
toBin(-6);
}
/*
0 1 2 3 4 5 6 7 8 9 A B C E F ==十六进制
0 1 2 3 4 5 6 7 8 9 11 12 13 14 15
*/
public static void toHex(int num)
{
char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//定义一个临时容器,数组
char[] arr = new char[8];
int pos = arr.length;
while(num!=0)
{
int temp = num & 15;
//System.out.println(chs[temp]);
arr[--pos] = chs[temp];
num = num >>> 4;
}
System.out.println("pos="+pos);
//存储数据的arr数组遍历一下
for(int x=pos;x<arr.length;x++)
{
System.out.print(arr[x]);
}
}
/*
十进制转化为二进制
*/
public static void toBin(int num)
{
//定义二进制的表
char[] chs = {'0','1'};
//定义一个临时存储容器。
char[] arr = new char[32];
//定义一个操作数组的指针
int pos = arr.length;
while(num != 0)
{
int temp = num & 1;
arr[--pos] = chs[temp];
num = num >>>1;
}
System.out.println("pos="+pos);
for(int x=pos;x<arr.length;x++)
{
System.out.print(arr[x]);
}
}
}
数组中的数组
二维数组[][]
格式1:
int[][] arr = new int[3][2];
1、定义了名称为arr的二维数组。
2、二维数组中有3个一维数组。
3、每一个一维数组中有2个元素。
4、一维数组的名称分别为arr[0], arr[1], arr[2]。
5、给第一个一维数组第一个脚标位赋值为78写法是:arr[0][0] = 78;。
6、arr存储的是二维数组的初始地址,arr[0]、arr[1]、arr[2]存储的是一维数组的初始地址。
int[] arr = new int[3];
一位数组
int[][] arr = new int[3][4];
二维数组有三个一维数组,每个一维数组有四个元素
第二种形式
int[][] arr = {{2,3,4,6},{6,2,6,8},{5,9,0,1},};
二维数组求和
int[][] arr = {{2,3,4,6},{6,2,6,8},{5,9,0,1},};
int sum = 0;
for(int x =0;x<arr.length;x++)
{
for(int y = 0;y<arr[x].length;y++)
{
sum+=arr[x][y];
}
}
System.out.println("sum="+sum);