【Java.SE】数组的练习

news/2024/10/23 9:22:28/

作者简介: 辭七七,目前大一,正在学习C/C++,Java,Python等
作者主页: 七七的个人主页
文章收录专栏:Java.SE,本专栏主要讲解运算符,程序逻辑控制,方法的使用,数组的使用,类和对象,继承和多态,抽象类和接口等内容
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

在这里插入图片描述


数组的练习

  • 1. 数组转字符串
    • 1.1 自己实现一个tostring函数
  • 2. 数组拷贝
  • 3. 求数组中元素的平均值
  • 4. 查找数组中指定元素(顺序查找)
  • 5. 查找数组中指定元素(二分查找)
  • 6. 数组排序(冒泡排序)
  • 7. 数组逆序
  • 8. 二维数组

1. 数组转字符串

数组转字符串我们需要借助工具类

代码示例

import java.util.Arrays  //Java中的包 public class TestDemo {public static int[] func() {return new int[]{1,2,3,4,5,6};}public static void main(String[] args) {int[] ret = func();//这个方法主要将参数的数组转化为字符串输出String s = Arrays.toString(ret);//Ctrl+鼠标点击,可以跳转到这个方法的原码System.out.println(s);}
}//执行结果
[1, 2, 3, 4, 5, 6]

使用这个方法后续打印数组就更方便一些.
Java 中提供了 java.util.Arrays 包,其中包含了一些操作数组的常用方法。

我们可以在jdk里搜索一下Arrays的用法,如图所示:
在这里插入图片描述

1.1 自己实现一个tostring函数

定义一个myToString的方法,利用for循环和if判断来解决问题
代码示例:

public class TestDemo {public static String myToString(int[] array){String ret = "[";for (int i = 0; i < array.length; i++) {ret += array[i];if (i != array.length -1){ret += ",";}}ret += "]";return ret;}public static void main(String[] args) {int[] array = {1,2,3,4,5};String ret = myToString(array);System.out.println(ret);}
}

打印结果:
在这里插入图片描述

2. 数组拷贝

先来看一个简单的数组拷贝:
使用for循环来完成的拷贝

public class TestDemo {public static void main(String[] args) {int[] array = {1,2,3,4,5};int[] copy = new int[array.length];for (int i = 0; i < array.length; i++) {copy[i] = array[i];}System.out.println(Arrays.toString(copy));}
}

打印结果:
在这里插入图片描述
以下代码是不是拷贝
在这里插入图片描述

答案:不是

在上述代码中我们可以通过修改形参的值来改变实参

// array3和array2引用的是同一个数组// 因此array3修改空间中内容之后,array2也可以看到修改的结果int[] array2 = {1,2,3,4,5};int[] array3 = array2;array3[0] = 10;System.out.println("newArr: " + Arrays.toString(array2));

我们可以不用for循环来拷贝数组,直接用Arrays中的copyof方法来完成

import java.util.Arrayspublic class TestDemo {public static void main(String[] args) {int[] array = {1,2,3,4,5};int[] copy = Arrays.copyOf(array,array.length);System.out.println(Arrays.toString(copy));}
}

//使用Arrays中copyOf方法完成数组的拷贝:
// copyOf方法在进行数组拷贝时,创建了一个新的数组
// array和copy引用的不是同一个数组

数组的扩容:array.length后 *2 就是扩大两倍
代码示例:

import java.util.Arrayspublic class TestDemo {public static void main(String[] args) {int[] array = {1,2,3,4,5};int[] copy = Arrays.copyOf(array,array.length*2);System.out.println(Arrays.toString(copy));}
}

运行结果:
在这里插入图片描述
拷贝某个范围
代码示例

