声明:
- 该资料来自自己整理。
- 参考书籍
疯狂 Java讲义(第五版) 李刚©著
一、入门知识
1.1 JDK、JRE、JVM
JDK
:JAVA Development Kit(JAVA开发工具包
)
JRE
:JAVA Runtime Environment(JAVA运行环境
)
JVM
:JAVA Virtual Machine(JAVA虚拟机
)
1)JDK
JDK (Java Development Kit)
:是Java程序开发工具包,包含 JRE 和开发人员使用的工具。
我们想要运行一个已有的Java程序,那么只需安装 JRE 即可。
我们想要开发一个全新的Java程序,那么必须安装 JDK。
2)JRE
JRE (Java Runtime Environment)
:是Java程序的运行时环境,包含 JVM 和运行时所需要的核心类库 。
3)JVM
JVM (Java Virtual Machine )
:Java虚拟机,简称JVM,是运行所有Java程序的假想计算机,是Java程序的运行环境,是Java最具吸引力的特性之一。我们编写的Java代码,都运行在 JVM 之上。
4)JDK、JRE、JVM 三者的关系
JDK 包含 JRE和Java的开发工具;JRE 包含JVM和Java的核心类库。
JDK = JRE + Java开发工具(javac.exe、java.exe、javadoc.exe 等)
JRE = JVM + Java核心类库
1.2 跨平台
我们用Java编写的软件可以运行在任何的操作系统上,这个特性称为Java语言的跨平台特性。
该特性是由JVM实现的,我们编写的程序运行在JVM上,而JVM运行在操作系统上。Java的虚拟机本身不具备跨平台功能的,每个操作系统下都有不同版本的虚拟机,Java通过虚拟机JVM实现的跨平台。一处编写,处处运行(Write once ,Run Anywhere)
注意:三者的关系:JDK > JRE > JVM
1.3 开发步骤
编写、编译、运行
Java 编译工具:javac.exe
它将 xxx.java 文件编译成 xxx.class 文件;
Java 运行工具:java.exe
Java程序启动Java虚拟机,Java虚拟机执行编译器编译到类文件中的字节码。
1)编译源代码
1、编译:是指将我们编写的Java源文件翻译成JVM认识的class文件,在这个过程中, javac 编译器会检查我们
所写的程序是否有错误,有错误就会提示出来,如果没有错误就会编译成功,生成字节码.class文件
2、运行:java 解释器 是指将class文件交给JVM去运行,此时JVM就会去执行我们编写的程序了
// 步骤
1)在DOS命令行中,进入Java源文件的目录
cd /目录名
2)使用 javac 命令编译
javac 源文件.java
3)编译成功可以看到新生成的字节码文件
HelloWorld.class
/**
* 编译成功后,命令行没有任何提示。打开所在目录,发现产生了一个新的文件 HelloWorld.class ,
* 该文件就是编译后的文件,是Java的可运行文件,称为字节码文件,有了字节码文件,就可以运行程序了。
*/
//单行注释
/* 多行注释 */
/** 文档注释 */
2)运行 Java 程序
// 进入字节码文件所在的目录
cd /目录名
// 执行命令
java 类名
1.4 关键字
关键字
:被Java语言赋予了特殊含义的单词称为关键字
保留字
:暂时还没有赋予特殊含义对的单词,goto、const等
1.5 标识符
标识符:是指在程序中,我们自己定义内容。比如类的名字、方法的名字和变量的名字等等,都是标识符。
HelloWorld案例中,出现的标识符有类名:HelloWorld
标识符的命名规则
1)标识符由大小写字母、阿拉伯数字、下划线“_”、美元符号“$”组成,不能以数字开头
2)不能把java关键字和保留字作为标识符
3)标识符对大小写敏感(大小写意义不一样)
4)标识符没有长度限制(不能瞎定义) 见名知义
命名规范
1)类名、接口名:单词首字母大写(如果多个单词组合,每个单词首字母大写,其余小写)
Demo 、HelloWorld
2)方法名、变量名:单词全部小写(如果多个单词组合,从第二个单词开始,首字母全部大写,其余小写)
add、findAllUser name、myName
3)常量名:全部大写(如果多个单词组合,每个单词用下划线_隔开)
MAX TOTAL_COUNT
二、数据类型
Java 区分大小写
2.1 分类介绍
数据类型分为两大类:
基本数据类型
:byte、short、int、long、float、double、char、boolean引用数据类型
:数组、字符串、类、接口
基本数据类型又分为四大类:
整数、浮点型、字符、布尔 (⚠️null是任何引用类型的默认值)
注意:
- long型常量**常用后缀
L
或l
**来表示,例如108L(十进制)、07123L(八进制)、0x3ABCL(十六进制)。- float型常量后面必须要有后缀
f
或F
,例如 2e40f (2乘10的40次方)。- java没有任何无符号(unsigned)形式的 int、long、short、byte类型。
- 有些 Unicode 字符可以用一个 char 值描述,另外一些 Unicode 字符则需要两个 char 值。
单位转换:1byte=8bit 1024byte=1KB 1024KB=1MB 1024MB=1GB 1024GB=1TB 1024TB=1PB 1024PB=1EB 1024EB=1ZB
2.2 数据类型默认值
public class Demo01 {
byte b;
short s;
char c;
int i;
long l;
float f;
double db;
boolean bl;
public void info(){
System.out.println("byte=" + b);
System.out.println("short=" + s);
System.out.println("char=" + c);
System.out.println("int=" + i);
System.out.println("long=" + l);
System.out.println("float=" + f);
System.out.println("double=" + db);
System.out.println("boolean=" + bl);
}
public static void main(String[] args) {
Demo01 d1 = new Demo01();
System.out.println("基本类型的默认值:");
d1.info();
}
}
注意:
- 直接给出一个整数值默认类型就是 int 类型;
- Java 语言的浮点类型默认是 double 类型;
2.3 数据类型转换
问:什么是数据类型转换?
答:Java程序中要求参与的计算的数据,必须要保证数据类型的一致性,如果数据类型不一致将发生类型的转换。
2.3.1 自动转换
小范围 --> 大范围 将取值范围小的类型自动提升为取值范围大的类型。
public class PrimitiveAndString{
public static void main(String[] args){
System.out.println(3+4+"hello");//输出:7hello //int->String
System.out.println("hello"+3+4);//输出:hello34
}
}
// 一个 int 类型变量和一个 byte 类型变量进行加法运算, 结果会是什么数据类型
public static void main(String[] args) {
int i = 1;
byte b = 2;
// byte x = b + i; // 报错
//int类型和byte类型运算,结果是int类型
int j = b + i;
System.out.println(j);
}
// 运算结果,变量的类型将是 int 类型,这就是出现了数据类型的自动类型转换现象
⚠️自动转换:将 取值范围小的类型 自动提升为 取值范围大的类型
//同理:当一个 int 类型变量和一个 double 变量运算时, int 类型将会自动提升为 double 类型进行运算
public static void main(String[] args) {
int i = 1;
double d = 2.5;
//int类型和double类型运算,结果是double类型
//int类型会提升为double类型
double e = d+i;
System.out.println(e);
}
⚠️转换规则:
范围小的类型向范围大的类型提升, byte、short、char 运算时直接提升为 int
byte、short、char‐‐>int‐‐>long‐‐>float‐‐>double
2.3.2 强制转换
语法格式:
(targetType)value
例如:
double dValue = 3.98;
int iValue = (int)dValue;
注意:
把一个浮点数强制类型转换为整数时,Java将直接截断浮点数的小数部分。
// 将 1.5 赋值到 int 类型变量会发生什么?产生编译失败,肯定无法赋值。
int i = 1.5; // 错误
/**
* double 类型内存8个字节, int 类型内存4个字节。 1.5是 double 类型内存8个字节,取值范围大于 int 。
* 可以理解为 double 是8升的水壶, int 是4升的水壶,不能把大水壶中的水直接放进小水壶去。
* 想要赋值成功,只有通过强制类型转换,将 double 类型强制转换成 int 类型才能赋值
*/
//强制类型转换:将 取值范围大的类型 强制转换成 取值范围小的类型
转换格式:数据类型 变量名 = (数据类型)被转数据
⚠️区别:自动转换是Java自动执行的,而强制转换需要我们自己手动执行
⚠️浮点转成整数,直接取消小数点,可能造成数据损失精度。
⚠️int 强制转成 short 砍掉2个字节,可能造成数据丢失
2.4 ASCII码表
⚠️在计算机的内部都是二进制的0、1数据,如何让计算机可以直接识别人类文字的问题呢?就产生出了编码表的概念
⚠️编码表 :就是将人类的文字和一个十进制数进行对应起来组成一张表格
public static void main(String[] args) {
//字符类型变量
char c = 'a';
int i = 1;
//字符类型和int类型计算
System.out.println(c+i);//输出结果是98
}
//将所有的英文字母,数字,符号都和十进制进行了对应,因此产生了世界上第一张编码表ASCII(American Standard Code for Information Interchange 美国标准信息交换码)
三、运算符
3.1 算术运算符
+ 加法、字符串拼接(数字就加法,字符串就是拼接)
- 减法
* 乘法
/ 除法(两个数相除取商)
% 取模(取余:两个数相除取余数)
++ 自增(基于自身加1)
-- 自减(基于自身减1)
3.2 赋值运算符
= 赋值符号(将符号右边的值,赋给左边的变量)
+= 加等于 a += ; a = a +
-= 减等于
*= 乘等于
/= 除等于
%= 模等于
+=思考题
1)下面的程序有问题吗?(重点)
public static void main(String[] args){
short s = 1;
s += 1;
System.out.println(s);
}
⚠️分析: s += 1 逻辑上看作是 s = s + 1 计算结果被提升为int类型,再向short类型赋值时发生错误,因为不能将取值范围大的类型赋值到取值范围小的类型。但是, s = s + 1 进行两次运算 , += 是一个运算符,只运算一次,并带有强制转换的特点!!!,也就是说 s += 1 就是 s = (short)(s + 1) !!!,因此程序没有问题编译通过,运行结果是2.
2)下面的程序有问题吗?
public static void main(String[] args){
byte b1=1;
byte b2=2;
byte b3=1 + 2;
byte b4=b1 + b2;
System.out.println(b3);
System.out.println(b4);
}
⚠️分析: b3 = 1 + 2 , 1 和 2 是常量,为固定不变的数据,在编译的时候(编译器javac),已经确定了 1+2 的结果并没有超过byte类型的取值范围,可以赋值给变量 b3 ,因此 b3=1 + 2 是正确的。
反之, b4 = b2 + b3 , b2 和 b3 是变量,变量的值是可能变化的,在编译的时候,编译器javac不确定b2+b3的结果是什么,因此会将结果以int类型进行处理,所以int类型不能赋值给byte类型,因此编译失败
3.3 比较运算符
⚠️比较运算符,是两个数据之间进行比较的运算,运算结果都是布尔值 true 或者 false
== 比较符号两边数据是否相等,相等结果是true
< 比较符号左边的数据是否小于右边的数据,如果小于结果是true
> 比较符号左边的数据是否大于右边的数据,如果大于结果是true
<= 比较符号左边的数据是否小于或者等于右边的数据,如果小于结果是true
>= 比较符号左边的数据是否大于或者等于右边的数据,如果小于结果是true
!= 不等于符号 ,如果符号两边的数据不相等,结果是true
boolean is = 1 != 2;
3.4 逻辑运算符
⚠️逻辑运算符,是用来连接两个布尔类型结果的运算符,运算结果都是布尔值 true 或者 false
&& 短路与
1. 两边都是true,结果是true
2. 一边是false,结果是false
短路特点:符号左边是false,右边不再运算(重点)
|| 短路或
1. 两边都是false,结果是false
2. 一边是true,结果是true
短路特点: 符号左边是true,右边不再运算(重点)
! 取反
1. !true 结果是false
2. !false 结果是true
3.5 三元运算符(三目)
三元运算符格式:
数据类型 变量名 = 布尔类型表达式 ?结果1:结果2;
三元运算符计算方式:
布尔类型表达式结果是true,三元运算符整体结果为结果1,赋值给变量
布尔类型表达式结果是false,三元运算符整体结果为结果2,赋值给变量
public static void main(String[] args) {
int i = (1==2 ? 100 : 200);
System.out.println(i);//200
int j = (3<=4 ? 500 : 600);
System.out.println(j);//500
}
3.6 拓展
3.6.1 == 与 equals
==
1.如果两个变量是基本类型的变量,且都是数值类型,则只要两个变量的值相等,就返回true;
2.如果两个变量是引用类型变量,只有它们指向同一个对象时,==判断才返回true(不管值是否相等);
3.==不可用于比较类型上没有父子关系的两个变量,否则编译错误。
equals
1.比较对象的地址(如果两个变量都指向一个对象则返回true);
2.比较字符串中所包含的内容是否相同(只要两个字符串所包含的字符序列相同,则equals()方法返回true);
public class String01 {
public static void main(String[] args) {
String s1 = "hello"; //String直接创建
String s2 = "hello"; //String直接创建
String s3 = s1; //相同引用
String s4 = new String("hello"); //String对象创建
String s5 = new String("hello"); //String对象创建
System.out.println(s1 == s3);//true 值相同,地址相同
System.out.println(s1 == s4);//false 值相同,地址不同
System.out.println(s1.equals(s4));//true 值相同,地址不同
System.out.println(s3.equals(s4));//true 值相同,地址不同
System.out.println("s4是否等于s5:"+s4.equals(s5));//值(侧重)相同,但地址不同 true
System.out.println("s4是否等于s5:"+(s4 == s5));//值相同,但地址(侧重)不同 false
}
}
3.6.2 Object.equals()
3.6.3 isEmpty、null、“” 的区别
isEmpty()
方法用于判断字符串是否为空。
语法: public boolean isEmpty()
- 如果字符串为空返回 true,否则返回 false;
- 字符串通过 length() 方法计算字符串长度,如果返回0,及为空字符串。
【案例】
public class IsEmptyNullTest {
public static void main(String[] args) {
//分配内存空间,值为空
String a = new String();
//分配内存空间,值为空字符串
String b = "";
String d = " ";// 多个空格,length() 不为 0
//未分配内存空间
String c = null;
System.out.println("a的长度"+a.length());//a的长度0
System.out.println("b的长度"+b.length());//b的长度0
System.out.println("c的长度"+d.length());//c的长度3
//System.out.println("c的长度"+c.length());//NullPointerException
System.out.println("a是否为空"+a.isEmpty());//a是否为空true
System.out.println("b是否为空"+b.isEmpty());//b是否为空true
//System.out.println("c是否为空"+c.isEmpty());//NullPointerException
}
}
四、流程控制
Java程序的执行,一般分为三种执行方式:顺序执行、选择执行和循环执行。流程控制语句包含3种结构:
顺序结构
:程序从上到下逐行地执行,中间没有任何判断和跳转。选择结构
:又叫分支结构,它是根据条件,选择性地执行某段代码。循环结构
:根据循环条件,重复性的执行某段代码。
4.1 选择结构
4.1.1 if 选择
if(条件表达式) {
条件为true时执行的代码;
}
/**
* 如果条件为真,则执行if中的语句,然后在执行if条件之后的语句;
* 反之则不执行if中的语句,直接执行if之外的语句。
*/
4.1.2 if…else 双选结构
if(条件表达式) {
条件为true时执行的代码;
} else {
条件为false时执行的代码;
}
/**
* 条件为真,执行if中的语句,然后再执行if...else之外的语句;
* 反之执行else中的语句,然后在执行if...else之后的语句。
*/
4.1.3 if…else 多选结构
if (条件表达式1) {
条件1为true时执行的代码;
}
else if(条件表达式2) {
条件2为true时执行的代码;
}
……
else {
条件1和条件2都不为true执行的代码。。
}
/**
* 条件1为真,则执行if中的语句;
* 如果条件2为真,则执行else if中的语句;...;
* 如果条件都不满足再执行else中的语句;
* 最后再执行if...else if...else之后的语句。
*/
小结:
- 如果if选择结构只需执行一条语句时,那么可以省略{};如果需要执行多条语句,那么就是不能省略{}。为了提高代码的易读性,建议不要省略{}。
- {}中的代码语句也称为代码块,在代码块定义的常量或变量的作用域仅限于代码块中,在代码块之外不能被使用。
- 能用if多选择结构就不要用if单选择结构,因为if多选择结构的效率要高于if单选择结构。
- 在if选择结构中还可以嵌套别的选择结构或循环结构。
4.1.4 switch 多选结构
// switch语句中,表达式的数据类型,可以是byte,short,int,char,enum(枚举),JDK7后可以接收字符串
switch(表达式) {
case 常量值1:
语句体1;
break;
case 常量值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
/**
* 执行流程:
* 1)首先计算出表达式的值
* 2)其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。
* 3)最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉
*/
注意:
- 在switch语句中,如果case的后面不写break,将出现穿透现象,也就是不会在判断下一个case的值,直接向后运行,直到遇到break,或者整体switch结束。
case 穿透
4.2 循环结构
4.2.1 for 循环
for(初始化表达式; 循环条件表达式; 循环后的操作表达式) {
执行语句;
}
/**
* 执行顺序:
* 1)先执行初始化语句
* 2)判断条件语句是否成立:不成立(false)则结束循环成立(true)则执行循环体语句
* 3)循环体每执行完一次,控制条件语句执行,然后再进行上面第2步的操作
* 4)直到判断条件语句不成立时,结束循环(跳出for循环),继续往下执行
*/
4.2.2 while 循环
while(循环条件){
循环体; //必须含有终止循环的条件,防止造成死循环
}
一般不知循环次数使用while循环;
/**
* 执行顺序:
* 1)判断条件语句是否成立:
* 2)成立(true)则继续执行循环体,执行控制条件语句,然后返回执行判断条件语句...(循环);
* 3)不成立(false)则直接结束循环(跳出while结构),继续往下执行。
*/
4.2.3 do…while 循环
do{
循环体; //必须含有终止循环的条件,防止造成死循环
}while(条件判断语句);
注意:do...while循环的特点:无条件执行一次循环体,即使我们将循环条件直接写成false,也依然会循环一次。
/**
* 执行顺序:
* 1)执行循环体
* 2)执行判断条件语句
* 3)成立(true)又从第1步开始循环
* 4)不成立(false),直接结束循环(跳出do...while循环结构)
*/
4.3 总结
4.3.1 break 和 continue 区别
break语句
在任何循环语句的主体部分,均可用break控制循环的流程。break 用于强行退出循环,不执行循环中剩余的语句。
适用于switch语句和循环语句中。当break作用于for循环上, “循环后的操作表达式”也不会执行。
注意:break之后不允许书写别的代码语句前,因为break会跳出当前循环或switch,那么break之后的代码永远不会执行。
continue语句
continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。只适用于循环语句中。
4.3.2 for 和 while 区别
for循环能做的事情while循环都可以实现,使用循环的时候for和while都可以选择。
建议以下条件使用while循环:
- 循环结束后循环变量还需要参与运算,那么建议使用while循环。
- 不确定循环次数的时候,建议使用while循环。
补充:最简单无限循环格式:while(true)
, for(;;)
,无限循环存在的原因是并不知道循环多少次,需要根据某些条件,来控制循环。
五、数组
Java中数组是相同类型数据的有序集合。
5.1 一维数组
5.1.1 定义和初始化
数组是一种引用类型的变量;
数组:就是存储固定长度数据的容器,保证多个数据的数据类型要一致。
数组声明的两种方式
01)int arr[];
02)int[] arr;
//案例
public class ArrayTest01 {
public static void main(String[] args){
//数组声明和初始化01
int arr1[] = new int[3];
//数组声明和初始化02
int[] arr2 = new int[]{1,2,3,4};
//数组声明和初始化03(推荐)
int[] arr3 = {1,2,3,4};
//输出数组arr的内存地址
System.out.println(arr1);//[I@5fd0d5ae
System.out.println(arr2);//[I@2d98a335
System.out.println(arr3);//[I@16b98e56
}
}
5.1.2 数组的访问(重点)
通过索引访问数组中的元素:
数组名[索引]
,获取出数组中的元素数组名[索引] = 数值
,为数组中的元素赋值
索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引 (index),可以通过数组的索引访问到数组中的元素。
public class Array01 {
public static void main(String[] args) {
//定义存储int类型数组,赋值元素1,2,3,4,5
int[] arr = {1,2,3,4,5};
//为0索引元素赋值为6
arr[0] = 6;
//获取数组0索引上的元素
int i = arr[0];
System.out.println(i);
//直接输出数组0索引元素
System.out.println(arr[0]);
}
}
5.2 二维数组
5.2.1 定义和初始化
栈内存:保存的是执行方法、运行方法(例如主方法)。
堆内存:保存的是具体的对象、数组等。
代码中带 new的就会在堆内存中开辟空间。
方法区:加载某一个类的.class字节码文件。
5.2.2 数组的访问
两种初始化形式
格式1: 动态初始化
数据类型 数组名[ ][ ] = new 数据类型[m][n]
数据类型[ ][ ] 数组名 = new 数据类型[m][n]
数据类型[ ] 数组名[ ] = new 数据类型[m][n]
//举例:
int[ ][ ] arr=new int [3][2]; //可以理解为定义了一个“3行2例”的数组
int arr[][] = new int[3][2];
// 遍历arr数组
for (int i = 0; i < arr.length; i++){
for (int x = 0; x < arr[i].length; x++){
System.out.print(arr[i][x] + "\t");
}
System.out.println();
}
格式2: 静态初始化
数据类型[ ][ ] 数组名 = {{元素1,元素2....},{元素1,元素2....},{元素1,元素2....}.....};
//举例:
int[ ][ ] arr={{1,2,3},{4,5,6},{7,8,9,10,11}, ...};
备注:静态初始化可用于不规则二维数组的初始化。
5.3 数组原理内存图
5.3.1 Java 虚拟机内存划分
为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
JVM内存划分:
- 寄存器:给CPU使用,和我们开发无关。
- 本地方法栈:JVM在使用操作系统功能的时候使用,和我们开发无关。
方法区
:存储可以运行的class文件。堆内存
:存储对象或者数组,new来创建的,都存储在堆内存。方法栈
:方法运行时使用的内存,比如main方法运行,进入方法栈中执行。
5.3.2 数组在内存中的存储
1)一个数组内存图
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);//[I@5f150435
}
1)以上方法执行,输出的结果是[I@5f150435,这个是什么呢?是数组在内存中的地址。
2)new出来的内容,都是在堆内存中存储的,而方法中的变量arr保存的是数组的地址
3)输出arr[0],就会输出arr保存的内存地址中数组中0索引上的元素
2)两个数组内存图
public static void main(String[] args) {
int[] arr = new int[3];
int[] arr2 = new int[2];
System.out.println(arr);//[I@2d98a335
System.out.println(arr2);//[I@16b98e56
}
3)两个变量指向一个数组
public class ArrayTest02 {
public static void main(String[] args){
//定义一个数组,存储3个元素
int[] arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
System.out.println(arr[0]);//1
System.out.println(arr[1]);//2
System.out.println(arr[2]);//3
//定义数组变量arr2,将arr的地址值赋给arr2
int[] arr2 = arr;
arr2[1] = 9;
System.out.println(arr[1]);//9
}
}
4)二维数组内存图
//静态初始化初始化二维数组
String[][] str1 = new String[][]{new String[3],new String[]{"hello"}};
//简化的静态初始化二维数组方法
String[][] str2 = {new String[3],new String[]{"hello"}};
5.4 数组的常见操作
5.4.1 数组的遍历(重点)
// 数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基础
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
}
// 优化:以上代码是可以将数组中每个元素全部遍历出来,但是如果数组元素非常多,这种写法肯定不行,因此我们需要改造成循环的写法。数组的索引是 0 到 lenght-1 ,可以作为循环的条件出现
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
5.4.2 数组获取最大值元素
// 最大值获取:从数组的所有元素中找出最大值
// 实现思路:
1)定义变量,保存数组0索引上的元素
2)遍历数组,获取出数组中的每个元素
3)将遍历到的元素和保存数组0索引上值的变量进行比较
4)如果数组元素的值大于了变量的值,变量记录住新的值
5)数组循环遍历结束,变量保存的就是数组中的最大值
// 示例:
public static void main(String[] args) {
int[] arr = { 5, 15, 2000, 10000, 100, 4000 };
//定义变量,保存数组中0索引的元素
int max = arr[0];
//遍历数组,取出每个元素
for (int i = 0; i < arr.length; i++) {
//遍历到的元素和变量max比较
//如果数组元素大于max
if (arr[i] > max) {
//max记录住大值
max = arr[i];
}
}
System.out.println("数组最大值是: " + max);
}
5.4.3 数组反转
// 数组的反转: 数组中的元素颠倒顺序,例如原始数组为1,2,3,4,5,反转后的数组为5,4,3,2,1
// 实现思想:数组最远端的元素互换位置。实现反转,就需要将数组最远端元素位置交换
1)定义两个变量,保存数组的最小索引和最大索引
2)两个索引上的元素交换位置
3)最小索引++,最大索引--,再次交换位置
4)最小索引超过了最大索引,数组反转操作结束
// 示例:
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
/*
循环中定义变量min=0最小索引
max=arr.length‐1最大索引
min++,max‐‐
*/
for (int min = 0, max = arr.length ‐ 1; min <= max; min++, max‐‐) {
//利用第三方变量完成数组中的元素交换
int temp = arr[min];
arr[min] = arr[max];
arr[max] = temp;
}
// 遍历输出反转后的数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
5.5 数组作为参数或返回值(重点)
⚠️注意:
- 1)数组是引用数据类型,引用数据类型作为方法参数或返回值,传递的都是内存地址。
- 2)方法的参数为基本类型时,传递的是数据值(值的副本);方法的参数为引用类型时,传递的是地址值。
六、计算机基础知识
6.1 单位
计算机存储单位
基本储存单元
位(bit):二进制数中的一个数位,可以是0或者1,是计算机中数据的最小单位。
字节(Byte,B):计算机中数据的基本单位,每8位组成一个字节。各种信息在计算机中存储、处理至少需要一个字节。例如,一个ASCII码用一个字节表示,一个汉字用两个字节表示。
字(Word):两个字节称为一个字。汉字的存储单位都是一个字
扩展的存储单位
在计算机各种存储介质(例如内存、硬盘、光盘等)的存储容量表示中,用户所接触到的存储单位不是位、字节和字,而是KB、MB、GB等,但这不是新的存储单位,而是基于字节换算的
单位:
1 位(bit): 计算机中最小的存储单位,只能存储0或者1。单位:b
1 字节(byte):8位(bit)。 就是byte,单位:B
1 KB: 1024 个字节(1024B,1024 * 8 位)
1 MB: 1024 KB
1 GB: 1024 MB
1 TB: 1024 GB
1 PB: 1024 TB
1 EB: 1024 PB
字符:
字符是指计算机中使用的字母、数字、字和符号,包括:1、2、3、A、B、C、~!·#¥%……—*()——+等等。
很多人对字符和字节经常混淆,其实两者压根不是一个概念,要强加点关系,就是计算机字符和计算机存储单位的关系, 即:一个字符占多少字节。
不同编码对字符的存储的大小也不同:
ASCII:一个英文字母一个字节(byte),一个汉字两个字节(byte)
GB 2312 或 GBK :一个英文字母一个字节(byte),一个汉字两个字节(byte)
UTF-8:一个英文字母字符存储需要1个字节(byte),一个汉字字符3到4个字节(byte)。
UTF-16:一个英文字母字符或一个汉字字符存储都需要2个字节(Unicode扩展区的一些汉字存储需要4个字节)
UTF-32:任何字符都是4个字节
案例
由于字节与位之间的关系是八倍,因此将1024Kb除以8就得到128KB。由此可见,实现上网络传输带宽中的1M只等于电脑中的128KB。这样加上信号的衰减,一般只能保持在100KB左右。相同的道理,我们的网卡一般都是100M的,但是为什么传输速度达不到这么高呢?因为100Mb,将其除以8得到12.5MB,这就是我们网卡能够达到的最高速度了。
6.2 二进制
二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。
二进制数(binaries)是逢2进位的进位制,0、1是基本算符 [2] ;计算机运算基础采用二进制。电脑的基础是二进制。。电子计算机出现以后,使用电子管来表示十种状态过于复杂,所以所有的电子计算机中只有两种基本的状态,开和关。也就是说,电子管的两种状态决定了以电子管为基础的电子计算机采用二进制来表示数字和数据。