JavaSE基础之数组
数组
一、静态初始化
- 格式一
数据类型[] 变量名 = {元素1,元素2,元素3...};
- 格式二
数据类型[] 变量名 = new 数据类型{元素1,元素2,元素3...};
或者:
数据类型[] 变量名;
变量名 = new 数据类型{元素1,元素2,元素3...};
二、动态初始化
- 格式
数组存储的元素的数据类型[] 数组名字 = new 数组存储的元素的数据类型[长度];
或者:
数组存储的数据类型[] 数组名字;
数组名字 = new 数组存储的数据类型[长度];
元素的类型可以是任意的java的数据类型,int,String。
数据的长度一旦指定,不可更改。
2、数组元素的默认值
当确定了数组的长度,但是在没有给数组元素复制的情况下,数组的元素存在默认值。
byte、short、int、long、float、double的默认值为0,其中long为0L,float为0.0F,double为0.0;
char为0或"\u0000"(变现为空),我认为String类型变现为char类型数组,String默认为空,故char类型默认变现为空;
boolean类型为false;
引用类型为null。
三、数组内存
- 内存概述
内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。
Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。
- Java虚拟机的内存划分
- 数组在内存中的存储
- 一个数组内存
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);//[I@5f150435
}

思考:打印arr为什么是[I@5f150435,它是数组的地址吗?
答:它不是数组的地址。
问?不是说arr中存储的是数组对象的首地址吗?
答:arr中存储的是数组的首地址,但是因为数组是引用数据类型,打印arr时,会自动调用arr数组对象的toString()方法,默认该方法实现的是对象类型名@该对象的hashCode()值的十六进制值。
问?对象的hashCode值是否就是对象内存地址?
答:不一定,因为这个和不同品牌的JVM产品的具体实现有关。例如:Oracle的OpenJDK中给出了5种实现,其中有一种是直接返回对象的内存地址,但是OpenJDK默认没有选择这种方式。
四、数组使用过程中常见异常
数组越界异常 ArrayIndexOutOfBoundsException
数组空指针异常 NullPointerException
public static void main(String[] args) {
int[] arr = {1,2,3};
arr = null;
System.out.println(arr[0]);
}
public static void main(String[] args){
//声明一个String[]类型的数组,用来存储三个学生的姓名
String[] names = new String[3];
int count = names[0].length();
System.out.println("第一个学生姓名的字数:" + count);
}
五、java内存管理(堆、栈、方法区)
- java堆
堆内存用来存放由new创建的对象实例和数组。(重点)
- java栈
在栈内存中保存的是堆内存空间的访问地址,或者说栈中的变量指向堆内存中的变量(Java中的指针)(重点)。
- 方法区
方法区是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 (重点)。
具体实现向下。
六、java内存管理的具体实现
我们看以下一个简单代码实现:
public class Student {
private String name;
private int age;
public void study() {
System.out.println("I love study!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class StudentDemo {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student.getName() + ":" + student.getAge());
student.setName("John");
student.setAge(23);
System.out.println(student.getName() + ":" + student.getAge());
student.study();
Student student2 = student;
student2.setName("Jack");
student2.setAge(25);
System.out.println(student2.getName() + ":" + student2.getAge());
System.out.println(student.getName() + ":" + student.getAge());
}
}
第一、二步:
运行程序时,JVM会把Student类与StudentDemo类编译完然后加载到JVM中一个叫方法区的地方,类的成员变量与成员方法也被加载到方法区中
第三步
接着JVM会自动寻找main方法,在栈中为main方法申请一个空间,这个过程也叫入栈,然后执行Student student = new Student();
第四步
在栈中分配一块内存空间用于指向堆空间中的Student对象区的内存地址
第五、六步
接着执行student.setName("John"); student.setAge(23); 程序为student对象的成员变量赋值,JVM会根据student所指向的地址在堆内存中寻找Student类的变量,并为变量赋新的值
第七步
student对象调用study方法,JVM在栈空间中为study方法申请了一块内存空间。study方法执行完后,立即释放栈空间。
注意:方法执行完后会立即释放,main函数会在执行完所有代码后释放。
第八步
执行Student student2 = student; student2对象的引用指向了student所指向的地址。执行student2.setName("Jack"); student2.setAge(25); 由于student2与student指向了同一个地方,所以这时student对象中变量的值也被改变

第九步
main方法中所有代码执行完毕,main方法所占用的栈空间也被回收,而堆空间等待GC回收

七、数组的查找算法
1、数组的顺序查找
public static void main(String[] args) {
int[] ints = {2,5,7,3,1,0,7};
int value = 0;
boolean hasFind = false;
for(int i : ints) {
if(i == 0) {
hasFind = true;
}
}
if(hasFind) {
System.out.println("查找到");
}else {
System.out.println("没有查找到");
}
}
2、数组的二分查找
public static void main(String[] args) {
int[] ints = {2,5,8,9,34,78};
int num = 34;
boolean hasFind = false;
int start = 0;
int end = ints.length - 1;
int mid = (start + end) / 2;
while(start <= end) {
if(ints[mid] == num) {
hasFind = true;
break;
}
if(ints[mid] > num) {
end = mid;
}else if(ints[mid] < num) {
start = mid;
}
mid = (start + end) / 2;
}
if(hasFind) {
System.out.println("查找到");
}else {
System.out.println("没有查找到");
}
}
3、冒泡排序
原理:比较两个相邻的元素,将值大的元素交换至右端。
注意,每一轮比较,都会找到数组内的最大值并将其安排至数组的最后一位。
因此需要进行数组.length-1轮比较。
public statis void main(String[] args) {
int[] ints = {2,5,7,3,1,0,7};
int num = 0;
for(int i = 0; i < ints.length-1; i++) {
for(int j = 0; j < ints.length-i-1; j++){
if(ints[j] > ints[j+1]) {
num = ints[j];
ints[j] = ints[j+1];
ints[j+1] = num;
}
}
}
for(int i = 0; i < ints.length; i++) {
System.out.print(ints[i]);
}
}
4、简单选择排序


代码有一些问题
public static void main(String[] args) {
int[] ints = {2,5,7,3,1,0,7};
for(int i = 1; i < ints.length; i++) {
int min = ints[i-1];
int index = 0;
for(int j = 0; j < ints.length; j++) {
if(ints[j] < min) {
min = ints[j];
index = j;
}
}
if(index != i-1){
int num = ints[i-1];
ints[i-1] = ints[index];
ints[index] = num;
}
}
for(int i = 0; i < ints.length; i++) {
System.out.print(ints[i]);
}
}
二维数组
1、二维数组的初始化
1.静态初始化
元素的数据类型[][] 二维数组名 = new 元素的数据类型[][]{
{元素1,元素2,元素3 。。。},
{第二行的值列表},
...
{第n行的值列表}
};
元素的数据类型[][] 二维数组名;
二维数组名 = new 元素的数据类型[][]{
{元素1,元素2,元素3 。。。},
{第二行的值列表},
...
{第n行的值列表}
};
// 以下格式要求声明与静态初始化必须一起完成
元素的数据类型[][] 二维数组的名称 = {
{元素1,元素2,元素3 。。。},
{第二行的值列表},
...
{第n行的值列表}
};
2.动态初始化(规则二维表:每一行的列数是相同的)
//(1)确定行数和列数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[m][n];
m:表示这个二维数组有多少个一维数组。或者说一共二维表有几行
n:表示每一个一维数组的元素有多少个。或者说每一行共有一个单元格
// 此时创建完数组,行数、列数确定,而且元素也都有默认值
//(2)再为元素赋新值
二维数组名[行下标][列下标] = 值;
3.动态初始化(不规则:每一行的列数可能不一样)
//(1)先确定总行数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[总行数][];
// 此时只是确定了总行数,每一行里面现在是null
//(2)再确定每一行的列数,创建每一行的一维数组
二维数组名[行下标] = new 元素的数据类型[该行的总列数];
// 此时已经new完的行的元素就有默认值了,没有new的行还是null
// (3)再为元素赋值
二维数组名[行下标][列下标] = 值;
部分内容参考:原文链接:https://blog.csdn.net/weixin_41043145/article/details/95663118
JavaSE基础之数组的更多相关文章
- javaSE基础05
javaSE基础05:面向对象 一.数组 数组的内存管理 : 一块连续的空间来存储元素. Int [ ] arr = new int[ ]; 创建一个int类型的数组,arr只是一个变量,只是数组的一 ...
- javaSE基础04
javaSE基础04 一.三木运算符 <表达式1> ? <表达式2> : <表达式3> "?"运算符的含义是: 先求表达式1的值, 如果为真, ...
- javaSE基础02
javaSE基础02 一.javac命令和java命令做什么事情? javac:负责编译,当执行javac时,会启动java的编译程序,对指定扩展名的.java文件进行编译,生成了jvm可以识别的字节 ...
- javase基础复习攻略《十》
按照计划本篇为大家总结JAVA的网络编程,什么叫网络编程呢?网络编程!=网站编程,对于这一点大家一定要注意,很多小朋友都曾经这么认为.既然谈到网络编程,咱们先了解一下网络的基础知识,什么是计算机网络? ...
- javase基础复习攻略《二》
今天就开始的真正走进JAVASE的世界,本篇介绍的是:JAVASE基础语法,大家如果有C语言的基础,对于本节内容一定感觉非常轻松,编程语言之间的都是相通的,只不过C语言属于面向过程编程,而JAVA语言 ...
- java学习之路之javaSE基础1
<h2>java学习之路之javaSE基础1</h2> <div> ###01.01_计算机基础知识(计算机概述)(了解)* A:什么是计算机?计算机在生活中的应用 ...
- JavaSE基础之矩阵运算
JavaSE基础之矩阵运算 1.矩阵类:Matrix.java 包括矩阵的加.乘运算,行列式的求解,最大最小元素等 package cn.com.zfc.help; import java.text. ...
- Java 语言基础之数组应用
什么时候使用数组呢? 如果数据出现了对应关系, 而且对应关系的一方是有序的数字编号, 并作为角标使用. 这时,就必须要想到数组的使用. 也就是将这些数据存储到数组中, 根据运算的结果作为角标, 直接去 ...
- Java 语言基础之数组常见操作
对数组操作最基本的动作: 存和取 核心思想: 就是对角标的操作 数组常见操作: 1, 遍历 2, 获取最大值和最小值 3, 排序 4, 查找 5, 折半查找 // 1. 遍历 int[] arr = ...
随机推荐
- vue仿移动端输入框
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 「Java面试题/知识点精华集」20000+字的Java基础知识篇(2020最新版) !
本文已经收录进我的 79K Star 的 Java 开源项目 JavaGuide:https://github.com/Snailclimb/JavaGuide (「Java学习+面试指南」一份涵盖大 ...
- KNIME快速入门指南
一.介绍 KNIME Analytics Platform是用于创建数据科学应用程序和服务的开源软件.KNIME直观,开放,不断整合新的开发,使人们可以理解数据,设计数据科学工作流程和可重用组件. ...
- UML ——六种依赖关系.md
在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization), 关联(Association), 聚合(Aggregation), 组合(Compos ...
- api.versioning 版本控制 自动识别最高版本
Microsoft.AspNetCore.Mvc.Versioning //引入程序集 .net core 下面api的版本控制作用不需要多说,可以查阅https://www.cnblogs.com/ ...
- JUC : 并发编程工具类的使用
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.JUC是什么 1.JUC定义 JUC,即java.util.concurrent 在并发编程中使用的 ...
- Java 第十一届 蓝桥杯 省模拟赛 70044与113148的最大公约数
问题描述 70044与113148的最大公约数是多少? 答案提交 这是一道结果填空的题,你只需要算出结果后提交即可.本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分. pac ...
- Java实现 LeetCode 695 岛屿的最大面积(DFS)
695. 岛屿的最大面积 给定一个包含了一些 0 和 1 的非空二维数组 grid . 一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在水平或者竖直方向上相 ...
- Java实现 LeetCode 430 扁平化多级双向链表
430. 扁平化多级双向链表 您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例 ...
- Java实现 LeetCode 316 去除重复字母
316. 去除重复字母 给定一个仅包含小写字母的字符串,去除字符串中重复的字母,使得每个字母只出现一次.需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置). 示例 1: 输入: " ...