1 Java简介
1.1 Java简介
Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling和同事们共同研发,并在 1995 年正式推出。后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Oracle 公司的产品。
Java分为三个体系:
JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版)
JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版)
JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。
2005 年 6 月,JavaOne 大会召开,SUN 公司公开 Java SE 6。此时,Java 的各种版本已经更名,以取消其中的数字 "2":J2EE 更名为 Java EE,J2SE 更名为Java SE,J2ME 更名为 Java ME。
1.2 Java主要特性
Java 语言是面向对象的:
Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。
Java 语言是健壮的:
Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。
Java 语言是跨平台性的:
一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台
Java 语言是解释型的:
Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统中运行。在运行时,Java 平台中的 Java 解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。
解释性语言:JavaScript, PHP, Java等
编译性语言:C, C++等
解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行,编译性语言,编译后的代码,可以直接被机器执行
1.3 Java运行机制及运行过程
Java核心机制——Java虚拟机(JVM Java Virtual Machine)
JVM是一个虚拟的计算机,具有指令集并使用不用的存储区域。负责执行指令,管理数据、内存、寄存器,包含在JDK中
对于不同的平台,有不同的虚拟机
Java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”。
JDK(Java Development Kit, Java开发工具包)
JDK = JRE + Java的开发工具(Java、Javac、Javadoc、Javap等)
JDK是提供给Java开发人员使用的,其中包含了Java开发工具,也包括了JRE,所以安装了JDK,就不用单独安装JRE了
JRE(Java Runtime Environment,Java运行环境)
JRE = JVM + Java的核心类(库)
包括Java虚拟机和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需安装JRE即可
1.4 Java的安装
首先我们需要下载 java 开发工具包 JDK,下载地址:https://www.oracle.com/java/technologies/downloads/,在下载页面中根据自己的系统选择对应的版本(一般Java8 或者 Java11)
下载后 JDK 的安装根据提示进行,还有安装 JDK 的时候也会安装 JRE,一并安装就可以了。
1.5 环境变量的配置
安装完成后,右击"我的电脑",点击"属性",选择"高级系统设置";在 "系统变量" 中设置 3 项属性,JAVA_HOME、PATH、CLASSPATH(大小写无所谓),若已存在则点击"编辑",不存在则点击"新建"。
变量名:JAVA_HOME
变量值:C:\Program Files (x86)\Java\jdk1.8.0_91 // 要根据自己的实际路径配置
变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; //记得前面有个"."
变量名:Path
变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
1.6 JAVA开发工具
Notepad++:http://notepad-plus-plus.org/
Netbeans:http://www.netbeans.org/index.html
1.7 Java快速入门
1.7.1 第一个Java程序
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
public class HelloWorld
表示HelloWorld
是一个类,是一个公有(public)的类HelloWorld{ }
表示一个类的开始和结束public static void main(String[] args)
表示一个主方法,即我们程序的入口main() {}
表示方法的开始和结束System.out.println("Hello World");
表示输出"Hello World"
到屏幕;
表示语句结束
1.7.2 运行Java程序
$ javac HelloWorld.java # 编译
$ java HelloWorld # 执行
Hello World
javac
后面跟着的是java文件的文件名,例如HelloWorld.java
。 该命令用于将 java 源文件编译为 class 字节码文件运行
javac
命令后,如果成功编译没有错误的话,会出现一个HelloWorld.class
的文件。java
后面跟着的是java文件中的类名,例如HelloWorld
就是类名,如:java HelloWorld
。
1.8 注意事项
Java源文件以
.java
为扩展名,源文件的基本组成部分是类(class)Java应用程序的执行入口是
main()
方法。它有固定的书写格式public static void main(String[] args) {...}
Java语言严格区分大小写
Java方法由一条条语句构成,每个语句以
;
结束大括号都是成对出现的,缺一不可
一个源文件最多只能由一个
public
类。其他类的个数不限,编译后,每一个类,都对应一个.class
文件。也可以将main
方法写在非public
类中,然后指定运行非public
类,这样入口方法就是非public
的main
方法如果源文件包含一个
public
类,则文件名必须按该类名命名
1.9 Java 包
包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。
在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。
下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类
import java.io.*;
1.10 转义字符的使用
1.11 注释
1.11.1 单行注释和多行注释
用于注解说明解释程序的文字就是注释,注释提高了代码的阅读性(可读性);注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码去体现
//单行注释
/*
多行注释
多行注释
*/
被注释的文字,不会被JVM(java 虚拟机)解释执行
多行注释里面不允许有多行注释嵌套
1.11.2 文档注释
注释内容可以被 JDK 提供的工具 javadoc
所解析 , 生成一套以网页文件形式体现的该程序的说明文档 , 一般写在类
/**
* @Author: AdRainty
* @Date: 2022-04-25 20:28:19
*/
生成网页文档:
javadoc -d 文件夹名 -xx -yy Demo.java
例如
javadoc -d d:\\test -author -date Demo.java
2 Java基础语法
2.1 变量
变量是程序的基本组成单位
变量有三个基本要素:类型 + 名称 + 值
class Test {
public static void main(String []args){
int a = 1; // 定义一个变量,类型为int整形,名称a,值1
System.out.println(a); //输出a变量的值
}
}
变量表示内存中的一个存储区域,不同的变量,类型不同,占用的空间大小不同。例如
int
4字节,double
8字节该区域有字节的变量名称和类型
变量必须先声明,后使用
该区域的数据可以在同一类型范围内不断变化
变量在同一个作用域内不能重名
2.2 +号的使用
当左右两边都是数值型时,则做加法运算
当左右两边有一方为字符串,则做拼接运算
运算顺序是从左到右
System.out.println(100 + 98); //198
System.out.println("100" + 98); //10098
System.out.println(100 + 3 + "hello"); //103hello
System.out.println("hello" + 100 + 3); //hello1003
2.3 数据类型
每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)。
2.3.1 整数类型
Java 的整数类型就是用于存放整数值的,比如12 , 30, 3456 等等
Java各整数类型有固定的范围和字段长度,不受具体OS的影响,以保证Java程序的可移植性
Java的整型常量默认为
int
型,声明long
型常量需后加l
或L
Java程序中的变量常声明为
int
型,除非不足以表示大数,才使用long
bit为计算机中的最小存储单位。byte为计算机中基本存储单元,1byte = 8 bit
2.3.2 浮点类型
Java 的浮点类型可以表示一个小数,比如123.4 ,7.8 ,0.12 等等
关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
尾数部分可能丢失,造成精度损失(小数都是近似值)。
与整数类型类似,Java浮点类型有固定的范围和字段长度,不受具体OS的影响
Java浮点类型常量默认为double,声明float型,后面需要加
f
或F
通常情况下应该使用double型,因为比float型更精确
2.3.3 字符类型
字符类型可以表示单个字符,字符类型是char,char 是两个字节(可以存放汉字),多个字符我们用字符串String(我们后面详细讲解String)
字符常量是用单引号
''
括起来的单个字符,例如char c1 = 'a';
Java中还允许使用转义字符
\
来将其后面的字符转化为特殊字符型常量在Java中,char的本质是一个整数,在输出时,是Unicode码对应的字符
可以直接将char赋一个整数,然后输出时,会按照对应的Unicode字符输出
char类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码
字符和码值的对应关系是通过字符编码表决定的
ASCII,一个字节表示,实际上一个字节可以表示256个字符,只用了128个
Unicode,固定大小的编码,使用两个字节表示字符,字母和汉字统一都是占用两个字节
utf-8,编码表,大小可变的编码,字母使用1个字节,汉字使用3个字节
gbk,可以表示汉字,而且范围广,字母使用1个字节,汉字使用2个字节
gb2312,可以表示汉字,gb2312<gk
big5,繁体中文
2.3.4 布尔类型
布尔类型也叫Boolean类型, Boolean类型数据只允许取址true和false,无null
Boolean类型占一个字节
Boolean类型适于逻辑运算,一遍用于程序流程控制
2.4 基本数据类型转换
2.4.1 自动类型转换
当Java程序在进行赋值或者运算时,精度小的类型会自动转化为精度大的数据类型,这个就是自动类型转化
有多种类型的数据混合运算时,系统首先自动将所有数据转化成容量最大的那种数据类型,然后再进行计算
当我们把精度大的数据类型赋值给精度小的数据类型时,就会报错,反之就会进行自动类型转换
(byte,short)和char之间不会相互自动转换
byte,short,char他们可以计算,在计算时首先转换为int类型
Boolean不参与转化
表达式结果的类型自动提升为操作数中最大的类型
2.4.2 强制类型转换
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符( ),但可能造成精度降低或溢出,格外要注意。
int i = (int)1.9;
int j = 100;
byte b1 = (byte)j
2.4.3 基本数据类型和String 类型的转换
在程序开发中,我们经常要将基本数据类型转成String类型,或者将String类转成基本数据类型。
基本类型转String类型
将基本类型的值 + “”
即可
int n1 = 100;
String str1 = n1 + ""
String类型转基本数据类型
通过基本类型的包装类调用praseXX
方法即可
Integer.parseInt("123");
Boolean.parseBoolean("true");
Float.parseFloat("123.45");
在将String 类型转成基本数据类型时,要确保String类型可以转化成有效的数据 ,比如我们可以把"123" , 转成一个整数,但是不能把"hello" 转成一个整数
如果格式不正确,就会抛出异常,程序就会终止,
2.5 修饰符
2.5.1 访问控制修饰符
Java语言提供了很多修饰符,主要分为以下两类:
访问修饰符
非访问修饰符
修饰符用来定义类、方法或者变量,通常放在语句的最前端。
public class ClassName {
// ...
}
private boolean myFlag;
static final double weeks = 9.5;
protected static final int BOXWIDTH = 42;
public static void main(String[] arguments) {
// 方法体
}
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
私有访问修饰符是最严格的访问级别,所以被声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。声明为私有访问类型的变量只能通过类中公共的 getter 方法被外部类访问。Private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。
public : 对所有类可见。使用对象:类、接口、变量、方法
被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
2.5.2 非访问修饰符
为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
static 修饰符,用来修饰类方法和类变量。
静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
静态方法:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
final 变量:final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。final 修饰符通常和 static 修饰符一起使用来创建类常量。
final 方法:父类中的 final 方法可以被子类继承,但是不能被子类重写。声明 final 方法的主要目的是防止该方法的内容被修改。
final 类:final 类不能被继承,没有类能够继承 final 类的任何特性。
abstract 修饰符,用来创建抽象类和抽象方法。
抽象类:抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。抽象类可以包含抽象方法和非抽象方法。
抽象方法:抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供。抽象方法不能被声明成 final 和 static。任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。抽象方法的声明以分号结尾,例如:public abstract sample();
synchronized 和 volatile 修饰符,主要用于线程的编程。synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
transient 修饰符:序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
volatile 修饰符:volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
2.5 运算符
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
算术运算符
赋值运算符
关系运算符[比较运算符]
逻辑运算符
位运算符[需要二进制基础]
三元运算符
2.5.1 算术运算符
算术运算符是对数值类型的变量进行运算的,在Java 程序中使用的非常多。
2.5.2 关系运算符
关系运算符的结果都是boolean 型,也就是要么是true,要么是false
关系表达式经常用在if 结构的条件中或循环结构的条件中
2.5.3 逻辑运算符
用于连接多个条件(多个关系表达式),最终的结果也是一个boolean 值。
1) a&b
: &
叫逻辑与:规则:当a 和b 同时为true ,则结果为true, 否则为false 2) a&&b
: &&
叫短路与:规则:当a 和b 同时为true ,则结果为true,否则为false 3) a|b
: |
叫逻辑或,规则:当a 和b ,有一个为true ,则结果为true,否则为false 4) a||b
: ||
叫短路或,规则:当a 和b ,有一个为true ,则结果为true,否则为false 5) !a
: 叫取反,或者非运算。当a 为true, 则结果为false, 当a 为false 是,结果为true 6) a^b
: 叫逻辑异或,当a 和b 不同时,则结果为true, 否则为false
2.5.4 赋值运算符
赋值运算符就是将某个运算后的值,赋给指定的变量。可以分为
基本赋值运算符
=
,如int a = 10;
复合赋值运算符
+=
,-=
,*=
,/=
,%=
等,a += b
; [等价a = a + b;
]
赋值运算符特点
运算顺序从右往左
赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值
复合赋值运算符等价于下面的效果
复合赋值运算符会进行类型转换。
2.5.5 三元运算符
条件表达式? 表达式1: 表达式2;
如果条件表达式为true,运算后的结果是表达式1;
如果条件表达式为false,运算后的结果是表达式2;
表达式1 和表达式2 要为可以赋给接收变量的类型(或可以自动转换)
2.5.6 位运算符
>>
算术右移:低位溢出,符号位不变,并用符号位补溢出的高位<<
算术左移:符号位不变,低位补0>>>
逻辑右移:低位溢出,高位补0
2.6 标识符
Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
有的标识符都应该以字母(A-Z 或者 a-z),美元符($)、或者下划线(_)开始
首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合
关键字不能用作标识符
标识符是大小写敏感的
合法标识符举例:age、$salary、_value、__1_value
非法标识符举例:123abc、-salary
2.7 Java关键字
Java 保留字:现有Java 版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字
2.8 键盘输入语句
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。Input.java , 需要一个扫描器(对象), 就是Scanner
import java.util.Scanner; //表示把java.util下的Scanner类导入
public class Input {
public static void main(String[] args) {
// 1. 引入Scanner类所在的包
// 2. 创建Scanner对象,new创建一个对象
Scanner myScanner = new Scanner(System.in);
// 3. 接收用户输入
System.out.println("请输入名字:");
// 接收用户输入
String name = myScanner.next();
// String name = myScanner.nextLine();
System.out.println("输入的数据为:" + name);
myScanner.close();
}
}
next() 与 nextLine() 区别:
next():
一定要读取到有效字符后才可以结束输入。
对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
next() 不能得到带有空格的字符串。
nextLine() :
以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
可以获得空白。
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用nextXxx() 来读取:
System.out.print("输入整数:");
if (scan.hasNextInt()) {
// 判断输入的是否是整数
i = scan.nextInt();
// 接收整数
System.out.println("整数数据:" + i);
} else {
// 输入错误的信息
System.out.println("输入的不是整数!");
}
3 程序控制结构
3.1 顺序控制
程序从上到下逐行地执行,中间没有任何判断和跳转
public class Test{
int num1 = 12;
int num2 = num1 + 2;
System.out.println("num2");
}
3.2 分支控制if-else
让程序有选择的的执行,分支控制有三种
单分支if
双分支if-else
多分支if-else if -....-else
3.2.1 单分支
if(条件表达式){
执行代码块;
}
当条件表达式为true时,就会执行{}的代码。如果为false,就不执行。如果{}中只有一条语句,可以不用{},否则不能省略
3.2.2 双分支
if(条件表达式){
执行代码块1;
} else{
执行代码块2;
}
当条件表达式成立,即执行代码块1,否则执行代码块2.如果{}中只有一条语句,可以不用{},否则不能省略
3.2.3 嵌套分支
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。
if(条件表达式1){
if (条件表达式2) {
// if -else
} else{
// if -else
}
}
3.3 switch 分支结构
switch(表达式){
case 常量1:
语句块1;
break;
case 常量2:
语句块2;
break;
default:
default语句块;
break;
}
switch关键字,表示switch分支
表达式对应一个值
当表达式的值等于常量1,则执行语句块1
break表示退出switch
如果case 常量1匹配,执行语句块1,否则继续匹配case 常量2
如果一个都没有匹配上,执行default
表达式的数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型
switch表达式的返回值必须是(byte, short, int, char, enum[枚举], String)
case子句中的值必须是常量,而不能是变量
default字句是可选的,没有匹配的case时,执行default
break语句用来执行一个case分支后使程序跳出switch语句块,如果没有写break,程序会顺序执行到switch结尾,除非遇到break
3.4 for 循环控制
for (循环变量初始化; 循环条件; 循环变量迭代){
循环操作;
}
for 关键字,表示循环控制
for 有四要素: (1)循环变量初始化(2)循环条件(3)循环操作(4)循环变量迭代
循环操作, 这里可以有多条语句,也就是我们要循环执行的代码
如果循环操作(语句) 只有一条语句,可以省略{}, 建议不要省略
例如
for (int i = 1; i <= 10; i++){
System.out.println(i);
}
1) 循环条件是返回一个布尔值的表达式 2) for(;循环判断条件;)
中的初始化和变量迭代可以写到其它地方,但是两边的分号不能省略。 3) 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代 语句,中间用逗号隔开。
3.5 while 循环控制
while (循环条件){
循环体;
循环变量迭代;
}
1) 循环条件是返回一个布尔值的表达式 2) while 循环是先判断再执行语句
3.6 do..while 循环控制
循环变量初始化;
do{
循环体(语句);
循环变量迭代;
}while(循环条件);
do while 是关键字
也有循环四要素, 只是位置不一样
先执行,再判断,也就是说,一定会至少执行一次
最后有一个分号;
3.7 跳转控制语句-break
break 语句用于终止某个语句块的执行,一般使用在switch 或者循环[for , while , do-while]中
break语句出现在多层嵌套的语句块中时,可以通过标签指明要中止的是那一层语句块
标签的基本使用:
label1: { ......
label2:{ ......
label3:{
......
break;
......
}
}
}
例如:
label1:
for (int j = 0; j < 4; j++){
label2:
for(int i = 0; i<10; i++){
if (i == 2){
break label1;
}
System.out.println("i=" + i);
}
}
break 语句可以指定退出哪层
label1是标签,名字由程序员指定
break后指定到哪个label就退出到哪里
如果没有指定break,默认退出最近的循环体
3.8 跳转控制语句-continue
continue 语句用于结束本次循环,继续执行下一次循环。
continue 语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环, 这个和前面的标签的使用的规则一样.
3.9 跳转控制语句-return
return 使用在方法,表示跳出所在的方法
4 数组
4.1 数组介绍
数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
public class Array01{
public static void main(String[] args) {
//1. double[] 表示是double 类型的数组, 数组名hens
//2. {3, 5, 1, 3.4, 2, 50} 表示数组的值/元素,依次表示数组的第几个元素
double[] hens = {3, 5, 1, 3.4, 2, 50, 7.8, 88.8,1.1,5.6,100};
double totalWeight = 0;
for( int i = 0; i < hens.length; i++) {
//3. 我们可以通过hens[下标] 来访问数组的元素
// 下标是从0 开始编号的比如第一个元素就是hens[0]
totalWeight += hens[i];
}
System.out.println("总体重=" + totalWeight+ "平均体重=" + (totalWeight / hens.length) );
}
}
4.2 数组的初始化
4.2.1 动态初始化
先声明数组:语法:数据类型数组名[]; 也可以数据类型[] 数组名; 如
int a[];
或者int[] a;
创建数组:语法: 数组名=new 数据类型[大小];如
a=new int[10];
//(1) 第一种动态分配方式
double scores[] = new double[5];
//(2) 第2 种动态分配方式, 先声明数组,再new 分配空间
double scores[] ; //声明数组, 这时scores 是null
scores = new double[5]; // 分配内存空间,可以存放数据
4.2.2 静态初始化
//int[] arr1 = {1, 2, 3, 60,"hello"};//String ->int
double[] arr2 = {1.1, 2.2, 3.3, 60.6, 100};//int ->double
4.3 数组使用注意事项和细节
数组是多个相同类型数据的组合,实现对这些数据的统一管理
数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
数组创建后,如果没有赋值,有默认值 int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String null
使用数组的步骤1. 声明数组并开辟空间2 给数组各个元素赋值3 使用数组
数组的下标是从0 开始的。
数组下标必须在指定范围内使用,否则报:下标越界异常
数组属引用类型,数组型数据是对象(object)
4.4 数组赋值
1) 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。int n1 = 2; int n2 = n1;
2) 数组在默认情况下是引用传递,赋的值是地址。
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
4.5 数组拷贝
public static void main(String[] args) {
int[] A = {1,2,3,4,5};
int[] B = new int[A.length];
// 1. for循环拷贝 (拷贝数值类型) ---深拷贝
for (int i = 0; i < A.length; i++) {
B[i] = A[i];
}
// 2. copyof / copyOfRange
// Arrays.copy(原数组,自定义新数组长度);
// Arrays.copyOfRange(原数组,from,to);
// 注意拷贝截取的范围是左闭右开的[from,to)
int[] A = {1,2,3,4,5}; //A : [1, 2, 3, 4, 5]
int[] B = Arrays.copyOf(A,A.length); //B : [1, 2, 3, 4, 5]
int[] C = Arrays.copyOfRange(A,1,3); //C : [2, 3]
// 3. arraycopy
// System.arraycopy(源数组, 源数组要复制的起始位置 目标数组, 目标数组复制的起始位置, 复制的长度);
int[] A = {1,2,3,4,5};
int[] B = new int[A.length];
System.arraycopy(A,1,B,2,2); ////B : [0, 0, 2, 3, 0]
// 4. clone
int[] A = {1,2,3,4,5};
int[] B = A.clone();
}
当数组中存放的元素为基本数据类型时,此时发生的是深拷贝;当数组中存放的元素为引用数据类型时,此时发生的是浅拷贝;
深拷贝:拷贝后,修改原数组,不会影响到新数组;
浅拷贝:拷贝后,修改原数组,新数组也会相应的发生改变;
4.6 二维数组
直接为每一维分配空间,格式如下:
type[][] typeName = new type[typeLength1][typeLength2];
type 可以为基本数据类型和复合数据类型,typeLength1 和 typeLength2 必须为正整数,typeLength1 为行数,typeLength2 为列数。
例如
int[][] a = new int[2][3];
从最高维开始,分别为每一维分配空间,例如
String[][] s = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
对二维数组中的每个元素,引用方式为 arrayName[index1][index2]
,例如:
num[1][0];
4.7 Array类
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
给数组赋值:通过 fill 方法。
对数组排序:通过 sort 方法,按升序。
比较数组:通过 equals 方法比较数组中元素值是否相等。
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。