JAVA数组的基础入门>从零开始学java系列
JAVA数组的基础入门
什么是数组,什么情况下使用数组
- 数组是一个存储多个相同类型数据的容器
- 当需要将大量相同数据类型存储起来并且不需要怎么进行增删数据时
数组的创建方式
- 静态创建方式(当数组创建时就已经有了值)
int[] arr1 = {1,3,5,6};
int[] arr2 = new int[]{1,3,5,6,8,1};
- 动态创建方式(创建时只指定长度并分配默认值),默认值就是每个数据类型的默认值
int[] arr3 = new[10];
获取数组的数据
// 数组的每一个元素都会有一个对应的索引(下标),索引从0开始
int[] arr4 = {1,3,5,6};// 这其中索引从0开始,也就是其中的1的索引为0,3的索引为1,以此类推
// 那么要获取到其中的数字6
System.out.println(arr4[3]);
数组的内存模型
// 栈中的main函数在执行到该条语句时
/*
1、会创建一个int数组对象,放在堆内存中。(其对象的值是一片连续的区域,每一个索引位置都对应着一个内存地址)理解为对象是一个地址,其中的元素也有对应的内存地址
2、栈内存中会创建一个数据类型为 int[],并且名称为arr5的引用,然后用该引用指向堆内存中的刚刚创建的对象的内存地址
*/
int[] arr5 = {3,4,5,6};
为什么数组查询修改快,而增删慢?
查询快的原因
- 因为数组拥有索引,而每个索引所对应的数据都会有一个内存地址
- 每次使用索引查找数据时,都会经过一个算法 (第一个索引的内存地址 + 当前索引 * 数据大小)来快速定位到当前索引所指向的内存地址,所以查询很快
增删慢的原因
- 增删慢是因为数组是一片连续的区域,按理来说数组创建后长度就是固定的,所以增加与删除数组实际上都是创建一个新的数组
- 而创建了一个新的数组后还要将数组进行重新的数据编排以此来完成数据的增删操作,所以速度慢
数组的两种遍历方式以及区别
fori的遍历方式
int[] arr6 = {8,9,5,4,7,3,1};
for(int i = 0; i < arr6.length; i++) {
System.out.println("arr6[" + i + "] = " + arr6[i]);
}
数组获取极值及其索引
/*
要求,1、从键盘输入一段数组,期间中空格隔开
2、要求输出最大值以及最大值的索引位置
提示:不用键盘输入,直接定义一个数组也是可以的。
*/
try (Scanner scanner = new Scanner(System.in)) {
String[] strings = scanner.nextLine().split(" ");
// 将String[]转换为int[]
int[] arrs = Arrays.stream(strings).mapToInt(Integer::valueOf).toArray();
// 上面的两行代码如果不熟悉的话可以直接定义一个数组。例如: int[] arrs = {1,3,5,12,33,12,15,46};
// 获取数组最大值
int max = arrs[0];
int index = 0;
for (int i = 0; i < arrs.length; i++) {
if(max < arrs[i]) {
max = arrs[i];
index = i;
}
}
System.out.println("最大值为" + max + " 在数组中的位置为:" + index);
}
增强foreach的遍历方式
int[] arr6 = {8,9,5,4,7,3,1};
for(int item : arr6) {
System.out.println(item);
}
两种遍历方式区别
- fori有索引位置,foreach没有
- fori遍历出来的每个元素都指向内存地址,foreach遍历出来的每个元素都是一个临时存储局部变量
- 按照第二条所得结论,fori遍历时可以修改数组中的元素,而foreach不可以在遍历时修改数组的元素
JAVA数组的基础入门
什么是数组,什么情况下使用数组
- 数组是一个存储多个相同类型数据的容器
- 当需要将大量相同数据类型存储起来并且不需要怎么进行增删数据时
数组的创建方式
- 静态创建方式(当数组创建时就已经有了值)
int[] arr1 = {1,3,5,6};
int[] arr2 = new int[]{1,3,5,6,8,1};
- 动态创建方式(创建时只指定长度并分配默认值),默认值就是每个数据类型的默认值
int[] arr3 = new[10];
获取数组的数据
// 数组的每一个元素都会有一个对应的索引(下标),索引从0开始
int[] arr4 = {1,3,5,6};// 这其中索引从0开始,也就是其中的1的索引为0,3的索引为1,以此类推
// 那么要获取到其中的数字6
System.out.println(arr4[3]);
数组的内存模型
// 栈中的main函数在执行到该条语句时
/*
1、会创建一个int数组对象,放在堆内存中。(其对象的值是一片连续的区域,每一个索引位置都对应着一个内存地址)理解为对象是一个地址,其中的元素也有对应的内存地址
2、栈内存中会创建一个数据类型为 int[],并且名称为arr5的引用,然后用该引用指向堆内存中的刚刚创建的对象的内存地址
*/
int[] arr5 = {3,4,5,6};
为什么数组查询修改快,而增删慢?
查询快的原因
- 因为数组拥有索引,而每个索引所对应的数据都会有一个内存地址
- 每次使用索引查找数据时,都会经过一个算法 (第一个索引的内存地址 + 当前索引 * 数据大小)来快速定位到当前索引所指向的内存地址,所以查询很快
增删慢的原因
- 增删慢是因为数组是一片连续的区域,按理来说数组创建后长度就是固定的,所以增加与删除数组实际上都是创建一个新的数组
- 而创建了一个新的数组后还要将数组进行重新的数据编排以此来完成数据的增删操作,所以速度慢
数组的两种遍历方式以及区别
fori的遍历方式
int[] arr6 = {8,9,5,4,7,3,1};
for(int i = 0; i < arr6.length; i++) {
System.out.println("arr6[" + i + "] = " + arr6[i]);
}
增强foreach的遍历方式
int[] arr6 = {8,9,5,4,7,3,1};
for(int item : arr6) {
System.out.println(item);
}
两种遍历方式区别
- fori有索引位置,foreach没有
- fori遍历出来的每个元素都指向内存地址,foreach遍历出来的每个元素都是一个临时存储局部变量
- 按照第二条所得结论,fori遍历时可以修改数组中的元素,而foreach不可以在遍历时修改数组的元素
数组的小练习,获取极值及索引、数组的扩容及缩容
获取极值及其索引
/*
要求,1、从键盘输入一段数组,期间中空格隔开
2、要求输出最大值以及最大值的索引位置
提示:不用键盘输入,直接定义一个数组也是可以的。
*/
try (Scanner scanner = new Scanner(System.in)) {
String[] strings = scanner.nextLine().split(" ");
// 将String[]转换为int[]
int[] arrs = Arrays.stream(strings).mapToInt(Integer::valueOf).toArray();
// 上面的两行代码如果不熟悉的话可以直接定义一个数组。例如: int[] arrs = {1,3,5,12,33,12,15,46};
// 获取数组最大值
int max = arrs[0];
int index = 0;
for (int i = 0; i < arrs.length; i++) {
if(max < arrs[i]) {
max = arrs[i];
index = i;
}
}
System.out.println("最大值为" + max + " 在数组中的位置为:" + index);
}
在数组指定索引位置插入数据
// 方式1
public static int[] insertArrayElementByIndex(int[] arr, int index, int element) {
// 先动态创建一个数组
int[] newArr = new int[arr.length + 1];
// 遍历原数组,获取索引前的数据
for (int i = 0; i < index; i++) {
newArr[i] = arr[i];
}
// 将索引处的值赋值
newArr[index] = element;
// 遍历索引后的数据
for (int i = index; i < arr.length; i++) {
newArr[i + 1] = arr[i];
}
return newArr;
}
// 方式2
public static int[] insertArrayElementByIndex2(int[] arr, int index, int element) {
// 先动态创建一个数组
int[] newArr = new int[arr.length + 1];
// 遍历原数组,获取索引前的数据
System.arraycopy(arr, 0, newArr, 0, index);
// 将索引处的值赋值
newArr[index] = element;
// 遍历索引后的数据
System.arraycopy(arr, index, newArr, index + 1, arr.length - index);
return newArr;
}
删除数组指定位置数据
// 方式1
public static int[] deleteArrayElementByIndex(int[] arr, int index) {
// 先动态创建一个数组
int[] newArr = new int[arr.length - 1];
// 遍历原数组,获取索引前的数据
for (int i = 0; i < index; i++) {
newArr[i] = arr[i];
}
// 遍历索引后的数据,由于长度减少了,所以需要少遍历一次给新数组赋值
for (int i = index; i < arr.length - 1; i++) {
newArr[i] = arr[i + 1];
}
return newArr;
}
// 方式2
public static int[] deleteArrayElementByIndex2(int[] arr, int index) {
// 先动态创建一个数组
int[] newArr = new int[arr.length - 1];
// 遍历原数组,获取索引前的数据
System.arraycopy(arr, 0, newArr, 0 , index);
// 遍历索引后的数据,由于长度减少了,所以需要少遍历一次给新数组赋值
System.arraycopy(arr, index + 1, newArr, index , arr.length - 1 - index);
return newArr;
}
Arrays工具类的使用以及System.arraycopy()方法的使用
Arrays工具类
Integer[] arr = {3, 5, 6, 1, 2, 5, 7};
// 倒叙排序数组
Arrays.sort(arr, Collections.reverseOrder());
// 升序排序数组
Arrays.sort(arr);
// 复制数组
Integer[] copyArr = Arrays.copyOf(arr, arr.length);
// 将数组转换为一串字符串
String arrStr = Arrays.toString(copyArr);
// 输出结果为:[1, 2, 3, 5, 5, 6, 7]
System.out.println(arrStr);
// 使用二分查找法查找某个数据所在的索引位置
int index = Arrays.binarySearch(arr, 5);
System.out.println(index);
System.arraycopy()方法的使用
// System.arraycope()方法 复制整个数组
/* 参数解析
* Object src: 原始数组
* int srcPos: 从原始数组的第几个下标开始复制
* Object dest: 目标数组,也就是要复制到该数组中
* int destPos: 从目标数组的第几个下标开始复制
* int length: 一共需要复制几个元素
* 提示一点:源数组与目标数组必须为相同类型的数组
*/
int[] arr = {3,5,6,1,2,5,7};
int[] newArr = new int[arr.length];
System.arraycopy(arr, 0, newArr, 0, arr.length);
System.out.println(Arrays.toString(newArr));
综合案例练习
/*
1、键盘输入 [学生姓名 学生成绩]后按回车,可以无限的录入学生信息
2、当输入over按回车时停止键盘输入
3、输出学生的名次、姓名、成绩
*/
public class Test4 {
public static void main(String[] args) {
Student[] stuArr = new Student[0];
Scanner scanner = new Scanner(System.in);
// 输入学生信息,格式为: 学生姓名 成绩;使用标记over结束
while (true) {
String str = scanner.nextLine();
if ("over".equals(str)) {
break;
}
String[] s = str.split(" ");
Student student = new Student(s[0], Integer.parseInt(s[1]));
// 插入一个数据
stuArr = insertArrElement(stuArr, student);
}
Arrays.sort(stuArr, ((o1, o2) -> Integer.compare(o2.getScore(), o1.getScore())));
for (int i = 0; i < stuArr.length; i++) {
System.out.println("比赛名次为第" + (i + 1) + "名 姓名为:" +
stuArr[i].getName() + " 成绩为:" + stuArr[i].getScore());
}
}
private static Student[] insertArrElement(Student[] stuArr, Student student) {
// 复制前面的所有内容,用这一行可以
//Student[] newArr = Arrays.copyOf(stuArr, stuArr.length + 1);
// 用这下面两行也可以做到
Student[] newArr = new Student[stuArr.length + 1];
System.arraycopy(stuArr, 0, newArr, 0, stuArr.length);
// 将最后一位添加上
newArr[newArr.length - 1] = student;
return newArr;
}
}
class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
}
运行效果如下
JAVA数组的基础入门>从零开始学java系列的更多相关文章
- 从零开始学 Java - 我放弃了 .NET ?
这不是一篇引起战争的文章 毫无疑问,我之前是一名在微软温暖怀抱下干了近三年的 .NET 开发者,为什么要牛(sha)X一样去搞 Java 呢?因为我喜欢 iOS 阿!哈哈,开个玩笑.其实,开始学 Ja ...
- 从零开始学Java——个人笔记(持续更新中)
从零开始学Java 学习流程 第一阶段:建立编程思想 Java概述 变量 运算符 控制结构 数组.排序和查找 面向对象编程(基础) 面向对象编程(中级) 项目&学习以致用 编程之乐 第二阶段: ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)
Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)
硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)
从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)
你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...
- 从零开始学 Java - 利用 Nginx 负载均衡实现 Web 服务器更新不影响访问
还记得那些美妙的夜晚吗 你洗洗打算看一个小电影就睡了,这个时候突然想起来今天晚上是服务器更新的日子,你要在凌晨时分去把最新的代码更新到服务器,以保证明天大家一觉醒来打开网站,发现昨天的 Bug 都不见 ...
- 从零开始学 Java - log4j 项目中的详细配置
你还会用笔来写字么 我是不怎么会了,有时候老是拿起笔之后不知道这个字怎么写,这时候就会拿起手机去打出来:有时候还会写出来这个字之后越看越不像,这时候就开始怀疑自己的能力了:有时候写出来了一大堆字之后, ...
- 从零开始学 Java - Spring 支持 CORS 请求踩的坑
谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...
随机推荐
- POJ 3449 Geometric Shapes 判断多边形相交
题意不难理解,给出多个多边形,输出多边形间的相交情况(嵌套不算相交),思路也很容易想到.枚举每一个图形再枚举每一条边 恶心在输入输出,不过还好有sscanf(),不懂可以查看cplusplus网站 根 ...
- HDU 1686 Oulipo kmp裸题
kmp算法可参考 kmp算法 汇总 #include <bits/stdc++.h> using namespace std; const int maxn=1000000+5; cons ...
- Java:TreeMap中LinkedHashMap和Map中HashMap的区别
一般情况下,我们用的最多的是HashMap,在Map 中插入.删除和定位元素,HashMap 是最好的选择. 但如果您要bai按自然顺序或自定义顺序遍历键,那么TreeMap会更好.如果需要输出的顺序 ...
- Go:go程序报错Cannot run program "C:\Users\dell\AppData\Local\Temp\___go_build_hello_go.exe" (in directory "…………"):该版本的 %1 与你运行的 Windows 版本不兼容。
问题截图 在go语言编译的时候,如果只是单单编译一个文件的话,package必须是main,意味着是可以单独编译的. 解决办法 修改为 package main 就可以 再次运行就可以啦. 文章转载至 ...
- 面试:MyBatis面试总结
1.什么是Mybatis? (1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动.创建连接.创建statement ...
- mongodb主从复制(读写分离)
1.[启动主服务器]mongod --port 1111 --dbpath D:\Program Files\Mongodb\master --logpath D:\Program Files\Mon ...
- Xshell怎么连接数据库
之前一直用Navicat Premium链接数据库,其实在xshell也可以链接数据库,本文将先介绍如何用xshell链接数据库的方法. 1.打开xshell,连接上 输入指令:mysql -h 19 ...
- Linux下使用Ansible处理批量操作
Ansible介绍: ansible是一款为类unix系统开发的自由开源的配置和自动化工具.它用python写成,类似于saltstack和puppet,但是不同点是ansible不需要再节点中安装任 ...
- 第九章 身体质量指数BMI的python实现
身体质量指数BMI:对身体质量的刻画(Body Mass Index) 国际上常用的衡量人体肥胖和健康程度的重要标准,主要用于统计分析 定义: BMI=体重(kg)/身高^2(m2) 提出问题: 实例 ...
- vue3 script setup 定稿
vue script setup 已经官宣定稿.本文主要翻译了来自 0040-script-setup 的内容. 摘要 在单文件组件(SFC)中引入一个新的 <script> 类型 set ...
