1.标识符:java对各种变量、方法和类等要素命名时使用的序列成为标识符。
凡是自己可以起名字的地方都叫标识符,都遵守标识符的规则。
标识符的命名规则:(这些不用记,注意一下就行)
1)标识符由字母、下划线“_”,美元符”$”或数字组成。
2)标识符应以字母,下划线,美元符开头。
3)java标识符大小写敏感(指带小写含义不同,A是A,a就是a,两者不能代替),长度无限制。
4)应见名知意且不能与java语言的关键字重名。
合法的标识符 | 不合法标识符 |
HelloWorld | Hell Word |
Car | Car* |
_96 | 9.6 |
$yh_00 | #67 |
2.关键字:java中一些赋予特定的含义,用作专门用途的字符串成为关键字(大多数编辑器会将关键字用特殊方式标出)。
java中所有的关键字都是小写英文,goto和const虽然未使用,但也作为Java 的保留字。
break |
||||
case |
const | |||
continue |
default |
do |
double |
else |
enum |
extends |
final |
finally |
float |
for |
goto |
if |
implements |
import |
instanceof |
int |
interface |
long | native |
new |
package |
private |
protected |
public |
return |
strictfp |
short |
static |
super |
switch |
synchronized |
this |
throw |
throws |
transient |
try |
void |
volatile |
while |
true | false | null |
3.java的常量:java的常量值用字符串表示,区分为不同的数据类型。
如:
整型常量(整数)123
实型常量(实数,带小数点的)3.14
字符常量(在计算机里也是一个数字来表示的,如ascII码)’a’
逻辑常量true、false
字符串常量“abc”
注意:1)区分字符常量和字符串常量。
2)“常量”这个名词还会用在另外其他语境中表示值不可变的变量,如final修饰的。
4.java变量:java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
(1)java程序中每一个变量都属于特定的类型,在使用前必须对其声明,
声明格式为:type varName[=value][{varName}[=value]](这种东西不用记,记住例子就可以了)
例如:
int i=100;
double a,b,c=0.123;
String str=“abc”;
从本质上讲,变量其实是内存中的一小块区域,使用变量来访问这块区域,因此,每一个变量使用前必须要先申请(声明),再赋值,才能使用。
程序的执行过程:heap主要作用就是动态分配内存。
(2)java的变量分类
1)按声明位置划分
局部变量:方法或语句块内部定义的变量。
成员变量:方法外部、类的内部定义的变量
注意:类外面(与类对应的大括号外面)不能有变量的声明。
例子1:
//类外不能声明变量
public class HelloWorld{
//成员变量(注意没有像c++一样有什么全局变量),作用域在这整个类中
int a=200;
//args,方法参数也属于局部变量
public static void main(String[] args) {
//局部变量,作用域在main方法里,出了main后的大括号就没人认识它了
int i=100;
System.out.println("HelloWord");
}
}
2)按所属的数据类型划分。
基本数据类型变量
引用数据类型变量
(1)boolean类型适用于逻辑运算,一般用于程序流程控制。boolean类型数据只允许取值true或false,不可以0或非0的整数代替true和false,这点与C语言不同。
//用法举例
boolean flag;
flag=true;
if(flag){
//do something
}
(2)char型数据用来表示通常意义上“字符”。
字符常量为用单引号括起来的单个字符,例如:
char e=’a’;
char e=’中’;
java字符采用Unicode编码,每个字符占两个字节(1个字节占8位,数据在计算机底层存储,用0101表示,每一个0,1都叫一个位(byte)),因而可用十六进制编码形式表示。例如:
char c1=’\u0061′;(在内存中应是01100001,\u指的是后面4位数是十六进制的Unicode编码)
注:Unicode编码是全球语言统一编码。
java语言中还允许使用转义字符‘\’来将其后的字符转变为其它的含义,例如:
char c2=’\n’;
补充:二进制、十进制、十六进制之间的转换
例子
1101——1*1+0*2+1*4+1*8
13——1+4+8 ——1101
1101——D (1,2,3,4,5,6,7,8,9,A(10),B(11),C(12),D(13),E(14),F(15))
(3)整数类型(java里面所有的数都是带符号的)
java各整数类型有固定的表数范围和字段长度,其不受具体操作系统(windows,linux,mac…)的影响,以保证java程序的可移植性。
java语言整型常量的三种表示形式:
1)十进制整数,如:12,-31,0
2)八进制整数,要求以0开头,如:012(因0开头,010就不确定是什么进制表示的了,为了避免混淆不建议用八进制)
3)十六进制数,要求Ox或OX开头,如:OX12
注意:不管是什么进制在计算机中都是以二进制表示,所以不管是十进制,八进制,十六进制来表示,只要是表示的同一个数它在计算机中的存储都是一样的。
java语言的整型常量默认为int型,声明long型常量可以加l或L(我建议加L好区分)
类型 | 占用存储空间 | 表数范围 |
byte | 1字节 | -128~127(-2^7~2^7-1) |
short | 2字节 | -2^15~2^15-1 |
int | 4字节 | -2^31~2^31-1 |
long | 8字节 | -2^63~2^63-1 |
(4)浮点类型:java浮点类型有固定的表数范围和字段长度,不受平台影响。
java浮点型常量有两种表示形式
1.十进制数形式,例如:3.14 41.0 .314
2.科学计数法形式,如3.14e2 3.14E2 100E-2
java浮点型常量默认为double,如果声明一个常量为float,则需在数字后面加f或F,如:
double d=123.4; float f=12.3f;//不加f则出错,f必须加
类型 | 占用存储空间 | 表数范围 |
float | 4字节 | -3.403E38~3.403E38(小数点后有效位数7位) |
double | 8字节 | -1.798E308~1.798E308(小数点后有效位数15位) |
注意:浮点数在计算机中表示是离散的,有误差,在有效位数(精度)之后就不精确了,浮点数值不适用于禁止出现舍入误差的金融计算中。如果需要在数值计算中不含有任何舍入误差,就应该用BigDecimal类。
5.数据类型转换
boolean类型不可以转换为其它的数据类型。
整型,字符型,浮点型的数据在混合运算中相互转换,转换时遵循一下原则:
注:实箭头表示无信息丢失的转换;虚箭头,表示可能有精度的丢失。
1)容量小的类型自动转换为容量大的数据类型;数据类型按容量大小(指表示数的大小)排序为:
byte,short,char->int->long->float->double
2)容量大的数据类型转换为容量小的数据类型时,要加上强制转换符,但可能造成精度降低或溢出,使用时要注意。
比如double类型(8)强制转换成float类型(4)就很容易溢出。
int强转byte,可以砍掉,没有影响,内部格式没问题。而double强转为float则不能砍掉,因为带有小数,内部格式会出问题,这也是float后面必须加f的原因。
3)有多种类型数据混合运算时,系统首先自动的将所有数据转换成容量最大的那一种数据类型,然后再计算。
6.程序格式
目的:要别人看的更清楚,让别人看这个更舒服就可以。
格式应该注意的问题:(若用ide则不用考虑,一般ide都有格式调整的功能)
1)大括号对齐
2)遇到{缩进,Tab/Shift+Tab
3)程序块之间加空行
4)并排语句之间加空格
5)运算符两侧加空格
6){前面有空格
7)成对编程
例子:
import test.Student;
import java.util.ArrayList;
import java.util.List;
import java.util.Comparator;
import java.util.Collections;
/**
* 说明:
*
* @author huayu
* @date 2018/7/30 下午4:31
*/
public class Test1 {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();
list.add(new Student("Hao LUO", 33));
list.add(new Student("XJ WANG", 32));
list.add(new Student("Bruce LEE", 60));
list.add(new Student("Bob YANG", 22));
/*通过 sort 方法的第二个参数传入一个 Comparator 接口对象
相当于是传入一个比较对象大小的算法到 sort 方法中
由于 Java 中没有函数指针、仿函数、委托这样的概念
因此要将一个算法传入一个方法中唯一的选择就是通过接口回调
*/
Collections.sort(list, new Comparator<Student>() {
// @Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (Student stu : list) {
System.out.println(stu);
}
}
}
7.运算符
(1)java语言支持的运算符
分类 | 运算符 |
算数运算符 | +,-,*,/,%(取余),++,– |
关系运算符 | >,<,>=,,<=,==,!= |
逻辑运算符 | !(非),&(与),|(或),^(异或),&&(短与),||(短路或) |
位运算符 | &,|,^,~,>>,<<,>>> |
赋值运算符 | = |
扩展赋值运算符 | +=,-=,*=,/= |
字符串连接运算符 | + |
注意:
1)自增和自减运算符:++(–)在前时先运算再取值,在后时先取值再运算。
2)逻辑运算符
a^b:相异为true
&(&&):同真为真 ,短路与(&&)只要第一个为false,第二个操作数就不算了。 |(||):同假为假,短路或运算(||)同短路与(&&)
a | b | !a | a&b | a|b | a^b | a&&b | a||b |
true | true | false | true | true | false | true | true |
true | false | false | false | true | true | false | true |
false | true | true | false | true | true | false | true |
false | false | true | false | false | false | false | false |
3)赋值运算符与扩展赋值运算符
赋值运算符
当“=”两侧数据类型不一致时,可以使用默认类型转换和强制转换原则进行处理。
注意:可以将整型常量直接赋值为byte,short,char等类型,而不需要进行强制类型转换,只要不超出表数范围就可以。
扩展赋值运算符
运算符 | 用法举例 | 等效的表达式 |
+= | a+=b | a=a+b |
-= | a-=b | a=a-b |
*= | a*=b | a=a*b |
/= | a/=b | a=a/b |
%= | a%=b | a=a%b |
4)字符串连接符(+)
“+”运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接。
举例
String str=1+”2″;
System.out.println(str);//12
注意:当进行打印时,无论任何类型,都自动转为字符串进行打印。
5)三目运算符
语法格式:x?y:z
其中x为boolean类型表达式,先计算x的值,若true,则整个三目运算的结果为y的值,否则整个运算结果为表达式z的值。
(简单说,若x判断为true,值就是y;若x判断为false,值就是z)
(2)表达式:是符合一定语法规则的运算符和操作数的序列(最后能算出一个值来)
举例:a
a+5.0
(a+b)*c-1
i<22&&i%10!=0
表达式的类型和值:
1)对表达式中的操作数进行运算得到的结果成为表达式的值。
2)表达式值和数据类型即为表达式的类型。
表达式的运算顺序
应按照运算符的优先级从高到低的顺序进行。
优先级相同的运算符按照实现约定的结合方向进行。
1)运算符优先级(下表不用记,最实用的方法就算你不知道你就加括号就行,这方法比什么都稳妥)
运算符 | 结合性 |
[] . () (方法调用) | 从左向右 |
! ~ ++ — +(一元运算) – (一元运算)() (强制类型转换)new | 从右向左 |
* / % | 从左向右 |
+ – | 从左向右 |
<< >> >>> | 从左向右 |
< <= > >= instanceof | 从左向右 |
== != | 从左向右 |
& | 从左向右 |
^ | 从左向右 |
| | 从左向右 |
&& | 从左向右 |
|| | 从左向右 |
?: | 从右向左 |
= += -= *= /= %= &= |= ^= <<= >>= >>>= | 从右向左 |
8.语句
(1)条件语句:根据不同条件,执行不同语句
1)if
2)if …else
3)if … else if
4)if … else if… else if… else
import java.util.Scanner;
/**
* 说明:
*
* @author huayu
* @date 2018/8/1 下午3:17
*/
public class IfTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
if (a == 1) {
System.out.println("a");
} else if (a == 2) {
System.out.println("b");
} else if (a == 3) {
System.out.println("c");
} else {
System.out.println("d");
}
}
}
if语句只有一句需要执行的语句时,可以省略{},但是我建议大家都写上,其实不写如果用ide的话它也会提醒你缺少大括号。
5)switch
(2)循环语句:重复执行某些动作
1)for循环
语句格式 :for(表达式1:表达式2:表达式3){语句;…;}
执行过程:首先计算表达式1,接着执行表达式2,若表达式2的值为true,则执行语句,接着计算表达式3,再判断表达式2的值,依次重复下去,直到表达式2的值为false结束。
for语句中的三个表达式都可以省略(jdk5开始)。
/**
* 说明:for循环使用举例
*
* @author huayu
* @date 2018/8/1 下午3:33
*/
public class ForTest {
public static void main(String[] args) {
int count=0;//局部变量
int sum=0;
for (int i = 0; i <100 ; i++) {
sum+=i;
count++;
System.out.println("i="+i+'\n'+"count="+count+"次");
}
System.out.println("sum="+sum);
}
}
2)while
while语句形式:while(逻辑表达式){语句;….;}
执行过程:先判断逻辑表达式的值,若为true则执行其后面的语句,然后再次判断条件并反复执行,直到条件不成立为止。
public class WhileTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数");
int a = scanner.nextInt();
while (a < 10) {
a++;
System.out.println("a=" + a);
}
}
}
3)do…while(用的较少)
语句形式:do{语句;…;}while(逻辑表达式);
执行过程:先执行语句,再判断逻辑表达式的值,若为true,再执行语句,否则结束循环。
4)break&Continue语句
break语句用于终止某个语句块的执行。用在循环语句体中,可以强行推出循环。
public class BreakTest {
public static void main(String[] args) {
int stop = 5;
for (int i = 0; i < 10; i++) {
if (i == stop) {
break;
}
System.out.println("i="+i);
}
}
}
结果:
i=0
i=1
i=2
i=3
i=4
/**
* 说明:输出1~100内前5个可以被3整除的数
*
* @author huayu
* @date 2018/8/1 下午4:14
*/
public class BreakTest {
public static void main(String[] args) {
int num=0,i=1;
while (i<=100){
if(i%3==0){
System.out.println(i+" ");
num++;
}
if(num==5){
break;
}
i++;
}
}
}
continue语句用在循环语句体中,用于终止某次循环过程,跳过循环体中continue语句下面未执行的循环,开始下一次循环。
public class ContinueTest {
public static void main(String[] args) {
int skip = 5;
for (int i = 0; i < 10; i++) {
if (i == skip) {
continue;
}
System.out.println("i="+i);
}
}
}
结果:
i=0
i=1
i=2
i=3
i=4
i=6
i=7
i=8
i=9
/**
* 说明:输出101~200内的质数
*质数又称素数。一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数;
* @author huayu
* @date 2018/8/1 下午4:21
*/
public class ContinueTest {
public static void main(String[] args) {
//只算奇数就可以,偶数肯定不是质数
for (int i = 101; i < 200; i+=2) {
//置个标记,首先默认是质数
boolean flag=true;
//如果进入这层for循环flag被置为false,则表示不是质数,那么就跳出内层循环不执行了
for (int j = 2; j < i; j++) {
if(i%j==0){
flag=false;
break;
}
}
//筛选,如果不是质数,也就是flag是false就跳过外层这一次循环,继续下一次循环
if(!flag){
continue;
}
//如果是质数则能走到这一步,输出出来
System.out.println(" "+i);
}
}
}
5)switch语句
语句形式:switch(choice){
case xx:
….
break;
case xx:
….
break;
default:
….
break;
}
注意:小心case穿透,推荐末尾使用break语句(关于case穿透,你将下面例子中第一个break去掉,输出看看会出现什么情 况)。
多个case可以合并到一起。
default可以省略,但不推荐省略。
choice(switch的语句中探测):java 1.6(包括)以前,只是支持等价成int 基本类型的数据:byte ,short,char,int,也可以是枚举常量,1.7加入的新特性可以支持String类型的数据。long是不可以的。。就算是通过强制的转化也必须是转成int。short、 char 或者 byte他会自动转换为int的。。long不能自动转换为int..因为long比int范围大..可能会丢失精度..
//switch例子
public class SwitchTest {
public static void main(String[] args) {
int a=1;
switch (a){
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
case 3:
System.out.println("3");
break;
default:
System.out.println("error");
}
}
}
结果:
1
9.方法:java的方法类似于其它语言的函数,是一段用来完成特定功能的片段(方法的本质是增强程序的复用性)。
声明格式:
[修饰符1 修饰符2…..] 返回值类型 方法名(形式参数列表){
java语句;
….
}
1)几个名词:
形式参数:调用方法时用于接受外界输入的数据。
实参:调用方法时实际传给方法的数据。
返回值:方法在执行完毕后返还给调用它的环境的数据。
返回值类型:事先约定的返回值的数据类型,如无返回值,必须给出返回值类型void。
2)方法调用(一般在代码区,方法执行起来才会占用内存)
java语言中调用方法:对象名.方法名(实参列表)
实参的数目、数据类型和次序必须和所调用方法声明的形参列表匹配。
return语句终止方法的运行并指定要返回的数据。
参数传递原则
java中进行函数调用中传递参数时,遵循值传递原则。
基本类型传递的是该数据值本身。引用类型传递的是对对象的引用,而不是对象本身。
//方法调用实例
public class Function {
public static void main(String[] args) {
int a=f1(1);
f2();
System.out.println(a);
}
public static int f1(int a){
int b=1+a;
return b;
}
public static void f2(){
System.out.println("空值");
}
}
结果:
空值
2
10.递归与非递归
(1)递归
递归调用:在一个方法内部对自身进行调用。注意,没有分支。
重要!!!:用递归编写程序时一定要牢记两点:1. 递归公式;2. 收敛条件
public class Test {
public static void main(String[] args) {
System.out.println(method(5));
}
public static int method(int n) {
if (n == 1) {
return 1;
} else {
return n * method(n - 1);
}
}
}
程序分析:
n=5 return 5*method(5-1)
n=4 return 5*4*method(4-1)
n=3 return 5*4*3*method(3-1)
n=2 return 5*4*3*2*method(2-1)
n=1 return 5*4*3*2*1
结果
120
以上方法递归调用过程
递归实现斐波那契数列
斐波那契数列指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
这个数列从第三项开始,每一项都等于前两项之和。
public class Feb {
public static void main(String[] args) {
System.out.println(fibonacci(5));
}
public static int fibonacci(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci(n - 1)+fibonacci(n - 2);
}
}
}
过程分析:
n = 5 return fibonacci(4)+fibonacci(3);
n = 4,n = 3 return fibonacci(3)+fibonacci(2);
n = 3,n = 2 return fibonacci(2)+fibonacci(1);
n = 2 return 1;
n = 1 return 1;
//如果这样再看不清楚代价就一步一步拆开或者将程序打debugger跑一下
n = 5 return fibonacci(4)+fibonacci(3);
n = 5 return fibonacci(3)+fibonacci(2)+fibonacci(3);
n = 5 return fibonacci(2)+fibonacci(1)+fibonacci(2)+fibonacci(2)+fibonacci(1));
结果
5
以上方法递归调用过程
(2)非递归
非递归实现斐波那契数列(for循环)
//没考虑健壮性,只考虑了算法的实现,如果是实际应用应考虑健壮性,比如不让人传不符合条件的值
public class Feb {
public static void main(String[] args) {
System.out.println(f(5));
}
public static long f(int index){
if(index==1||index==2){
return 1;
}
long f1=1L;
long f2=1L;
long f=0;
for (int i = 0; i <index-2; i++) {
f=f1+f2;
f1=f2;
f2=f;
}
return f;
}
}