public class TestDemo {public static void main(String[] args) {int[] array = {1,2,3,4,5};//取下标为1到3的数字int[] copy = Arrays.copyOfRange(array,1,3);System.out.println(Arrays.toString(copy));}
}

运行结果:
在这里插入图片描述

如果下标范围过大,则能拷贝多少拷贝多少,其余位置用0补全

画图对比看一下拷贝和指向的区别

在这里插入图片描述
在这里插入图片描述

注意: 数组当中存储的是基本类型数据时,不论怎么拷贝基本都不会出现什么问题,但如果存储的是引用数据类型,拷贝时需要考虑深浅拷贝的问题,关于深浅拷贝在后续详细给大家介绍。

crtl+鼠标左键,单击copyOfRange来查看他的原码看一下他是怎么运行的
在这里插入图片描述
在这里crtl+鼠标左键,单击arraycopy,来看一下他是怎么实现的
可以看到他的参数如下图所示:
在这里插入图片描述
按照以上参数用自己代码实现如下:

public class TestDemo {public static void main(String[] args) {int[] array = {1,2,3,4,5};int[] copy = new int[array.length];System.arraycopy(array,0,copy,0,array.length);System.out.println(Arrays.toString(copy));}
}

3. 求数组中元素的平均值

给定一个整型数组, 求平均值
代码示例:

public static void main(String[] args) {int[] arr = {1,2,3,4,5,6};System.out.println(avg(arr));
}public static double avg(int[] arr) {int sum = 0;for (int x : arr) {sum += x;}return (double)sum / (double)arr.length;//需要强转成double型
}// 执行结果3.5

4. 查找数组中指定元素(顺序查找)

给定一个数组, 再给定一个元素, 找出该元素在数组中的位置.
代码示例:

public static void main(String[] args) {int[] arr = {1,2,3,10,5,6};System.out.println(find(arr, 10));
}
public static int find(int[] arr, int data) {for (int i = 0; i < arr.length; i++) {if (arr[i] == data) {return i;//找到返回下标}}return -1; // 表示没有找到
}
// 执行结果
3

5. 查找数组中指定元素(二分查找)

针对有序数,可以使用更高效的二分查找。

什么叫有序数组?
有序分为 “升序” 和 “降序”
如 1 2 3 4 ,依次递增即为升序。
如 4 3 2 1 ,依次递减即为降序。

如果数组为无序数组,可以用 Arrays.sort(array)这个方法对其进行排序
代码所示:

public class TestDemo {public static void main(String[] args) {int[] array = {1,3,2,6,4,5};Arrays.sort(array);System.out.println(Arrays.toString(array));}
}

打印结果:
在这里插入图片描述

以升序数组为例,二分查找的思路是先取中间位置的元素,然后使用待查找元素与数组中间元素进行比较:

  • 如果相等,即找到了返回该元素在数组中的下标
  • 如果小于,以类似方式到数组左半侧查找
  • 如果大于,以类似方式到数组右半侧查找

画图理解
当我们想找的是4时
在这里插入图片描述

代码示例:

public static void main(String[] args) {int[] arr = {1,2,3,4,5,6};System.out.println(binarySearch(arr, 6));
}
public static int binarySearch(int[] arr, int toFind) {int left = 0;int right = arr.length - 1;while (left <= right) {int mid = (left + right) / 2;if (toFind < arr[mid]) {// 去左侧区间找right = mid - 1;} else if (toFind > arr[mid]) {// 去右侧区间找
l      eft = mid + 1;} else {// 相等, 说明找到了return mid;}}// 循环结束, 说明没找到return -1;
}
// 执行结果
5

可以看到,针对一个长度为 10000 个元素的数组查找,二分查找只需要循环 14 次就能完成查找。随着数组元素个数越多,二分的优势就越大。

我们也可以直接调用Java中的binarySearch方法来直接找下标
代码演示:

public class TestDemo {public static void main(String[] args) {int[] array = {1,3,2,6,4,5};Arrays.sort(array);System.out.println(Arrays.binarySearch(array,5));}
}

运行结果:
在这里插入图片描述
扩展:Java中的Attays方法
在这里插入图片描述
例如:比较两个数组两个对应位置数字的大小是否相等用Arrays.equals()的方法
代码演示:

 public static void main(String[] args) {int[] array1 = {1,2,3,4,5};int[] array2 = {1,2,3,4,5};boolean flg = Arrays.equals(array1,array2);System.out.println(flg);}

结果为
在这里插入图片描述
填充一个数组时用Arrays.fill()的方法
代码演示:

public static void main(String[] args) {int[] array3 = new int[10];Arrays.fill(array3,-1);System.out.println(Arrays.toString(array3));}

打印结果为:
在这里插入图片描述
也可选择填充位置 Arrays.fill(array3,1,4,-1);,把括号里边改成1~4下标的数字,填充为-1

6. 数组排序(冒泡排序)

给定一个数组, 让数组升序 (降序) 排序。
假设排升序:

  1. 将数组中相邻元素从前往后依次进行比较,如果前一个元素比后一个元素大,则交换,一趟下来后最大元素就在数组的末尾
  2. 依次从上述过程执行,直到数组中所有的元素都排列好

我们来看一下4,8,9,3,6的排序图
在这里插入图片描述

代码示例:

public class TestDemo {public static void bubbleSort(int[] array) {//i代表的是趟数!!for (int i = 0; i < array.length-1; i++) {//j代表每一趟比较的次数boolean flg = false;for (int j = 0; j < array.length-1-i; j++) {if(array[j] > array[j+1]) {int tmp = array[j];array[j] = array[j+1];array[j+1] = tmp;flg = true;}}if(flg == false) {break;//说明有序了!!!}}}public static void main(String[] args) {int[] arr = {9, 5, 2, 7};bubbleSort(arr);System.out.println(Arrays.toString(arr));}
}//运行结果
[2, 5, 7, 9]

冒泡排序性能较低。Java 中内置了更高效的排序算法

public static void main(String[] args) {int[] arr = {9, 5, 2, 7};Arrays.sort(array);System.out.println(Arrays.toString(array));
}

关于 Arrays.sort 的具体实现算法, 我们在后面的排序算法课上再详细介绍. 到时候我们会介绍很多种常见排序算法.

7. 数组逆序

给定一个数组,将里面的元素逆序排列。
思路
设定两个下标,分别指向第一个元素和最后一个元素,交换两个位置的元素,然后让前一个下标自增,后一个下标自减,循环继续即可。
代码示例:

public static void main(String[] args) {int[] arr = {1, 2, 3, 4};reverse(arr);System.out.println(Arrays.toString(arr));
}
public static void reverse(int[] arr) {int left = 0;int right = arr.length - 1;while (left < right) {int tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;left++;right--;}
}

运行结果:
在这里插入图片描述

库里边没有方法可以直接数组逆序

8. 二维数组

二维数组本质上也就是一维数组,只不过每个元素又是一个一维数组。
基本语法

数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
初始化示例:

int[][] arr = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};
int[][] arr1 = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};
int[][] arr2 = new int[2][3]

通过array[行][列]的坐标来访问某一个值
图解:
在这里插入图片描述

代码示例:

int[][] arr = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};
for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {System.out.printf("%d\t", arr[i][j]);}System.out.println("");
}
// 执行结果
1 2 3 4
5 6 7 8
9 10 11 12

二维数组的用法和一维数组并没有明显差别,因此我们不再赘述。
同理,还存在 “三维数组”,“四维数组” 等更复杂的数组,只不过出现频率都很低。

我们如果想直接打印二维数组要用什么呢?
我们知道一维数组的打印用Arrays.toString(),但是用它打印二维数组打印的是数组的地址
所以我们要用Arrays.deepToString()的方法直接打印二维数组
代码演示:

int[][] arr = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};System.out.println(Arrays.deepToString(arr));

在这里插入图片描述
不规则的二维数组
代码演示:

public static void main(String[] args) {int[][] array = new int[2][];array[0] = new int[]{1,2,3};array[1] = new int[]{4,5,6,7,8,9};System.out.println(Arrays.deepToString(array));}
//运行结果
[[1, 2, 3], [4, 5, 6, 7, 8, 9]]

可以指定二维数组的长度,这时可以省略他的列
画图解释:
在这里插入图片描述

关于【Java.SE】数组的练习,七七就先分享到这里了,如果你认为这篇文章对你有帮助,请给七七点个赞吧,如果发现什么问题,欢迎评论区留言!!💕💕


http://www.ppmy.cn/news/695986.html

相关文章

管理层反目 乐视绕不开钱荒

一纸声明将易到资金困境“真相”公之于众&#xff0c;但事实却恐怕并不简单。4月17日&#xff0c;针对日前关于易到资金出现问题等诸多传闻&#xff0c;易到创始人周航称&#xff0c;易到当前确实存在着资金问题。这个问题最直接的原因是乐视对易到的资金挪用达13亿元&#xff…

针对乐视网的主页无法打开的解决办法

一直都在使用乐视网看电视等&#xff0c;但是最近突然不能访问乐视&#xff0c;开始以为是乐视的服务器有问题&#xff0c;可能是暂时访问不了&#xff0c;但是几天之后还是这样&#xff0c;因此想到是不是自身的电脑有什么问题&#xff1f; 首先换一台电脑&#xff0c;看是不…

6.0权限 乐视手机打不开权限

if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.READ_PHONE_STATE)! PackageManager.PERMISSION_GRANTED) {if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_PHONE_STATE)) {// 用户拒绝过这个权限…

FPGA中ROM初始化方法

一 读取txt数据文件进行初始化 parameter INIT_FILE "文件路径/Data.txt" &#xff08;**注意文件路径中斜杠方向**&#xff09; reg [DATA_WITDH - 1:0] ROM [DATA_DEPTH - 1:0];initial begin$readmemh(INIT_FILE, ROM, 0, DATA_DEPTH - 1); end Dat…

VScode配置Linux内核环境

1.准备工作 需要的VSCode插件&#xff1a;clangd、remote-ssh(本机阅读和开发代码不需要&#xff09;。 需要的脚本&#xff1a;kernel目录下的scripts/clang-tools/gen_compile_commands.py 。 2.步骤 2.1.在VSCode上安装remote-ssh 如果是远程阅读和开发代码的话&#x…

c++ sizeof()详解

sizeof() 实现方法&#xff1a;主要是计算与地址0的偏移量。 #define sizeof(type) ((size_t) ((type*)0 1))sizeof 是一个关键字&#xff0c;同时也是一个运算符&#xff0c;它是一个编译时运算符&#xff0c;用于判断变量或数据类型的字节大小。 sizeof 运算符可用于获取类…

C/C++ sizeof函数解析——解决sizeof求结构体大小的问题

转自&#xff1a;C/C sizeof函数解析——解决sizeof求结构体大小的问题 - WhyWin - 博客园 (cnblogs.com) C/C中不同数据类型所占用的内存大小 32位 64位 char 1 1 int 4 大多数4&#xff…

c++size

以前求字符串大小时候一直搞A:size&#xff08;s&#xff09; 这是错的 正确应该是B:s.size(); 这俩逻辑理解是不同的 A&#xff1a;size是一个函数&#xff0c;可以猜想它的函数体应该是 int size(string s) { int size0; … return size; } 这么理解也没啥问题也许这个函数还…