首页 > 代码库 > 二 Java基础
二 Java基础
【第一个JAVA程序】
书写hello world,书写中排除常见的错误。★★★★★
1 class Demo //类名:书写时每一个单词的首字母大写 2 { 3 public static void main(String[] args) 4 { 5 System.out.println("heloo world"); 6 } 7 }
Javac: 编译命令:
功能是将Java的源文件编译成class文件。在编译的过程中会进行语法检查,
如果有语法错误错误,这时编译无法通过,不会生成对应的class文件
Java :运行Java程序命令
首先会启动Jvm,JVM加载对应的class文件。接下来查找当前的这个class文件中是否有main主方法
如果没有报错。有就会执行mainJava严格区分大小写。一个Java文件中可以有多个类,但要是类经过public修饰,类名必须与文件名保持一致。.Java为源文件,源文件经过Javac编译后生成.class文件此文件被虚拟机调用。
常见的错误
1、缺少分号; 这个错误在编译时发生
2、括号不配对这个错误在编译时发生
3、主方法名字写错mian发生在运行时
4、编译器找不到文件
解决办法:
查看当前目录下有没有1234.Java这个文件。如果没有话,切换到1234.Java所在的目录从新执行Javac
如果当前目录下面有,使用dir命令查看当前文件具体的扩展名是什么。
5、找不到class文件 E:\JavaSE1115\code\day01>Java Demo
错误: 找不到或无法加载主类 Demo
前提是,配置的了classpath:JVM会在classpath配置的目录中查找,如果没有找到,会报上面的错误
如果没有配置classpath,当前目录下面没有Demo.class这个文件。
【Java语法格式】
如何定义Java中的类:
Java代码都定义在类中,类用 class来定义,区分public class和class
main方法的作用:main方法是程序的入口;保证程序的独立运行;被JVM调用。
【注释】
注释用来解释说明Java代码用的,注释不属于Java代码的运行部分,但是Java代码的一部分,注释的另一功能是调试代码。
Java中的三种注释:
1、 单行注释 :eg:// 注释内容
a) 注意:单行注释可以嵌套单行注释
2、 多行注释 :eg:/* 注释内容 */
a) 注意:多行注释不可以嵌套多行注释,但可以嵌套单行注释
3、文档注释 :eg:/** 注释内容 */
a) Java中特有的注释,这种注释提供给Javadoc命令,将代码中的注释部分提取出来,形成一个html文档即API文档。注释使用在类上面,主要将这个信息通过Javadoc命令提取。
【Java 关键字 保留字 标示符】
【关键字】
关键字:被Java语言赋予了特定含义的单词。
特点: 关键字所有字母都为小写,好比汉语中的专有名词。
用于定义数据类型的关键字 |
||||
class |
interface |
byte |
short |
int |
long |
float |
double |
char |
boolean |
void |
|
|
|
|
用于定义数据类型值的关键字 |
||||
true |
false |
null |
|
|
用于定义流程控制的关键字 |
||||
if |
else |
switch |
case |
default |
while |
do |
for |
break |
continue |
return |
|
|
|
|
用于定义访问权限修饰符的关键字 |
||||
private |
protected |
public |
|
|
用于定义类,函数,变量修饰符的关键字 |
||||
abstract |
final |
static |
synchronized |
|
用于定义类与类之间关系的关键字 |
||||
extends |
implements |
|
|
|
用于定义建立实例及引用实例,判断实例的关键字 |
||||
new |
this |
super |
instanceof |
|
用于异常处理的关键字 |
||||
try |
catch |
finally |
throw |
throws |
用于包的关键字 |
||||
package |
import |
|
|
|
其他修饰符关键字 |
||||
native |
strictfp |
transient |
volatile |
assert |
【保留字】
保留字:goto 和 const是java的保留字。现在未被使用。
【标示符】
标示符可简单理解为Java程序中为了提高阅读性自定义的名称。Eg:类名,方法名,变量名。
标示符组成:
a) 标示符由数字、字母、下划线、$符组成,数字不能开头。(字母还可以是中文,日文等)
b) 标示符大小写敏感 ;
c) 标示符不能使用 Java中的关键字和保留字;
d) 名字不能用空格隔开
e) 别用JavaAPI里面的类名作为自己的类名。
注意:在取名时,只要标示符不是关键字就可以,但为了提高阅读性经常用有意义的单词作为标示符。
【标示符书写规范】
包名:多单词组成时所有字母都小写,eg:xxxyyyzzz
(包:用于把同名的文件放到不同的目录下,多级包用.隔开 eg:cn.itcast(可用域名反写作包名))
类名接口名:所有单词的首字母大写,eg:XxxYyyZzz
变量名函数名:多单词组成时,第一个单词首字母小写,其余单词首字母大写
Eg:xxxYyyZzz
常量名:所有单词字母都大写,多单词时单词间用下划线连接,eg:XX_YY_ZZ
【进制和常量】
【进制】
十进制可以用8个二进制位表示。八进制是每三个二进制位表示一位,不够的补零,十六进制是每四个二进制位表示一位。
【常量】
常量:在程序中固定不变的值。
Eg:整数1,4,6 小数3.14 一星期有7天等
【常量分类】
常量的分类:(字面值常量 ,自定义常量)
整数常量:所有整数
小数常量:所有小数
布尔型常量:两个值,true false
字符串常量:将一个或多个字符用双引号标识
字符常量:将一个字母或数字或者符号用单引号标识
null常量:只有一个值null
【变量】
概念:变量表示内存中的一个存储区域,该区域用来不断的存放同一类型的常量数据,并可以重复使用该区域并且这个区域有自己的名称和类型。
理解:变量就好比数学中的未知数;
格式:数据类型 变量名 = 初始化值;
数据类型 变量名; 变量名 = 初始化值;
注意:变量在使用前,一定要赋值。
取名:变量表示内存中的一个存储区域,必须给该区域取个名字才能使用,当给变量取名时,同样需要见名知意。Eg:String name;
【数据类型:】
Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间。
【数据类型分类:】
基本数据类型:4类8种。
引用数据类型:类、接口、数组
数据类型 |
所占字节数 |
默认值 |
byte |
1 |
0 |
short |
2 |
0 |
int |
4 |
0 |
long |
8 |
0 |
float |
4 |
0.0 |
double |
8 |
0.0 |
char |
2 |
‘\u0000‘(空字符) |
boolean |
1 |
false |
注意:整数默认是int类型,long类型整数需要加后缀名l或L;
浮点数默是double类型,float浮点数需要加后缀名F或f。
Java里只有浮点型的变量才可以接受科学计算式结果:int num = 314E2; //× num为int类型,不可以使用科学计数法
解析:
布尔型boolean
boolean类型通常用于逻辑运算和程序流程控制,只允许取值true或false(不可使用0或非0的数代替,区分于C语言)。
字符型char (A:65, a:97, 0:48)
char类型数据用来表示通常意义上的“字符”,char占用2个字节,取值范围[0,65535],但是前256个表示特殊字符,字符常量为用单引号括起来的单个字符。单引号中必须要有字符,否则会报错。
Eg:char c = ‘A‘; char c2 = ‘传‘; char c3=97;
java中的char类型是否可以存储一个中文,为什么?
可以。原因是java采用的unicode编码方法,这个编码用两个字节表示一个字符。
转义字符
有部分符号在Java中有特殊含义,当需要使用符号自身原有的意思时,可以通过转移字符表示。
Eg:键盘上的制表符tab键,可以使用‘\t’表示。
如双引号,在java中使用双引号表示字符串,若想使用双引号,可使用‘\”’,\会把后面的内容转义掉。
String类型
String不属于基本数据类型;但和字符有一定的联系。String是一个类,表示字符串; 就是一串字符,也就是多个字符连接在一起;字符串都得使用 "" 括起来的,连接字符串使用 + ;(String不属于基本数据类型)eg:System.out.println(‘a’+1+”hello”);//98hello 先运算
System.out.println(“hello”+’a’+1);//helloa1
【类型转换】
在参与运算的过程中,要求运算符两端的数据类型一致。
【隐式类型转换】
隐式类型转换:(自动转换,从小到大 boolean类型不参与):
Eg:byte b = 2; //会把int类型的2转换为byte类型存放到b空间中。
当把一个int类型的数据存放到char类型空间时也会发生隐式类型转换:
Eg:char ch = 65; //这里会用int类型65,到编码表中查找对应的字符,然后将字符存放在ch空间中
char ch2 = ‘A‘;//直接将A字符存放在ch2空间中
注意:当把超过byte和short范围的数据给他们开辟空间存放会发生编译时错误,同样把无法在编码表中查找到对应字符的数据存放到char空间也会发生报错。
整型、字符型、浮点型的数据在混合运算中相互转换,转换时遵循以下原则:
容量小的类型可自动转换为容量大的数据类型(类型自动提升)
byte,short,char → int → long → float → double
为什么long可以到float?
因为浮点数的存储和整数不太一样。
浮点数的存储只存储有效数字,和次幂数字等。
23456.123;
2.34E3 * 10 ^ 4
不管怎么说,long能够表示的数据的值是小于float的。
所以,这种转换是可以的。
long 2^63
float 10^38 > 8^38 = 2^3^38 = 2^114 > 2^63
byte,short,char之间不会相互转换,他们在计算时首先会转换为int类型。
【强制转换】(从大到小)
这种做法不推荐。因为可能有数据精度的损失。
格式:
目标数据类型 变量名 = (目标数据类型) (被强制转换的数据);
Eg:byte b = (byte) (100 + 200);
思考:
byte b1 = 3,b2 = 4,b;
b = b1+b2; //b1,b2为变量,数值都不确定相加的值可能超出范围。编译失败
b = 3+4; // 3,4 为常量计算结果在byte内,编译通过
【运算符】
【算术运算】
特殊符号:
+: 加法,正号,字符串连接符。
System.out.println(10+‘a‘+"hello");//107hello
System.out.println("hello"+‘a‘ + 10);//helloa10
/: 整数相除,结果只能是整数。当两侧数据类型一致,结果仍为运算过后保持一致
Eg:4321/1000*1000=4000;
%: 取得余数。
如果左边小于右边,结果是左边。
如果左边等于右边,结果是0。
如果左边大于右边,结果是余数。
符号只和左边有关。
自加自减
++ 自加。对原来的数据进行+1;
-- 自减。对原来的数据进行-1;
如果单独使用:
符号在前后结果一致。
如果参与运算使用:
前:先++或者--,后运算。
后:先运算,后++或者--。
当在一个运算表达式中包含自加运算时,当自加符号在变量右侧时,需要先将变量临时存储,然后给变量空间加1,接着用临时变量空间中的值去给其他运算符进行运算。当自加符号在变量左侧时,需 要先给变量空间加1,然后把加1后的值和其他运算符进行运算。
Eg:int i =4; i=i++; System.out.println(i);//4;
【赋值运算符(=,+=,-=,*=,/=,%=)】
赋值号的功能就是讲赋值号右侧的结果存储到左侧的变量空间中。
Eg:int a = 3;//将3 存储到左侧a空间中
int b,c,d;
b=c=d=a;//将a空间中的值分别存储到d,c,b空间中。
= 把右边的赋值给左边的变量。
+= 把左右两边的结果赋值给左边。
注意:
左边只能是变量,不能是常量。
呵呵:下面那个有问题,并说明。
short s = 1;
s = s + 1;//编译失败,因为s会被提升为int类型,运算后的结果还是int类型,无法赋值给short类型 左边 = (左边数据类型)(左边操作右边);
s += 1;//编译通过,因为+=运算符在给s赋值时,会自动完成强转操作。
【比较运算符(>,< ,>=,<=,==,!=,instanceof)】
比较运算符用来判断数据的大小。
>大于 >=大于等于 <小于 <=小于等于 ==相等 !=不等
instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。
比较运算符,运算完的结果要么是true,要么是false,根据比较的结果做出相应的逻辑判断。
注:比较运算符“==”不能误写成“=”
【逻辑运算符(&,|,^,!,&&,||。部分可用于位运算)】
& : 与 有false 则false
| :或 有true则true
^ : 异或。两边相同为false,两边不同为true
!:非。 非真为假,非假为真
&& 短路与 如果左侧为真右边参与运算,如果左侧为假,右侧不参与运算
|| 短路或 左侧为真右侧不参与运算。
【位运算(&,|,~,<<,>>,>>>)】
位运算:主要是说的是 二进制数位运算。(为方便记忆0为false,1为true)
1,运算符符号
& 按位与运算。规则:相同二进制位上数值都为1,结果为1;否则为0。
Eg:
3 & 5 先把 3和5以二进制表示,再进行按位于运算:
十进制 二进制 结果(十进制)
3 00000000_00000000_00000000_00000011
5 00000000_00000000_00000000_00000101
-------------------------------------------------------------------------------------------------
& : 00000000_00000000_00000000_00000001 = 1
| 按位或运算。规则:相同二进制位上数值都为0,结果为0;否则为1.
Eg:
3 | 5 先把 3和5以二进制表示,再进行按位于运算:
十进制 二进制 结果(十进制)
3 00000000_00000000_00000000_00000011
5 00000000_00000000_00000000_00000101
-----------------------------------------------------------------------------------------
| : 00000000_00000000_00000000_00000111 7
^ 按位异或。规则:参与运算的两个对应位相同结果为0;否则为1。
Eg:
十进制 二进制 结果(十进制)
3 00000000_00000000_00000000_00000011
5 00000000_00000000_00000000_00000101
-----------------------------------------------------------------------------------------
^ : 00000000_00000000_00000000_00000110 6
~ 按位 取反。 规则:二进制位上的0变1;1变0。
Eg: 十进制 二进制 结果(十进制)
5 00000000_00000000_00000000_00000101
-----------------------------------------------------------------------------------------
补码: ~ : 11111111_11111111_11111111_1111010 -6
反码: 11111111 _11111111 11111111_1111001
源码: 10000000 00000000 00000000 0000110
左右移 运算
左移操作“<<”:将运算数的二进制码整体左移指定位数,左移之后的空使用“0”来补充,移出去的二进制数忽略不计。
9 << 2 :
十进制 二进制 结果(十进制)
9 00000000_00000000_00000000_00001001
-----------------------------------------------------------------------------------------
00000000_00000000_00000000_0000100100 36
所以9<<2等于 36.
规律:<<:相当于给原数乘以2的倍数
右移操作“>>”:将运算数的二进制码整体右移指定位数,右移之后的空使用“符号位”来补充。移出去的二进制数忽略不计。若是正数使用“0”补充;若是负数使用“1”补充;
9 >>2 :
十进制 二进制 结果(十进制)
9 00000000_00000000_00000000_00001001
-----------------------------------------------------------------------------------------
0000000000_00000000_00000000_00001001 2
所以9>>2等于 2.
规律:>>:相当于给原数除以2的倍数
-6 >> 2:
十进制 二进制 结果(十进制)
-6 11111111_11111111_11111111_1111010
-----------------------------------------------------------------------------------------
1111111111_11111111_11111111_1111010
所以-6>>2等于 -2.
无符号右移">>>":将运算数的二进制码整体右移指定位数,右移之后的空使用“0”来补充
面试题:最高效求2*8? 2<<3;
【三元运算符】
三元运算符,也称为三目运算符或则问号冒号运算符。即有三个表达式参与的运算表达式。既然是个运算符,运算完必须有运算结果。
格式:(表达式1)?表达式2:表达式3;
运算原则:表达式1运算结果必须为boolean类型的值。
表达式1的结果为true时,表达式2的运算结果为整个三元运算符的结果。
表达式1的结果为false时,表达式3的运算结果为整个三元运算符的结果。
Eg: int x = 3,y ;
y = x < 10 ? 100 : 200;//
System.out.println("y="+y);
Eg:求三个数中的最大值
int a = 1,b = 2,c = 3;
int max = a > b ? (a>c?a:b):(b>c?b:c);
(int temp = a>b?a:b;
int max = temp>c?temp:c;)
1.位运算应用
需求1:最有效率运算2乘以8。 → 通过位移运算 2<<3.
需求2: 完成两个整数变量的数值呼唤(不使用第三方变量)
//1.通过第三方变量的形式进行置换。
int a = 3, b = 7;
int temp = a;
a = b;
b = temp;
//2.通过和的形式。有个弊端,两个数据较大,可能会超出int范围。
a = a + b;//a = 3 + 7;
b = a - b;//b = 3 + 7 - 7; b = 3;
a = a - b;//a = 3 + 7 - 3; a = 7;
//3.技巧。异或。(左边:a,b,a; 右边:a^b;)
a = a ^ b;// a = 3 ^ 7;
b = a ^ b;// b = 3 ^ 7 ^ 7;
a = a ^ b;// a = 3 ^ 7 ^ 3;
【算符的优先级】
运算符的优先级决定了表达式的执行顺序,表达式的运算通常是按照运算符的优先级由高到低依次执行的。
优先级 |
描述 |
运算符 |
1 |
括号 |
()、[] |
2 |
正负号 |
+、- |
3 |
自增自减,非 |
++、--、! |
4 |
乘除,取余 |
*、/、% |
5 |
加减 |
+、- |
6 |
移位运算 |
<<、>>、>>> |
7 |
大小关系 |
>、>=、<、<= |
8 |
相等关系 |
==、!= |
9 |
按位与 |
& |
10 |
按位异或 |
^ |
11 |
按位或 |
| |
12 |
逻辑与 |
&& |
13 |
逻辑或 |
|| |
14 |
条件运算 |
?: |
15 |
赋值运算 |
=、+=、-=、*=、/=、%= |
16 |
位赋值运算 |
&=、|=、<<=、>>=、>>>= |
如果在程序中,要改变运算顺序,可以使用()。 |
流程语句
【程序运行流程&顺序结构】
(程序的流程:代码的执行顺序)
说明:当在DOS命令行中输入java Demo(假设有Demo.class文件)回车后。首先会加载JVM,JVM
会去加载当前Demo这个class文件,并执行其中的main方法,当程序执行main方法的时候会从第一行开始往下执行,直到整个代码全部执行完成。像这样的执行流程就是常见的顺序执行结构。
【语法结构:】
【判断结构(if)】
if是java中的关键字,当程序在执行过程中遇到if关键字,JVM会在此进行判断,根据判断结果需要处理相应的代码。
【if 判断第一种格式:】
if(条件表达式)
{
执行语句;
}
格式说明:if关键字后面是一对小括号(后面没有分号),小括号中的表达式运算完的结果必须是boolean 类型的值。
执行说明:JVM在执行代码时,遇到if关键字,首先运算if括号中的表达式,当if中表达式的值为true时,就会执行if后面大括号中的语句。当if中表达式的值为false时,就会条多if后面大括号中的语句,继续执行大括号下面的其他语句。
【if判断语句第二种格式:】
if(条件表达式)
{
执行语句;
}
else
{
执行语句;
}
执行说明:当if条件表达式为true时,执行if后面大括号中的语句,当if条件表达式为false时,执行else后面大括号里面的语句。if-else格式,要么执行if后面的语句,要么执行else后面的语句。切记,else后面的语句要能够执行,if中的条件表达式结果必须为false。
三元运算符可以简化成if-else格式:
1 Eg:int a =4,b=5,max; 2 3 if(a>b) 4 { 5 max = a; 6 } 7 else 8 { 9 max = b; 10 }
可以使用三元运算简化为:max = a > b ? a: b;
三元运算符是简写的if-else格式,简写是有弊端的:三元运算符运算完必须要有结果,而if-else语句不一定有运算结果。
【if判断第三种格式:】
if(条件表达式)
{
执行语句;
}
else if (条件表达式)
{
执行语句;
}
……
else
{
执行语句;
}
if 练习:根据提供数值,输出对应的星期。
class IfTest
{
public static void main(String[] args)
{
//1,定义变量。记录数据。
int week = 9;
//2,通过判断结构语句if对该变量进行判断。
if(week == 1)
//3,根据不同的条件,通过输出语句显示不同的结果。
1 System.out.println(week+"对应的是星期一"); 2 3 else if(week == 2) 4 5 System.out.println(week+"对应的是星期二"); 6 7 else if(week == 3) 8 9 System.out.println(week+"对应的是星期三"); 10 11 else if(week == 4) 12 13 System.out.println(week+"对应的是星期四"); 14 15 else if(week == 5) 16 17 System.out.println(week+"对应的是星期五"); 18 19 else if(week == 6) 20 21 System.out.println(week+"对应的是星期六"); 22 23 else if(week == 7) 24 25 System.out.println(week+"对应的是星期日"); 26 27 else 28 29 System.out.println(week+"没有对应的星期"); 30 31 } 32 33 }
注意:条件表达式必须为boolean类型;if语句{}前加”;”,编译能通关,但不再做判断;当if控制的执行语句只有一行时,{}可以省略(if只控制离它最近的一条语句)
【键盘录入数据:】
键盘数据录入数据有三种:
1. main方法中的args字符串数组接受。
2. 使用IO流中的技术。
3. JDK5 以后的新的键盘录入。
使用Scanner类的方法
怎么使用:
a) 导包:import java.util.Scanner;
b) 创建对象:Scanner sc = new Scanner(System.in);
c) 使用: int num = sc.nextInt();// nextInt ();(方法)
【switch 多分支结构:】
格式:
switch(表达式)
{
case 取值1:
执行语句;
break;
case 取值2:
执行语句;
break;
…...
default:
执行语句;
break;
}
执行说明:当程序执行时,遇到switch关键字,首先会计算表达式的值,然后根据计算的值和case后面的值做比较,当case后面的值和switch表达式的值相同时,就执行case身后的所有语句,若case身后没有和switch表达式匹配的值,程序会执行default后面的语句。
注意:
switch语句选择的类型只有四种:byte,short,int,char(JDK5之前)。还支持enum(JDK5),String(JDK7)。
case 与 default 写法上没有先后顺序,执行上有顺序(先执行case,没匹配的才执行default)。
结束switch语句的两种情况:遇到break,执行到switch语句结束。
break:可以省略,但可能对结果造成影响,建议不省略。
如果匹配的case或者default没有对应的break,程序会继续向下执行,运行可以执行的语句,直到遇到break或者switch语句结束。
switch练习:
根据用户的给定的数值,显示该数值对应的星期。如:2,星期二。
1 class SwitchTest { 2 public static void main(String[] args) { 3 int week = 9; 4 switch (week) { 5 case 1: 6 System.out.println(week + "对应的是星期一"); 7 break; 8 case 2: 9 System.out.println(week + "对应的是星期二"); 10 break; 11 case 3: 12 System.out.println(week + "对应的是星期三"); 13 break; 14 case 4: 15 System.out.println(week + "对应的是星期四"); 16 break; 17 case 5: 18 System.out.println(week + "对应的是星期五"); 19 break; 20 case 6: 21 System.out.println(week + "对应的是星期六"); 22 break; 23 case 7: 24 System.out.println(week + "对应的是星期日"); 25 break; 26 default: 27 System.out.println(week + "没有对应的星期"); 28 break; 29 } 30 } 31 }
if和switch的区别:
if可以用于判断数值,也可以判断区间,只要运算结果是boolean类型,都可以进行判断。
switch用于对固定的几个值,进行判断。判断的值的类型有限。
【循环结构(while&do-while)】
循环结构:根据程序的需求,可以将某些代码重复的操作,java中的循环结构有三种:
while:事先不需要知道循环执行多少次;
do-while:同上,只是至少要执行一次(先执行一次,后判断)
for:需要知道循环次数
【while 循环】
格式:
while(条件表达式)
{
执行语句;
}
执行顺序:当程序执行到while关键字,JVM首先会运算while后面的条件表达式,当条件表达式结果为true,就会执行while的执行语句,当执行完执行语句后,会又回到while的条件表达式再次判断,如果为true,就继续执行,知道条件表达式结果为false时,才会跳过循环继续往下执行。
Eg:
int i = 1;
while( i < 10 )
{
System.out.println("i"+i);
i++; // 让i不断的更新,最后使循环可以结束
}
System.out.println("over");
while 练习:
需求:运算1-10的和。(累加思想)
思路:
1+2+3+4+...+10
每次加的和是确定的吗?不确定。需要变量记录和值。
每次和值需要加的下一个数是确定的吗?不确定,需要变量。
求和和+下一个数在重复,说明需要执行多次,用循环。
下一个数,是有规律的。自增。
步骤;
1,定义变量。一个记录和,一个记录下一个数。
2,需要循环结构。
3,循环中需要进行和+下一个数的运算。并让下一个数自增。
//1,定义变量。一个记录和,一个记录下一个数。
int i = 1;
int sum = 0;
//2,需要循环结构。
while(i<=10)
{
//3,循环中需要进行和+下一个数的运算。并让下一个数自增。
sum = sum + i;
i++;
}
System.out.println("sum="+sum);
注意:while循环的括号中的表达式记过必须为boolean类型的值;while循环的括号中不能直接写false常量;while循环的括号后面不能写分号,循环控制的语句的代码用大括号括起;while循环控制的条件变量一定要更新,保证循环能够正常结束。
【do-while 循环】
格式:
do {
执行语句;
}while(条件表达式);
执行顺序:先执行do句,后面的语句,当执行完后在进入条件表达式进行判断,若条件表达式结果为true继续执行do后面的语句,直到条件表达式结果为false,循环结束。
do-while 特点是无论条件是否满足,循环至少执行一次。
【for 循环】
格式:
for(初始化表达式;条件表达式;增量表达式)
{ 循环体; }
初始化表达式:定义对次数的起始变量;
条件表达式:用来限定循环次数;
增量表达式:对起始变量进行改变;
循环体:需要被执行的语句。
执行流程:
a) 首先看初始化表达式;
b) 接着看条件表达式,如果为true执行循环体;
如果为false结束循环;
c) 当循环体执行完毕,执行增量表达式;
d) 返回b,直到条件不满足。
注意:初始化表达式:只执行一次;条件表达式至少执行一次,增量表达式执行0次或多次。
【for循环嵌套】
所谓for循环嵌套就是for语句中还有for语句。
Eg:在控制台打印九九乘法表
1 class NineDemo { 2 public static void main(String[] args) { 3 for (int i = 1; i <= 9; i++)//外循环控制行数 4 { 5 //外循环执行一次,内循环执行一遍。 6 for (int j = 1; j <= i; j++)//内循环控制列数 7 { 8 System.out.print(j + "*" + i + "=" + i * j + "\t"); 9 } 10 System.out.println();//用作换行。 11 } 12 } 13 }
【for和while的区别(变量的生命周期不同)】
for(int x = 1; x<3; x++)
{
System.out.println("x="+x);
}
//System.out.println("x......"+x);
int y = 1;
while(y<3)
{
System.out.println("y="+y);
y++;
}
System.out.println("y....."+y);
while与for可以互换,区别在于for为了循环而定义的变量在for循环结束就在内存中释放。而while循环使用的变量在循环结束后还可以继续使用。
【无限循环最简单书写】
最简单无限循环格式:while(true){} , for(;;){},无限循环存在的原因是并不知道循环多少次,而是根据某些条件,来控制循环。
【流程控制:(continue,break)】
break: 终止该层循环;应用于循环语句和选择语句(switch)。
continue:跳出该层循环,继续下次循环;应用于循环结构。
注意:若这两个语句离开应用范围,存在是没有意义的。
②:这个两个语句单独存在,后面都不能有语句,因为执行不到。
③:continue语句是跳过本次循环,继续下次循环。
④:标签的出现,可以让这两个语句作用于指定的循环。
break语句、continue语句举例:
break是终止循环,即在程序中遇到break,那么break所属的循环将结束。
for (int x=0; x<3 ;x++ ){ if(x==1){ break; } System.out.println("x="+x); } // continue是结束本次循环,继续下次循环。循环是不会结束的。 for (int x=0; x<10 ;x++ ) { if(x%2==0) continue; System.out.println("x="+x); }
【使用循环标签】
在多层嵌套循环中,终止/跳过标签标记的那层循环的执行;break <标签> 或 continue <标签>;
outer:for (int x=0; x<3 ;x++ ) { inner:for (int y=0; y<4 ;y++ ) { System.out.println("x="+x); break outer; } }
|
outer:for (int x=0; x<3 ;x++ ) { inner:for (int y=0; y<4 ;y++ ) { System.out.println("x="+x); continue outer; } }
|
【水仙花问题】
所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。
例如:
153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
分析:
A:通过三位数,我们就知道了范围。(100-999)
通过for循环可以很容易的实现。
B:通过各位数字立方和等于该数本身,我们知道我们应该想办法获取每一个数据的个位,十位,百位。
那么,我们如何获取一个数据的个,十,百呢???
153
ge: 153%10 = 3
shi:153/10%10 = 5
bai:153/10/10%10 = 1
qian:x/10/10/10%10
wan:x/10/10/10/10%10
C:然后用该数字和 ge*ge*ge + shi*shi*shi + bai*bai*bai比较即可。
如果相等,说明该数就是满足条件的,然后就把该数据输出。
1 class FlowerDemo { 2 public static void main(String[] args) { 3 //用循环实现获取100-999 4 for (int x = 100; x < 1000; x++) { 5 6 int ge = x % 10; 7 8 int shi = x / 10 % 10; 9 10 int bai = x / 10 / 10 % 10; 11 if ((ge * ge * ge + shi * shi * shi + bai * bai * bai) == x) { 12 System.out.println(x); 13 } 14 } 15 } 16 }
【函数的概念】
函数:函数就是定义在类中的具有特定功能的独立小程序,并能被多次使用(函数也叫方法)。
形式参数:在函数被调用时用于接收外界输入的数据。
实际参数:调用函数时实际传给方法的数据。
返回值:函数在执行完毕后返还给调用它的语句的数据。
返回值类型:事先约定的返回值的数据类型,如无返回值,必须给出返回类型 void。
参数列表:函数的参数个数及参数的类型
函数(方法)签名:函数名 和 函数的参数列表(能区别函数);不能使用关键字和保留字,第一个单词的首字母小写,采用驼峰式;由有实际意义的动词或动词短语。
java语言中调用函数:对象名.函数名(实参列表)。
实参的数目、数据类型和次序必须和所调用函数声明的形参列表匹配。
return 语句终止函数的运行并指定要返回的数据。
【函数的定义格式】
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2......)
{
执行语句;
return 返回值;//return关键字是用于结束该功能。并将后面的具结果返回给调用者。
//必须有return语句。
}
注意:函数的返回值类型如果是void时,return语句可以省略不写return;void表示的是没有返回值的情况。
【如何定义函数】
函数就是一个功能,功能就需要两部分:
1、函数运行完的结果是什么;2、函数运行时有未知参数吗。
定义函数时,时刻把握如下两个明确,基本就可以完成函数的定义:
明确1:这个功能的结果是什么?其实就是明确返回值类型。
明确2:这个功能需要未知内容是什么? 其实就是明确参数列表。
【函数的执行过程】
以下代码的执行顺序
class MethodDemo
{
public static void main(String[] args)
{
int sum = getSum(3,4);
System.out.println("sum="+sum);
}
//定义功能求和
public static int getSum(int a , int b)
{
return a + b;
}
}
上面代码执行的内存图解如下:
图解说明:首先会加载main方法加载进栈内存中,并执行main方法中的代码,分别给a变量开辟空间并存放3,给b变量开辟空间存放4。当程序执行到int sum = getSum(a,b);时,会将getSum函数加载进栈内存中,同样在getSum所属的栈区域中开辟a和b变量空间,接受main方法中的getSum(a,b);传递的值。然后执行getSum函数中的代码,当getSum函数执行结束后,函数会出栈(弹栈)。程序回到main方法的调用语句int sum = getSum(a,b);处,并将getSum方法执行完返回的结果赋值给sum变量,程序继续往下执行。打印sum的值。
【函数的重载overload】
【重载的概念】
在同一个类中,允许存在一个以上的同名函数,只要它们的参数列表(参数个数或者参数类型)不同即可,这样就形成了重载。(重载与返回值类型无关)
【重载的练习】
void show(int a,float b,char c){}
下列哪些函数和给定函数重载了。
a.int show(int x,float y,char z) //没有重载,这个函数不允许和给定函数存在于同一个类 中。因为会产生调用的不确定性。
b.void show(float b,int a,char c) //重载了,参数类型不同。
c.void show(int c,float a,char b) //没有重载,和给定函数一样。不允许存在。
d.void show(int a,int b,int c) //重载了,因为类型不同。
e.double show() //重载了,因为个数不同。
【练习一下】
// 编程求:1+(1+2)+(1+2+3)+. . .+(1+2+3+. . .+100)
void addAdd(){
int sum=0;//总和
for(int i=1;i<=100;i++){
int tempSum=0;//临时和
for(int j=1;j<=i;j++){
tempSum+=j;
}
sum+=tempSum;
} 11
System.out.println(sum);
}
/**
* 编程求:1!+2!+3!+4!+. . .+15!
*/
private void addFactorial() {
long result=0;
for(int i=1;i<=15;i++){
int temp=1;
for(int j=1;j<=i;j++){
temp*=j;
}
result+=temp;
}
System.out.println(result);
}
}
【数组概述】
【数组的概念】
数组是同一种类型数据的集合;即能够存放多个相同类型的数据的容器。
【数组的定义方式】
数组是存放多个数据的容器,Java中需要使用new关键字来创建容器,在创建容器时也要明确容器的大小,即容器中存放数据个数。
Java中的数组必先初始化才可以使用,所谓初始化就是为数组的数组元素分配内存,并为每个数组元素赋值;
数组初始化的两种方式:
静态初始化:初始化时由我们自己指定每个数组元素的初始值,由系统决定需要的数组长度;
格式:元素类型[] 数组名 = new 数组类型[]{元素1,元素2,元素3...元素n};
简化语法:元素类型[] 数组名 = {元素1,元素2,元素3...元素n};
动态初始化:初始化时由我们指定数组的长度,由系统为数组元素分配初始值;
格式:元素类型[] 数组名 = new 数组类型[数组长度];
动态初始化有默认初始化值。
不能静态和动态初始化同时使用:
也就是说不能同时指定数组的长度和元素;
数组的长度一旦确定,就不能改变,也就数组是定长的;
【数组的好处】
数组可以存储多个数据,而且可以对数据进行编号,从0开始。操作元素完成可以通过编号(索引)完成。
int[] arr = new int[3];
arr[0] = 3; //给数组编号(角标)为0的空间中存放int类型的常量值3
System.out.println(arr[1]);//输出数组编号为1空间中的值。
【数组内存图解】
【Java的内存分配】
Java对内存空间的划分:五部分:栈,堆,方法区,本地方法区,寄存器。
栈内存:存储都是局部变量。只要是在方法中定义的变量都是局部变量。一旦变量的生命周期结束该变量就被自动释放。(先进后出,压栈→弹栈)
堆内存:存储都是实体(数组或对象),每一个实体都有一个首地址值。堆内存的变量都有默认初始化值。不同类型不一样。int-0; double-0.0; boolean-false; char-‘\u0000‘(空字符),String(所有引用类型null)。当实体不在使用时,就会被垃圾回收机制处理。
【数组的内存分配】
int[] arr = new int[3];
arr = null;
图解说明:程序执行main方法时,会先在堆内存中开辟数组空间,并为其分配内存地址0x34(假设)。数组各个空间都有默认的编号(角标或索引),接着给数组各个存储空间默认初始化为0。到底数组创建结束,将数组的内存地址赋值给main方法的数组引用变量arr。程序继续执行,将arr引用变量赋值为null,即arr不再指向堆中的数组实体。这时这个数组实体将会编程垃圾,等待垃圾回收机制收走。
【数组的常见问题】
数组角标越界异常
ArrayIndexOutOfBoundsException:访问到了数组不存在的索引时,会发生该异常。
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = new int[3];
System.out.println(arr[3]); //访问到了数组中不存在的角标,会发生异常
}
}
空指针异常
NullPointerException:当使用没有任何实体指向的引用变量操作实体时,运行会发生该异常。
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = new int[3];
arr = null; // arr引用变量不再执行任何数组实体
System.out.println(arr[3]); //使用不再指向任何实体的引用变量,会发生空指针异常
}
}
【数组的应用(遍历、求和、最值)】
【遍历数组】
当需要操作数组的每个空间时,需要从角标0为开始,一直操作到数组最后一个空间,发现数组的角标在有规律的递增。可以使用循环提供数组角标。
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = {12,21,18,11,15};
for (int i=0;i<5 ;i++ )
{
System.out.println("arr["+i+"]="+arr[i]);
}
}
}
数组中的数据如果较多时,不可能去数数组中到底有多少个元素,具体需要循环多少次。数组这个实体对象有一个属性length,这个属性中记录当前引用所属数组实体中具体有都少个元素。
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = {12,21,18,11,15};
System.out.println("数组中元素个数:"+arr.length);
for (int i=0;i<arr.length ;i++ )
{
System.out.println("arr["+i+"]="+arr[i]);
}
}
}
运行结果:
数组中元素个数:5
arr[0]=12
arr[1]=21
arr[2]=18
arr[3]=11
arr[4]=15
【数组求和】
需求:求数组中所有元素的和
思路:
1、需要定义个功能,用来求数组中所有元素的和值。
2、定义功能,必须搞清楚两个明确:
明确1:有返回结果,即所求的和值,和值类型int。
明确2:有未知参数参与。求数组和,数组需要调用者传递给此功能。
步骤:
1、定义变量记录和。
2、 通过循环对数组进行遍历。
class ArrayTest
{
public static void main(String[] args)
{
int[] arr = {23,14,22,88,45,90,17};
int sum = add(arr);
System.out.println("sum="+sum);
}
public static int add(int[] arr)
{
//1,定义变量记录和。
int sum = 0;
//2,通过循环对数组进行遍历。
for(int x=0; x<arr.length; x++)
{
sum = sum + arr[x];
}
return sum;
}
}
【数组求最值】
需求:获取多个整数中最大值。
思路:
1,数据多了为了便于操作,先存储起来。需要容器。用数组。
2,多个数据需要进行比较。每次都有较大的数,需要记录下来和下一个数比较。
3,将数组中的元素都比一遍。最后,就有了最大值。
步骤:
1,需要数组。
2,定义一个变量记录住较大的数。
3,对数组进行遍历。让元素和较大的值进行比较。
如果元素大于较大的数,用变量记录该元素。
4,遍历完成后,变量中记录就是最大值。
class ArrayTest2
{
public static void main(String[] args)
{
int[] arr = {23,15,67,25,90,33};
int max = getMax(arr);
System.out.println("max="+max);
}
//定义功能。
/*
明确1:结果?int
明确2:参数?int[]
*/
public static int getMax(int[] arr)
{
//1,定义变量。初始化为数组中的任意一个元素。
int max = arr[0];
//2,遍历数组。
for(int x=1; x<arr.length; x++)
{
//遍历的元素只要比max大,就用max记录下来。遍历到最后max中记录就是最大值。
if(arr[x]>max)
max = arr[x];
}
return max;
}
//第二种方式获取最值
public static int getMax_2(int[] arr)
{
int max = 0;//初始化为数组中的任意一个角标。
for(int x=1; x<arr.length; x++)
{
if(arr[x]>arr[max])
max = x;
}
return arr[max];
}
}
【目标:数组排序】
如何让数组中的值变的有序呢,比如从小到大,或者从大到小的排列。回想下上体育课时老师让大家从低到高站队,是怎么做到呢?
1、选择排序
选择排序是排序中的一种。算法原则(从小到大排序):先用数组中第一个空间值和数组中剩余的其他空间值一一做比较,在比较的过程有任何值比第一个空间值小,就用第一个空间值和当前这个空间值换位置,直到所有值和第一个空间值全部比较完。第一个空间中就放着最小值。接着在使用数组第二个空间值和数组中剩下空间中值做比较,比较方式和前一次相同。以此类推,比较完成。
规律:第一个空间和剩余空间比一圈,第二个空间在和剩余空间比一圈,以此类推,到倒数第二个空间值和最后一个空间值比完,整个数组有有序了。正好符合了外循环循环一次,内循环执行一圈。即外循环控制每次到底使用那个空间值和剩余空间比较,内循环提供剩余空间。
图解:
代码演示:
public static void selectSort(int[] arr)
{
for(int x=0 ;x<arr.length-1; x++) //提供比较的空间角标
{
for(int y=x+1; y<arr.length; y++) //提供剩余空间的角标
{
if(arr[x]>arr[y]) //判断当前外循环角标位置上的值和内循环角标位置上的值
{
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
2、冒泡排序
冒泡排序算法原理:这种算法和生活中常见的水中气泡的浮沉类似。
数组冒泡算法(从小到大):
第一轮:数字第一个空间值和第二个空间值比较,把较大的值存在第二个空间中,接着第二个空间值和第三个空间值作比较,较大的值存在第三个空间中,以此类推直到倒数第二个空间和倒数第一个空间比较,把较大值存放在最后一个空间中。
第二轮:由于最后一个空间已经是最大值了,那么第二轮算法和第一轮一样,只是最后一次比较是倒数第三个空间和倒数第二个空间比较。把较大的值存在倒数第二个空间中。
以此类推。
图解:
代码演示:
/*
冒泡排序。
*/
public static void bubbleSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=0; y<arr.length-1-x; y++)
{
if(arr[y]>arr[y+1])
{
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
【目标:数组查找】
1、一般查找
从组中第一个空间开始查找,每取出一个空间值和待查找的数值做比较,若相等,就返回当前角标,若数组遍历结束,没有找到相等的值,则返回-1.
public static int searchKey(int[] arr,int key)
{
//遍历查找。
for(int x=0; x<arr.length; x++)
{
if(arr[x]==key)
return x;
}
return -1;//-1,代表的是角标不存在的情况。
}
2、折半查找
折半查找,必须保证数组已经是有序的。
思路:
1,通过角标先获取中间角标上元素。
2,让该元素和要找的数据比较。
3,如果要找的数大了,缩小范围,要找的范围应该是 中间的角标+1---尾角标。
如果要找的数小了,要找的范围 头角标---中间角标-1;
4,不断如此重复,就可以找到元素对应的角标。
public static int binarySearch(int[] arr,int key)
{
//1,定义三个变量,记录头角标,尾角标,中间角标。
int max,min,mid;
min = 0;
max = arr.length-1;
mid = (max+min)>>1;
while(arr[mid]!=key)
{
if(key>arr[mid])
min = mid + 1;
else if(key<arr[mid])
max = mid - 1;
//判断元素是否存在。
if(max<min)
return -1;
mid = (max+min)>>1;
}
return mid;
}
【学习效果】
掌握数组的折半查找原理。代码体现。
【第五阶段】
【目标:二维数组定义】
二维数组,其实就是一个数组中又装了一个数组。
1、二维数组定义
int[][] arr = new int[3][2];
定义了名称为arr的二维数组, 二维数组中有3个一维数组,每一个一维数组中有2个元素, 一维数组的名称分别为arr[0], arr[1], arr[2]。
二维数组赋值:arr[1][1] = 78;
System.out.println(arr);// [[I@e6f7d2//二维数组实体。
System.out.println(arr[0]);//[I@3e0ebb//一维数组实体。
System.out.println(arr[0][0]);//0 一维数组中的元素。
2、二维数组内存图解:
3、二维数组的其他定义格式:
int[][] arr = new int[3][];
二维数组中有3个一维数组,每个一维数组都是默认初始化值null,可以对这个三个一维数组分别进行初始化。
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};
定义一个名称为arr的二维数组,二维数组中的有三个一维数组,每一个一维数组中具体元素也都已初始化。
第一个一维数组 arr[0] = {3,8,2};
第二个一维数组 arr[1] = {2,7};
第三个一维数组 arr[2] = {9,0,1,6};
第三个一维数组的长度表示方式:arr[2].length;
【第六阶段】
【目标:二维数组的应用】
需求:二维数组求和
class Array2Demo
{
public static void main(String[] args)
{
int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};
int sum = getSum(arr);
System.out.println("sum="+sum);
}
// 求二位数组的和值
public static int getSum(int[][] arr)
{
int sum = 0;
for (int i=0;i<arr.length ;i++ )
{
for (int j=0;j<arr[i].length ;j++ )
{
sum += arr[i][j];
}
}
return sum;
}
}
二 Java基础