目录
一,环境搭建
1,Java体系与特点
2,Java跨平台原理
2.1 Java虚拟机(JVM)
2.2 垃圾回收器(GC)
2.3 Java SE组成概念图
2.4 JDK与JRE
2.5 环境变量
3,Java程序开发的三个步骤
4, 语法
注释
Java代码的位置
语法规则
二,基础语法
1,变量与基本数据类型
1.1 变量
1.2 数据类型
1.3 标识符
1.4 数据类型的转换
1.5 部分变量的使用
1.6 ASCII码表
2,方法
2.1 概述
2.2 格式
2.3 权限修饰符详解
2.4 返回值
2.5 参数列表详解
2.6 方法实例
3,运算符
3.1 算数运算符
3.2 赋值运算符
3.3 关系运算符
3.4 逻辑运算符
3.5 字符串连接运算符
3.6 三目运算符
4,命名规范
5,转义字符
三,流程控制
1,接收用户输入
2,程序的执行结构
3,分支执行结构
3.1 if条件语句
3.2 switch语句
4,循环执行结构
4.1 while循环
4.2 do-while 循环
4.3 for循环
4.4 break、continue与多重循环的跳出
4.5 判断用户输入类型
四,数组
1,数组
1.1 数组概念
1.2 数组创建格式
1.3 数组相关操作
2,数组常见问题
2.1 下标越界
2.2 空指针问题
3,数组应用
3.1 寻找数组最大最小值
3.2 常用算法
五,综合案例
Java1.2之后分为三个方向——Java SE、Java EE、Java ME;
- Java SE:Java Platform ,Standard Edition。标准版:各种应用平台的基础,桌面开发和低端商务应用的解决方案。
- Java EE:Java Platform ,Enterprise Edition。企业版:以企业为环境而开发应用程序的解决方案。
- Java ME:Java Platform ,Micro Edition。微型版:致力于消费产品和嵌入式设备的最佳解决方案。
Java可以做什么?
- 开发桌面应用程序:银行软件、商场结算软件;
- 开发面向Internet的web应用程序:门户网站(工商银行)、网上商城、阿里巴巴、电子商务网站;
- 提供各行业的解决方案:提供各行业的解决方案;
- 嵌入式开发:移动电话、可视电话、数字机顶盒和汽车导航系统;
Java的特性
- 一种纯面向对象的编程语言;
- 一种与平台无关(跨平台)的语言;(它提供了在不同平台下运行的解释环境)【当时九几年Java提出这个特性,然而现在很多语言都具备了】
- 一种健壮的语言,吸收了 C/C++语言的优点。;
- 有较高的安全性。(自动回收垃圾【C++中需要手动new/delete】,强制类型检查,取消指针);
JVM 可以理解成一个可运行 Java 字节码的虚拟计算机系统
- 它有一个解释器组件,可以实现 Java 字节码和计算机操作系统之间的通信;
- 对于不同的运行平台,有不同 的 JVM;
JVM 屏蔽了底层运行平台的差别,实现了“一次编译,随处运行”。
简单介绍
- 不再使用的内存空间应当进行回收-垃圾回收。
- 在 C/C++等语言中,由程序员负责回收无用内存。
- Java 语言消除了程序员回收无用内存空间的责任: JVM 提供了一种系统线程跟踪存储空间的分配情况。并在 JVM 的空闲时,检查并释放那些可以被释放的存储空间。
- 垃圾回收器在 Java 程序运行过程中自动启用,程序员无法精确控制和干预。
单纯运行Java程序:JRE;
进行Java项目开发:JDK;
JDK(Java Development Kits)Java 开发工具集
JDK(Java Development Kit)又称J2SDK(Java2 Software Development Kit),是Java开发工具包,它提供了Java的开发环境(提供了编译器javac等工具,用于将java文件编译为class文件)和运行环境(提 供了JVM和Runtime辅助包,用于解析class文件使其得到运行)。如果你下载并安装了JDK,那么你不仅可以开发Java程序,也同时拥有了运 行Java程序的平台。JDK是整个Java的核心,包括了Java运行环境(JRE),一堆Java工具tools.jar和Java标准类库 (rt.jar)。
具体包括:
- JRE(Java Runtime Environment)Java 运行时环境
- JVM
- Java API (应用程序编程接口)
- Java 编译器(javac.exe)、Java 运行时解释器(java.exe)、Java 文档化化工具(javadoc.exe)及其它工具及资源
JRE(Java Runtime Enviroment)Java运行环境:
JRE(Java Runtime Enviroment)是Java的运行环境。面向Java程序的使用者,而不是开发者。如果你仅下载并安装了JRE,那么你的系统只能运行Java程序。JRE是运行Java程序所必须环境的集合,包含JVM标准实现及 Java核心类库。它包括Java虚拟机、Java平台核心类和支持文件。它不包含开发工具(编译器、调试器等)。
主要功能有:
- 加载代码:由类加载器(class loader)完成;
- 校验代码:由字节码校验器(byte code verifier)完成;
- 执行代码:由运行时解释器(runtime interpreter)完成;
环境变量一般指的是:我的电脑-》属性-》高级系统设置-》环境变量
环境变量的配置:
- 为了使得安装的JDK文件在任意文件夹中可以正常运行,需要对环境变量中的Path变量进行修改;(不配置的话,只能在JDK安装目录中才能正常运行Java程序,比如在该目录下输入命令:java -version,可以正常出现JDK版本。而在其他目录输入命令时,则会报错:不是内部或外部命令)
- 将 JDK安装文件夹路径\bin; 添加到Path中;
- 然而由于日常生活中不同项目所用的JDK版本有可能不一致,因此需要频繁地更换Path中JDK的位置,这就使得配置过程中极易出错,万一误删了环境变量Path中重要的值,很有可能系统部分功能无法正常运行;
- 所以采取的方法是:用一个一个变量JAVA_HOME代替JDK的位置,并在原先Path中的位置替换为 %JAVA_HOME%\bin; ,这样就可以实现原先配置同样的功能;
单行注释://注释
多行注释:/*注释*/
文档注释:/**注释*/
class必须写在 .java 文件中;
- Java是一种纯面向对象的语言,任何代码语句必须包含在class中;
- 严格区分大小写;
- 是一种自由格式的语言;
- 代码分为结构定义语句和功能执行语句;
- 功能执行语句最后必须以分号结束;
变量就是系统为程序分配的一块内存单元,用来存储各种类型的数据。由于该存储单元中的数据可以发生改变,因此得名为"变量"。
变量分类
按所属的数据类型划分:
- 基本数据类型变量
- 引用数据类型变量 (比如字符串)
按被声明的位置划分:
- 局部变量:方法或语句块内部定义的变量
- 成员变量:方法外部、类的内部定义的变量
特别注意:类的外面不能有变量的声明
由于变量记录的数据内容大小不同, 导致所需的存储单元大小不同,在 Java 语言中使用数据类型的概念加以描述 . (C/C++、Java都属于强类型语言,声明变量时必须指定变量类型。相对应的,python属于弱类型语言)
字节是计算机信息技术用于计量存储容量的一种计量单位,作为一个单位来处理的一个二进制数字串,是构成 信息的一个小单位。Java 中的字节是八位的字节,即它包含八位的二进制数。
Java 对包、类、方法、参数和变量等要素命名时使用的字符序列称为标识符。
规则如下:
- 由字母、数字、下划线(_)和美元符号($)组成。(甚至可以使用中文作为部分变量,但不建议这样做)
- 不能以数字开头。
- 区分大小。
- 长度无限制。
- 不能是 Java 中的保留关键字。
标识符命名习惯:见名知意。
示例:
- 合法标识符:HelloWord、username2、user_name、_userName、$abc_123
- 非法标识符:2UserName、user#Name、Hello World、class
boolean 类型不能转换成任何其它数据类型。
自动类型转换:
- 容量小的类型自动转换成容量大的数据类型 byte,short,int -> float ->long ->double
- byte,short,int 不会互相转换,它们三者在计算时会转换成 int 类型
强制类型转换:
- 容量大的类型转换成容量小的数据类型时,要加上强制转换符
- long l = 100L;
- int i = (int)l;
- 有可能造成精度降低或数据溢出,使用时要小心
当出现以下场景时,编译器会提示错误:
float num1 = 10.1;// 浮点数默认为double类型,由于左边float,右边double,所以提示需要强制类型转换。解决方法:在浮点数后加字符 f,即 float num1 = 10.1f;
long num2 = 2200000000;// 整型默认为int,最大值为21亿多,long型变量虽然足够容纳,但由于左边为long,右边为int,所以还是会提示超出范围。解决方法:在整型后加字符l,即long num2 = 2200000000l;
方法用于封装一段特定的逻辑功能。方法的主要要素有:权限修饰符、方法名、参数列表和返回值。
方法调用结束后可以返回一个数据,称之为返回值。
方法在声明时必须指定返回值的类型。
通过 return 语句返回,return 语句的作用在于结束方法且将数据返回。
如果方法没有返回值(即方法不需要返回数据),需将返回值类型声明为 void
方法的参数列表:在调用时传递给方法,需要被方法处理的数据。
在方法定义时,需要声明该方法所需要的参数变量。
在方法调用时,会将实际参数值传递给方法的参数变量。
必须保证传递参数的类型和个数符合方法的声明。
public void say(int a, int b) {
System.out.println("say函数正在执行");
}
++:
如果是变量前缀:先对此变量加 1,再执行其他的操作。
如果是变量后缀:先执行当前语句的其他操作,再对此变量加 1
--:
如果是变量前缀:先对此变量减 1,再执行其他的操作。
如果是变量后缀:先执行当前语句的其他操作,再对此变量减 1
赋值运算符作用是将一个值赋给一个变量,运算顺序从右到左;
关系运算符作用是比较两边的操作数,结果总是 boolean 型的。
逻辑运算符用于对 boolean 型结果的表达式进行运算,运算结果总是 boolean 型,后面结合条件结构讲解。
- &:与,需要左右两端都计算出,结果全0为false,否则为true;
- &&:短路与,左边计算出为false则停止后面的运算,否则继续执行运算符后面的表达式,全部为true,才判断为true;
String s="He" + "llo"; 结果"Hello"
"+"除了可用于字符串相连接,也能将字符串与其它的数据类型相连成一个新的字符串。 (“+”两边任意一边为字符串,结果就为字符串);
如:String s="x" + 123; 结果"x123
X ? Y : Z
X 为 boolean 类型表达式,先计算 x 的值,若为 true,整个三目运算的结果为表达式 y 的值,否则整个运算结果为表达式 z 的值。
例:
- int score = 75;
- String type = score >=60 ? "及格" : "不及格";
标识符 :Java 对包、类、方法、参数和变量等要素命名时使用的字符序列称为标识符。
规则如下:
- 由字母、数字、下划线(_)和美元符号($)组成。
- 不能以数字开头。
- 区分大小。
- 长度无限制。
- 不能是 Java 中的保留关键字。
命名规范: 软性建议
- 类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。
- 方法名规范: 首字母小写,后面每个单词首字母大写(小驼峰式)。
- 变量名规范:全部小写。
所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示常见的那些不能 显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。
首先,创建Scanner工具类对应的实体对象input,用于操作输入,需要注意以下两点:
更具体的输入,需要使用上一步创建的实体input带有的函数,比如:
- input.nextInt(); // 返回值为int
- input.nextFloat(); // 返回值为float
- input.nextByte(); // 返回值为byte
- ......
然而上述函数要求输入必须与预定类型一致。为了方便接受各种不同类型的输入,可以使用函数:
- input.next(); // 返回值为String
- input.nextLine(); // 返回值为String
注意:
next与nextLine尽量不要同时使用,以下面的例子为例:
package com.kaikeba.demo; import java.util.Scanner; public class Demo4 { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("请输入next接受的内容:"); String s1 = input.next(); System.out.println(s1); System.out.println("请输入nextLine接受的内容:"); String s2 = input.nextLine(); System.out.println(s2); System.out.println("------我是分界线------"); } }
原先设想的是可以在控制台输入两次数据,一次给next函数,另一次给nextLine函数。然而运行时会发现,next接收数据后,敲下回车,可以正常显示,等到nextLine函数接受数据时,却不能继续在控制台进行输入。
原因是:敲下回车后,next函数接受了数据,nextLine函数接收了后面的换行字符;所以s2中存放的是换行字符;
1996 年,计算机科学家 Bohm 和 Jacopini 证明了:任何简单或复杂的算法都可以由顺序结构、分支结构和循环结构这三种基本 结构组合而成。
它们的共同点是都包含一个入口和一个出口,它们的每个代码都有机会被执行,不会出现死循环。
- 顺序结构 :顺序结构是一种基本的控制结构,它按照语句出现的顺序执行操作 ;
- 分支结构 :分支结构又被称为选择结构,根据条件成立与否来执行操作;
- 循环结构 :循环结构是一种重复结构,如果条件成立,它会重复执行某一循环体,直到出现不满足的条件为止;
if 条件结构是根据条件判断之后再做处理
- if(条件语句){…}
- if (条件语句){…}else{…}
- if (条件语句){…}else if(条件语句){…}
- if (条件语句){…}else if(条件语句){…}else{…}
例子:用户输入学生成绩,判断成绩是否及格,判断条件为 优良: > 90、良好:81-90、中:60-80、不及格:<60
import java.util.Scanner; public class Demo4{ public static void main(String[] args){ Scanner input = new Scanner(System.in); System.out.println("请输入成绩:"); int score s= input.nextInt(); // 91 优 81-90 良 60-80 中 60 差 if(score >= 91){ System.out.println("您的成绩是优秀!继续加油哦!"); }else if(score >= 81 & score < 91){ System.out.println("您的成绩是良好!还要努力哦!"); }else if(score >= 60 & score <= 80){ System.out.println("您的成绩是中等!还要加倍努力哦!"); }else{ System.out.println("您的成绩是差!准备补考费吧!"); } } }
switch(表达式){
case 取值 1: 语句块 1;break;
case 取值 n: 语句块 n;break;
default: 语句块 n+1;break;
}
switch 语句有关规则
- 表达式的返回值必须是下述几种类型之一:int, byte, char, short,String;
- case 子句中的取值必须是常量,且所有 case 子句中的取值应是不同的;
- default 子句是可选的;
- break 语句用来在执行完一个 case 分支后使程序跳出 switch 语句块;
- 如果 case 后面没有写 break 则直接往下面执行!
- Case 后面的执行体可写{ }也可以不写{ }
例题:多分支月份输出天数(充分利用语句特性)
import java.util.Scanner; public class Demo6{ public static void main(String[] args){ Scanner input = new Scanner(System.in); System.out.println("请输入月份:"); int month = input.nextInt(); switch(month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: System.out.println(month + "月共有 31 天"); break; case 4: case 6: case 9: case 11: System.out.println(month + "月共有 30 天"); break; case 2: System.out.println(month + "月共有 28 天"); break; default : System.out.println("友情提示,您输入有误!"); break; } } }
循环语句功能
- 在循环条件满足的情况下,反复执行特定代码
循环语句分类
- for 循环
- while 循环
- do/while 循环
符合条件,循环继续执行;否则,循环退出
特点:先判断,再执行
- while(条件表达式){
- //语句块;
- }
int sum = 0; int score = 0; int avg = 0; int studentNum = 20; while(i<=studentNum){ System.out.print("请输入第" + i + "位同学的成绩:"); score = input.nextInt(); sum = sum + score; i++; } avg = sum / stuNum ;
先执行一遍循环操作,符合条件,循环继续执行;否则,循环退出 (保证函数体内的代码至少执行一次)
特点:先执行,再判断
- do {
- 循环操作
- }while ( 条件表达式 );
- for(初始化参数;判断条件 ;更新循环变量){
- 循环体;
- }
public class ForLoop { public static void main(String [] args){ int result = 0; for(int i=1; i<=100; i++) { result += i; } System.out.println("result=" + result); } }
break:跳出包含break的最近的一个循环体;
continue:跳过此次循环体中continue语句后的代码,并执行下一次循环;
多重循环的跳出使用别名的方法,举例如下:
数组是相同数据类型的多个数据的容器。
这些元素按线性顺序排列。所谓线性顺序是指除第一个元素外,每一个元素都有唯一的前驱元素;除最后一个元素外,每一个元素都有唯一的后继元素。(“简单理解就是:一个跟一个顺序排列”)。
格式 1. 数据类型[] 数组名称 = new 数据类型[数组长度];
格式 2. 数据类型[] 数组名称 = {数组内容 1,数组内容 2,数组内容 3...数组内容 n};
格式 3. 数据类型[] 数组名;
格式 3 属于只创建了数组引用名, 并未在内存创建数组空间。
格式 4. 数据类型[] 数组名称 = new 数据类型[]{内容 1,内容 2,内容 3...内容 n};
package com.kaikeba.demo; import java.util.Scanner; public class Demo1 { public static void main(String[] args) { /* * 创建数组的格式 */ // 常用格式1:创建数组同时指定数组内容 // 数据类型[] 数组名 = {数据1,数据2,数据3,......}; int[] tem1 = {1, 2, 3, 4}; // 常用格式2:创建数组,指定长度,不指定内容 // 数据类型[] 数组名 = new 数据类型[数组长度(int)类型] int[] tem2 = new int[10]; // 不常用格式1:创建数组 不初始化 // 数据类型[] 数组名 int[] tem3; // 不常用格式2:创建数组并指定内容 // 数据类型[] 数组名 = new 数据类型[]{数据1,数据2,数据3,......} int[] tem4 = new int[] {1, 2, 3, 4}; } }
1,通过下标操作数据的方式
- 给数组某个下标赋值:
tem1[2] = 66;
- 从下标取值:
System.out.println(tem1[2]);
2,获得数组长度
- 数组名.length
System.out.println(tem2.length);
名称与值未绑定;
创建变量,存储最大值,遍历数组更新最大值;
建议:将变量初始化为数组的第一个元素;
冒泡排序:
原理:
- - 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- - 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的 数。
- - 针对所有的元素重复以上的步骤,除了最后一个。
- - 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
名字来由:
- 是因为最小(或最大)的元素会经由交换慢慢“浮”到数列的顶端(降序或升序),就如同水中的气泡最终会上浮到 顶端一样,故名“冒泡排序”。
package com.kaikeba.demo1; public class Demo4 { /** * 冒泡排序 * @param args */ public static void main(String[] args) { int[] nums = {20,15,18,13,30,60}; int temp; //外层循环控制的是, 比较的轮数。 //外层循环次数: length-1 for(int i=0;i
nums[j+1]) { //两两相比, 满足移动条件 temp = nums[j]; nums[j] = nums[j+1]; nums[j+1] = temp; } } } //排序已经完成。 下面是遍历打印查看的过程 for(int i=0;i
二分查找
概述
- 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,二分查找要求数组数据必须采用顺序存储结构有序排列。
原理
- 首先,假设数组中元素是按升序排列,将数组中间位置的数据与查找数据比较,如果两者相等,则查找成功;否则利用 中间位置记录将数组分成前、后两个子数组,如果中间位置数据大于查找数据,则进一步查找前子数组,否则进一步查 找后子数组。
- 重复以上过程,直到找到满足条件的数据,则表示查找成功, 直到子数组不存在为止,表示查找不成功。
package com.kaikeba.demo1; public class Demo5 { /** * 二分查找(折半查找) */ public static void main(String[] args) { int[] nums = {10,20,30,40,50,60,70,80,90}; //要查找的数据 int num = 20; //关键的三个变量: //1. 最小范围下标 int minIndex = 0; //2. 最大范围下标 int maxIndex = nums.length-1; //3. 中间数据下标 int centerIndex = (minIndex+maxIndex)/2; while(true) { System.out.println("循环了一次"); if(nums[centerIndex]>num) { //中间数据较大 maxIndex = centerIndex-1; }else if(nums[centerIndex]
maxIndex) { centerIndex = -1; break; } //当边界发生变化, 需要更新中间下标 centerIndex = (minIndex+maxIndex)/2; } System.out.println("位置:"+centerIndex); } }
多维数组
package com.kaikeba.demo; import java.util.Scanner; public class Demo1 { public static void main(String[] args) { /* * 多维数组 * * 创建格式: * 数据类型[] 数组名 = new 数据类型[长度] * int[][] tem = new int[10][]; */ int[][] tem = new int[10][]; // tem[0] = {1, 2, 3}; // 这样写会报错 tem[0] = new int[]{1, 2, 3}; System.out.println(tem[0][2]); } }
双色球彩票训练任务
参考代码:
package com.kaikeba.demo; import java.util.Scanner; public class Demo1 { public static void main(String[] args) { int[] winRed = new int[6]; // 中奖红色球号码 int[] userRed = new int[6]; // 用户红色球号码 int winBlue; // 中奖蓝色球号码 int userBlue; // 用户蓝色球号码 Scanner input = new Scanner(System.in); // 生成随机数 for(int i = 0; i < 6; i++) { winRed[i] = (int)(Math.random() * (33 - 1) + 1); } winBlue = (int)(Math.random() * (16 - 1) + 1); // 获取用户提供的数字 System.out.println("请输入6个红色球号码(1-33):"); for(int i = 0; i < 6; i++) { userRed[i] = input.nextInt(); } System.out.println("请输入1个蓝色球号码(1-16):"); userBlue = input.nextInt(); // 输出中奖号码 System.out.println("中奖红色球号码分别为:"); for(int i = 0; i < 6; i++) { System.out.print(winRed[i] + " "); } System.out.println(); System.out.println("中奖蓝色球号码分别为:"); System.out.println(winBlue); // 对比 获得中奖号码个数 int scoreOfRed = 0, scoreOfBlue = 0; for(int i = 0; i < 6; i++) { for(int j = 0; j < 6; j++) { if(userRed[i] == winRed[i]) { scoreOfRed++; break; } } } if(userBlue == winBlue) { scoreOfBlue++; } if(scoreOfRed == 6 && scoreOfBlue == 1) { System.out.println("一等奖"); }else if(scoreOfRed == 6 && scoreOfBlue == 0) { System.out.println("二等奖"); }else if(scoreOfRed == 5 && scoreOfBlue == 1) { System.out.println("三等奖"); }else if((scoreOfRed == 5 && scoreOfBlue == 0) || (scoreOfRed == 4 && scoreOfBlue == 1)) { System.out.println("四等奖"); }else if((scoreOfRed == 4 && scoreOfBlue == 0) || (scoreOfRed == 3 && scoreOfBlue == 1)) { System.out.println("五等奖"); }else if((scoreOfRed == 2 && scoreOfBlue == 1) || (scoreOfRed == 1 && scoreOfBlue == 1) || (scoreOfRed == 0 && scoreOfBlue == 1)) { System.out.println("六等奖"); }else { System.out.println("很遗憾,未中奖"); } } }