Java数组总结

一维数组的定义(3种):

1)先声明后初始化:
int[ ] arr;
arr = new int[5];
2)声明的同时进行初始化:
int[ ] arr = new int[ ]{1,2,3};
3)先声明后初始化使用系统默认分配的默认值(0):
int[ ] arr = new int[5];
注:错误定义方式:
int[ ] arr = new int[5]{1,2,3,4,5}; //定义的时候需要制定所需元素个数或者制定元素初始值,让程序自动推出元素个数
int[ ] brr = new int[ ]; //不能定义数组的大小的同时进行初始化

一维数组的遍历(3种):

1)for循环
2)foreach遍历
for(int i :arr){
System.out.print( i ); }
3)Arrays.toString( );方法

一维数组的拷贝(4种):

1)数组名.clone( );
int[ ] brr = arr.clone( );
2)Arrays.copyof( 原数组,拷贝数组长度);方法
3)System.arraycopy(原数组,原数组要复制的起始位置,目标数组,目标数组要放置的起始位置,复制长度);方法
4)for循环进行拷贝

二维数组的初始化(3种):

1)int[ ] [ ] arr = {{1,2,3},{4,5,6},{7,8,9}};
2)int[ ] [ ] arr = new int[3] [ ];
arr[0] = new int[3];
arr[1] = new int[3];
arr[2] = new int[3];
3)int[ ] [ ] = {new int[3],new int[3],new int[3]};

二维数组的遍历(3种):

1)Arrays.deepToString(int[ ] arr);
System.out.println(Arrays.deepToString(arr); )
2)for循环

int[] [] arr = new[] []{{1,2,3},{4,5,6}};
int[] [] brr = new[arr.length] [arr[0].length];
for(int i=0;i<arr.length;i++){
     for(int j=0;j<arr[i].length;j++){
                   brr[i][j] = arr[i][j] }
           }  

3)foreach循环遍历

int[][] arr = new int[][]{{1,2,3},{4,5,6}};
for(int[] brr : arr){
     for(int i : brr){
            System.out.print(i);
              }
        }      

二维数组的拷贝:

1)for循环

int[] [] arr = new[] []{{1,2,3},{4,5,6}};
int[] [] brr = new[arr.length] [arr[0].length];
for(int i=0;i<arr.length;i++){
     for(int j=0;j<arr[i].length;j++){
                   brr[i] [j] = arr[i] [j] }
           }  

2)数组名.clone( );方法
int[ ] [ ] = arr.clone( );
3)Arrays.copyof( );方法
int[ ] [ ] brr = Arrays.copyof(arr,arr.length);
4)System.arraycopy( );方法



练习时间到叮~  :将数组中的数奇数在前,偶数在后

