- 引用数据类型
- 通过下标实现数据的存储或获取
- 在堆中开辟内存,有默认值
- 开辟的内存是连续的
- 便于数据的查找,不便于数据的删除和添加
内存分配
int[] arr = new int[5];
arr是一个局部变量,存储的是数组在堆中的首地址
arr = new int[8];
arr中存储的地址被一个新的数组的地址覆盖了。因此之前的数组就成了垃圾,等待垃圾回收线程回收
int[] brr = arr;
变量之间的赋值,brr中存储了和arr相同的数值,所以和arr指向相同的数组
arr = null;
这时arr不再指向长度为8的数组,但是brr依然指向它,所以该数组不是垃圾
常见异常
- 数组下标越界
- 空指针异常
int[] arr;
arr=new int[3];
System.out.print1n(arr[3]);//ArrayIndexOutOfBoundsException: 3数组 下标越界
arr=null;
System.out.println(arr[0]);//NullPointerException空指针异常
初始化
数组的初始化:定义数组中存放的数据
//方法1:
int[] arr={3,4,5,6,7};
for(int i=0;i<5;i++)
{
System.out.println(arr[i]);
}
//方法2:
int[] brr=new int[]{44,55,77,12,8};
for(int i=0;i<brr.length;i++)
{
System.out.print(brr[i]);
}
存值
Scanner sc=new Scanner(System.in);
int[] crr=new int[3];
for(int i=0;i<crr.length;i++)
{
System.out.println("请输入第"+(i+1)+"个数");
crr[i] = sc.nextInt();
}
排序
选择排序
依次固定每个下标(除了最后一个下标),让固定下标中的数据和后边所有的数据分别比较,如果后边的数据小于前边的则交换,最终是从小到大排序。
public static void main(String[] args)
{
int[] arr={3,10,8,19,15};
selectSort(arr);
System.out.println(Arrays.toString(arr));
}
//选择排序
public static void selectSort(int[] arr)
{
int c;
for(int i=0;i<arr.length-1;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[j]<arr[i])
{
c=arr[j];
arr[j]=arr[i];
arr[i]=c;
}
}
}
}
冒泡排序
下标相邻的两两比较,如果顺序错误就把他们交换过来。
public static void main(String[] args)
{
int[] arr={3,10,8,19,15};
bubble(arr);
System.out.println(Arrays.toString(arr));
}
//冒泡排序
public static void bubble(int[] arr)
{
for(int i=1;i<arr.length-1;i++)
{
for (int j=0; j<arr.length-i-1; j++)
{
if (arr[j+1]<arr[j])
{
change(arr,j+1,j);
}
}
}
}
查找
二分法查找
- 前提:有序的
public static void main(String[] args)
{
int[] arr={10,22,26,35,55,67,89};
int key=55;
int index=halfFind(arr,key);
System.out.println("index="+index);
}
//二分法查找
public static int halfFind(int[] arr,int key)
{
int min=0,max=arr.length-1,mid;
while (min<=max)
{
mid=(min+max)/2;
if (key<arr[mid])
{
max=mid-1;
}
else if (key>arr[mid])
{
min=mid+1;
}
else
return mid;
}
return -1;
}
进制转换
位运算
//十进制转十六进制:位运算
int num=60;
int a=num&15;
int b=num>>>4;
System.out.println(""+b+(char)(a-10+'a'));
数组&循环
//十进制转十六进制:数组&循环
public static void to16(int num)
{
int[] arr=new int[8];
int index=arr.length;
while (num!=0)
{
arr[--index]=num&15;
num=num>>>4;
}
for (; index<arr.length; index++)
{
if (arr[index]>9)
{
System.out.println((char)(arr[index]-10+'a'));
}
else
{
System.out.print(arr[index]);
}
}
System.out.println();
}
查表法
//十进制转十六进制:查表法
public static void a16(int num)
{
char[] ch={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
char[] arr=new char[8];
int index=arr.length;
while (num!=0)
{
int a=num&15;
arr[--index]=ch[a];
num=num>>>4;
}
for (;index<arr.length; index++)
{
System.out.print(arr[index]);
}
System.out.println();
}
//十进制转八进制:查表法
public static void a8(int num)
{
char[] ch={'0','1','2','3','4','5','6','7'};
char[] arr=new char[11];
int index=arr.length;
while (num!=0)
{
int a=num&7;
arr[--index]=ch[a];
num=num>>>3;
}
for (;index<arr.length; index++)
{
System.out.print(arr[index]);
}
System.out.println();
}
//十进制转二进制:查表法
public static void a2(int num)
{
char[] ch={'0','1'};
char[] arr=new char[32];
int index=arr.length;
while (num!=0)
{
int a=num&1;
arr[--index]=ch[a];
num=num>>>1;
}
for (;index<arr.length; index++)
{
System.out.print(arr[index]);
}
System.out.println();
}
通用写法:
//十进制转x进制:查表法
public static void toAny(int num, int base, int offSet)
{
char[] ch={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
char[] arr=new char[32];
int index=arr.length;
while (num!=0)
{
int a=num & base;
arr[--index]=ch[a];
num=num>>>offSet;
}
for (;index<arr.length; index++)
{
System.out.print(arr[index]);
}
System.out.println();
}
public static void toHex(int num)
{
toAny(num,15,4);
}
public static void toOctal(int num)
{
toAny(num,7,3);
}
public static void toBinary(int num)
{
toAny(num,1,1);
}
java.util.Arrays
-
Arrays.copyOf(arr, 6);
第一个参数是被拷贝的数组,第二个参数是拷贝的数据的个数,返回一个新的数组,多拷贝的数据使用默认值
-
Arrays.copyOfRange(arr, 1, 4);
第二个参数是拷贝的数据的起始下标,第三个参数是拷贝的数据的结束下标+1
-
Arrays.toString(arr);
把数组中的数据转成字符串
-
Arrays.equals(arr, brr);
判断两个数组中的数据是否一样
-
Arrays.sort(arr);
排序
-
Arrays.binarySearch(arr, 8);
二分法查找,第二个参数是要查的找的数据
-
Arrays.fill(arr,66);
填充,第一个参数是被填充的数组,第二个参数是要填充的数据,会把数组中存放的数据全部填充为指定数据
import java.util.Arrays; class Arr { public static void main(String[] args) { int[] arr={23,15,36,8,88}; //拷贝 int[] brr = Arrays.copyOf(arr,6); //把数组中的数据转成字符串 System.out.println(Arrays.toString(brr)); //拷贝指定范围 int[] crr = Arrays.copyOfRange(arr,1,4); System.out.println(Arrays.toString(crr)); //判断两个数组中的数据是否一样 boolean boo = Arrays.equals(arr,brr); System.out.println(boo);//false //排序 Arrays.sort(arr); System.out.println(Arrays.toString(arr)); //二分法查找 注意:使用该方法前,需先排序 int index = Arrays.binarySearch(arr,23); System.out.println(index); //填充 Arrays.fill(arr, 66); System.out.println(Arrays.toString(arr)); //[66, 66, 66, 66, 66] } }
拷贝数组
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
- 第一个参数是被拷贝的数组;
- 第二个参数是被拷贝的数据的起始下标;
- 第三个参数是拷贝到的数组;
- 第四个参数是拷贝到的数组的起始下标;
- 第五个参数是拷贝数据的个数。
应用
import java.util.Array; class Home2 { public static void main(String[] args) { System.out.println(); } } class MutableArray{ private Object[] arr; MutableArray(){ arr=new Object[0]; } //添加数据 public void add(Object obj){ Object[] array = Arrays.copyOf(arr,arr.length+1); //把数据存储到数组中 array[array.length-1]=obj; arr=array; } //add(1, "lily") 在指定下标位置添加数据 public void add(int index,Object obj){ Object[] array = Arrays.copyOf(arr,arr.length+1); System.arraycopy(array,index,array,index+1,array.length-1-index); array[index]=obj; arr=array; } //remove("lily"); 删除 public void remove(Object obj){ int index=-1; //从数组中查找被删除的数 for(int i=0;i<arr.length;i++) if(arr[i].equals(obj)){ index=i; break; } if(index==-1) return; System.arraycopy(arr,index+1,arr,index,arr.length-1-index); Object[] array = Arrays.copyOf(arr,arr.length-1); arr=array; } //remove(1) public void remove(int index){ if(index<0 || index>=arr.length) return; System.arraycopy(arr,index+1,arr,index,arr.length-1-index); Object[] array = Arrays.copyOf(arr,arr.length-1); arr=array; } //clear() public void clear() { arr=new Object[0]; } //set(1, "lucy"); public void set(int index,Object obj){ if(index<0 || index>=arr.length) return; arr[index]=obj; } //get(1) public Object get(int index){ if(index<0 || index>=arr.length) return; return arr[index]; } public String toString(){ return Arrays.toString(arr); } }
可变参数
规则
数据类型…
e.g.: int…
特点
- 可以接收任意多的数据
- 本质上还是数组
- 可变参数必须位于参数列表的最后
public static void main(String[] args){
//int[] arr={2,3,45,6,78,8,9};
int sum = add(2,34,23,67);
System.out.println( sum);
}
//public static int add(int a,int... arr)//参数+可变参数
public static int add(int... arr)//可变参数
{
int sum=0;
for(int i=0;i<arr.length;i++)
sum+=arr[i];
return sum;
}
二维数组
初始化
二维数组的第二个值可以省略
int[][] arr=new int[2][];
arr[0]=new int[5];
arr[1]=new int[8];
内存情况
可看作一个存放多个一维数组地址的数组
int[][] arr=new int[2][3];
//arr.length=2
//arr[0].length=3
遍历数组
for(type element:array){……}
for(数据类型 变量:被遍历的内容){……}
-
式中,type为数组array的类型;element是用来存放数组中元素的临时变量;array是待操作的数组。
-
作用是:对数组中的数据依次进行存取。比如下面的代码中,代码的功能是:每次从数组arr中取出元素arr[i],并自动设定给num,不用判断是否超出了数组的长度。
增强的for循环
有一定的局限性:只能得到数组中的数据
优点:每次从数组array中取数据,会自动赋给变量element,并且不用编译器判断是否超出了数组的长度。也即省去了标准for语句里的判决条件,如”i<=array.length“。
int[] arr={1,2,3,4,5};
for(int i=0;i<arr.length;i++)
arr[i]=arr[i]*3;
for(int num:arr)//依次取出数组arr中的元素赋给变量num
System.out.println(num);//输出e
// 3 6 9 12 15