//思路1:
int[] brr = new int[arr.length];
int i=0;
int left = 0;right = brr.length-1;
for(;i<arr.length;i++){
if(arr[i]%2 == 1){
brr[left++] = arr[i];//这里有一个二合一的小细节,原本先把arr[i]赋给brr[left],然后再left++,可以直接把left++和数组brr合并,下面right也一样
}else{
brr[right--] = arr[i];
}
}
System.out.println(Arrays.tostring(brr));
//思路2:
int i =0,j = arr.length-1;
while(i+1<j){
while(i<j && arr[i]%2 == 1){
i++;//
}
while(i<j && arr[j]%2 == 0){
j--;
}
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
System.out.println(Arrays.toString(arr));

插入数据与删除数据

(一).插入一个数(前提是当前数组有序):

public class Test {
public static int[ ]  insertValue(int[ ]  arr,int value){
int srcLen = arr.length;  / /原始数组长度
arr = Arrays.copyOf(arr,arr.length+1);
for(int i=0;i<srcLen;i++){
//从前向后找第一个比value大的数,插入到当前数字的前面,此时i小于原数组长度即可,刚好取到最后一个数字的下标
if(arr[i]>value){
//移动元素
for(int j=srcLen-1;j>=i;j--){
arr[j+1] = arr[j];
}
//不要忘了放值进去
arr[arr.length-1] = value;
return arr;
}

(二).删除一个数据(不能删除其中的重复的数据)

public static int search(int[] arr,int value){
for(int i=0;i<arr.length;i++){
if(arr[i] == value){
return i;
}
}return -1;
}
public static int[] delete(int[] arr,int value){
//1.查找value
int index = search(arr,value);
if(index<0){
return arr;
}
//2.移动数据
for(int i= index;i<arr.length-1;i++){
arr[i]=arr[i+1];
}//如果循环部分出现i+1那for中的i只能写成<arr.length-1,如果直接写成<arr.length下面的arr[i+1]会出现数组下标越界
//3.进行缩容
arr = Arrays.copuOf(arr,arr.length-1);
return arr;
}

(三.)删除连续重复的数据,例如删除[2,2,2,2]中的2

public static int[] deleteRepeatValue(int[] arr,int value){
for(int i=0;i<arr.length;){
if(arr[i] == value){
for(int j=i;j<arr.length-1;j++){
arr[j] = arr[j+1];
}
arr= Arrays.copuOf(arr,arr.length-1);
}else{
i++;
}
}
return arr;
}

我觉得对于初学者来说这个程序确实可圈可点,亮点在于数组遍历的for循环中没有给出末尾循环体i++,而将此表达式放在了其后的else中,我觉得对于初学者哪怕是学了好一段时间的朋友来说都应该会不自觉的在for中最后写上i++,那我们按照程序的逻辑想往下一下这样会带来如何的后果,首先用if找到了要删除的value的下标i,紧接着用j进行for遍历使value位置之后的数统一往前移动一位,覆盖掉此时的value达到删除的目的再进行缩容,如果其后还有同样值的value随着for循环的继续再进行同样的删除操作,但是此时遗留了一个最致命的问题,如果value之后紧跟的也是需要删除的同样值的value1,在移动数据缩容之后,后面的value1覆盖掉了之前的value但此时的value1的下标也变成了之前已经覆盖掉的value的下标,再次进入for循环的i++就会完美跳过此时的value1,最终所导致的结果就是没有办法删除连续重复的数据例子中的[2,2,2,2],会变成[2,2],而把i++写在其后的else中就会弥补此漏洞了

二分(折半)查找与冒泡排序

二分查找:前提是有序的,其核心思想是将有序列表的中间位置元素与目标元素进行比较,如果相等则查找成功,如果不相等则继续与前半部分或后半部分的中间位置元素进行比较,每次比较后长度都会减少一半,直到找到目标元素

public static int binarySearch(int[] arr,int value){
int left =0;
int right= arr.length-1;
while(left<=right){
int midIndex = (left+right)/2;
if (arr[midIndex]>value){
right=midIndex-1;
}else if (arr[midIndex]<value){
left = midIndex+1;
}else{
return midIndex;
}
}
return -1;
}

这里再写一个最经典的排序方法,冒泡排序,为什么偏偏要在这种时候单独写一个排序方法呢,还不是因为二分查找的前提是有序的。冒泡的原理即依次比较两个数的大小,将小数放在前面大数放在后面(数据从小往大排),先比较第一个数和第二个数,满足条件不交换位置,不满足条件交换位置,再比较第二个数和第三个数,依次进行,仔细品味的话是有点冒泡的感觉的我总觉得还是不够形象,虽然每次比较的位置会不停往后推移,但也无法确定新交换好位置的数据与之前交换好位置数据的大小关系,所以这样的冒泡肯定不止一趟,但是每趟冒泡可以确定的是最后两位数据一定满足所需要的大小要求,所以再一次冒泡的时候就不需要再考虑最后一个数据了,依次类推每趟冒泡都会少考虑一个数据(倒数第一个,第二个…),n个数据单独比较一趟需要比较n-i次(i为趟数),一共要走n-1趟

public static void bubbleSort(int n[] arr){
for(int i=0;i<arr.length;i++){//外层i控制趟数
for(int j=0;j<arr.length-1-i;j++){//内层j控制每一趟排序次数,并且下面有j+1上面一定要length-1否则会数组下标越界
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}

简单的登录注册系统

登录注册功能:
请选择:1.注册 2.登录 3.退出
1
请输入账号:
111
注册成功
请选择:1.注册 2.登录 3.退出
1
请输入账号:
111
注册失败
请选择:1.注册 2.登录 3.退出
2
请输入账号
111
登录成功

public static boolean login(int[] arr){
System.out.println("请输入账号:");
Scanner scanner = new Scanner(System.in);
int id = scanner.nextInt();
for(int i=0;i<arr.length;i++){
if(arr[i]==id){
return true;
}
}
return false;
}
public static boolean register(int[] arr,int size){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入账号");
int id = scanner.nextInt();
for(int i=0;i<size;i++){
if(arr[i] == id){
return false;
}
}
arr[size]=id;
return true;
}
public static int[] checkCapacity(int[] arr,int size){
if(size  == arr.length){
arr = Arrays.copyOf(arr,arr.length*2);
}
return arr;
}
public static void operate(){
int[] arr =new int[1];
int size = 0;
while(true){
System.out.println("1.注册  2.登录  3.退出");
Scanner scanner = new Scanner(System.in);
int chioce = scanner.nextInt();
if(chioce == 3){
return;
}
switch(chioce){
case 1:
boolean flag = login(arr,size);
if(flag){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
break;
case 2:
arr = checkCapacity(arr,size);
flag = register(arr,size);
if(flag == true){
System.out.println("注册成功");
size++;
}else{
System.out.println("注册失败");
}
break;
}
}
}
public static void main(String[] args){
operate();
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值