视频笔记看尚硅谷老师整理的
基本语法
关键字
- 被java语言赋予了含义,用做专门用途的字符串(单词)
- 关键字中所有字母都为小写
保留字
goto const 尚未使用的,以后可能会用,但不一定用
标识符
- Static可以通过,因为java严格区分大小写
- 如果不遵守如上规则,编译不通过,需要大家严格遵守
标识符的命名规范(不遵守可以通过,但是建议遵守)
- 包名:多单词组成时所有字母都小写:xxxyyyzzz
- 类名 接口名:多单词组成时,所有单词首字母大写XxxYyyZzz
- 变量名 方法名:多单词组成时:第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
- 常量名:所有字母都大写,多单词时每个单词用下划线连接XXX_YYY_ZZZ
- 起名建议 :见名知意
- java采用unicode字符集,因此标识符也可以使用汉字声明,但是不建议使用
变量
- 内存中的一个存储区域
- 该区域的数据可以在同一个类型范围内不断变化
- 变量是程序中最基本的存储单元,包含变量类型,变量名和存储的值
-
说明:
- 变量必须先声明,后使用
- 变量都定义在其作用域内,在作用域内他是有效的,出来作用域,就无效了
- 同一个作用域内不可以声明两个同名变量
-
注意:变量在方法内部赋值才可以使用
- 总结:如果变量是成员变量那么虚拟机会自动给赋默认值,可以被直接使用
如果是局部变量,系统不会给赋默认值,不能直接使用,需要手动赋值才可以使用
public class DD {
private int a;
private double b;
private boolean c;
private String d;
public void eat(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
public class A {
public static void main(String[] args) {
DD dd = new DD();
dd.eat();
}
}
结果是:
0
0.0
false
null
变量的分类
一.变量按照类型来分:
基本数据类型
1.整形:byte \ short \ int \long
注意:声明long行变量,必须以l或L结尾
2.浮点型: float \ double
public class A {
public static void main(String[] args) {
double d1=123.3;
System.out.println(d1+1);
//long声明时候后面必须加l或者大L,数值小的时候不加不会报错(int自动提升为long),数值大了那么就会报错.
long c=12;
System.out.println(c);
//long d=12123131241544;报错
long a=12123132413654l;
System.out.println(a);
//定义float变量的时候是,变量要以'f' 或'F'结尾,否则报错,因为12.3没加情况会默认是double
float f1=12.3F;
System.out.println(f1+1);
}
}
运行结果
124.3
12
12123132413654
13.3
通常,定义浮点型变量时,一般使用double型
3.字符型: char
-
一个字符=2字节
public class A { public static void main(String[] args) { //一个字符=2字节 //定义char变量,通常使用一对'' 内部只能写一个字符 char c1='a'; char c2='1'; char c3='中'; System.out.println(c1); System.out.println(c2); System.out.println(c3); //2.转义字符 System.out.println("===222===="); char c4='\n'; System.out.print("hello"); System.out.println("world"); System.out.print("hello"+c4); System.out.println("world"); c4='\t'; System.out.print("hello"+c4); System.out.println("world"); //3.直接使用Unicode值 System.out.println("===333===="); char c5='\u0123'; //找到对应的值 System.out.println(c5); c5='\u0043'; System.out.println(c5); } }
运行结果
a 1 中 ===222==== helloworld hello world hello world ===333==== ģ C Process finished with exit code 0
补充一些知识(来自知乎):
作者:盛世唐朝
链接:https://www.zhihu.com/question/23374078/answer/69732605
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。链接:https://www.zhihu.com/question/23374078/answer/69732605
正在这时,大天使加百列及时出现了——一个叫 ISO(国际标谁化组织)的国际组织决定着手解决这个问题。他们采用的方法很简单:废了所有的地区性编码方案,重新搞一个包括了地球上所有文化、所有字母和符号 的编码!他们打算叫它”Universal Multiple-Octet Coded Character Set”,简称 UCS, 俗称 “unicode“。
unicode开始制订时,计算机的存储器容量极大地发展了,空间再也不成为问题了。于是 ISO
就直接规定必须用两个字节,也就是16位来统一表示所有的字符,对于ASCII里的那些“半角”字符,unicode包持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他文化和语言的字符则全部重新统一编码。由于”半角”英文符号只需要用到低8位,所以其高8位永远是0,因此这种大气的方案在保存英文文本时会多浪费一倍的空间。这时候,从旧社会里走过来的程序员开始发现一个奇怪的现象:他们的 strlen 函数靠不住了,一个汉字不再是相当于两个字符了,而是一个!是的,从unicode开始,无论是半角的英文字母,还是全角的汉字,它们都是统一的”一个字符“!同时,也都是统一的”两个字节“,请注意”字符”和”字节”两个术语的不同,“字节”是一个8位的物理存贮单元,而“字符”则是一个文化相关的符号。在unicode中,一个字符就是两个字节。一个汉字算两个英文字符的时代已经快过去了。
unicode同样也不完美,这里就有两个的问题,一个是,如何才能区别unicode和ascii?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储空间来说是极大的浪费,文本文件的大小会因此大出二三倍,这是难以接受的。
unicode在很长一段时间内无法推广,直到互联网的出现,为解决unicode如何在网络上传输的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。UTF-8就是在互联网上使用最广的一种unicode的实现方式,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分,注意的是unicode一个中文字符占2个字节,而UTF-8一个中文字符占3个字节)。从unicode到utf-8并不是直接的对应,而是要过一些算法和规则来转换。
防止乱码就要实现保存的字符类型和编码用的类型一样
乱码
- 布尔型:boolean
public class R0416 {
public static void main(String[] args) {
//布尔只能取两个值之一 true false
// boolean b=2; 报错
boolean b=true;
System.out.println(b); //true
// System.out.println(b==1); //报错:java: 不可比较的类型: boolean和int
// System.out.println(b+1); //报错: 二元运算符 '+' 的操作数类型错误
}
}
引用数据类型
- 类(class):
- 接口(interface)
- 数组(array)
二 .变量在类中声明的位置:
成员变量 vs 局部变量
类型运算
自动类型提升运算
结论:当容量小的数据类型变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型
byte、short、int -->float–>double(注意运算的时候千万要注意一些坑,比如 byte+short运算结果是int)
-
特别的:byte、short、int 三种类型的变量做运算(任意组合,byte和byte做运算, …)的时候,结果是int型.
书上说:java做运算的时候,如果操作数均在int的范围内,那么一律在int的空间内运算.
/*
* 基本数据类型之间的运算规则:
* 前提:这里讨论的只是7中基本数据类型变量间的运算,不包含boolean的*/
public class R0416 {
public static void main(String[] args) {
byte b=1;
byte b1=2;
int c=b+b1;
//byte d=b+b1;//报错,这个可以看我short那篇文章,你就明白了
System.out.println(b); //1
}
}
- 说明:此时容量大小指的是,表示数的范围的大和小,比如:float容量要大于long的容量
强制类型转换
- 需要使用强转符:()
- 注意点:强制类型转换,可能导致精度损失
public class DD {
public static void main(String[] args) {
//精度损失例子1
double d1=12.9;
int i1=(int)d1;
System.out.println(i1); //12
//没有精度损失
long l1=123;
short s=(short) l1;
System.out.println(s); //123
//精度损失例子2
int i2=128;
byte b=(byte) i2;
System.out.println(b); //-128
}
//* 总结:整形常量默认为int型,
//* 浮点型常量,默认类型为double型
}
String类型变量的使用
- String属于引用类型
- 声明String类型变量时,使用一对""
- String可以和8种基本数据类型做运算,且运算只能是连续运算:+
- 运算你的结果仍然是String类型
char c=''; //报错(编译不通过),不可以存空,可以存空格' '
String d=""; //可以,也可以存空格" "
String a="sdf";
System.out.println(a+true); //sdftrue
- 练习
public class DD {
public static void main(String[] args) {
//练习2
//* *
System.out.println("* *"); //* *
System.out.println('*'+'t'+'*');//200
System.out.println('*'+"\t"+'*');//* *
System.out.println('*'+'\t'+"*");//51*
System.out.println('*'+("\t"+"*"));//* *
}
}
* *
200
* *
51*
* *
String str2=3.5f+"44";
System.out.println(str2); //3.544
- String不能直接(int)String转int,需要用包装类Integer.parseInt(str);
进制与进制间的转换
计算机底层都已补码的方式来存储数据
- 解释为什么128变成-128,因为int转换为byte后,只要后8位,后8位中1000 0000代表-128
-
二进制的使用说明:
- 计算机底层的存储方式:所有数字都是以二进制形式存储
- 二进制数数据存储方式:所有的数值,不管正负,底层都是以补码的方式存储.
-
练习
public class DD {
public static void main(String[] args) {
char c4='5';
int i1=(int)c4;
short i2=(short) c4;
System.out.println(c4);
System.out.println(i1);
System.out.println(i2);
System.out.println(i1==i2);//基本数据==比较的是值
}
}
5
53
53
true
运算符
算数运算符
//除法
public static void main(String[] args) {
int num1=12;
int num2=5;
int result1=num1/num2;
System.out.println(result1); //2
double result11=num1/num2;
System.out.println(result11); //2.0
double result111=num1/(num2+0.0); //2.4
double result1111=(double)num1/num2;
System.out.println(result1111); //2.4
System.out.println(result111);
int result2=num1/num2*num2;
System.out.println(result2); //10
}
//%
//结果的符号与被模数的符号相同
//开发中,经常使用%来判断是否能被出除进
public static void main(String[] args) {
int m1 = 12;
int n1 = 5;
System.out.println("m1%n1=" + m1 % n1);
int m2 = -12;
int n2 = 5;
System.out.println("m2%n2=" + m2 % n2);
int m3 = 12;
int n3 = -5;
System.out.println("m3%n3=" + m3 % n3);
int m4 = -12;
int n4 = -5;
System.out.println("m4%n4=" + m4 % n4);
}
//结果
m1%n1=2
m2%n2=-2
m3%n3=2
m4%n4=-2
b=++a 先自增 b=a++ 先赋值
double a=0.1;
a++;
System.out.println(a); //1.1
short s1=10;
s1++; //自增1不会改变本身的数据类型
//问题
byte b1=127;
b1++;
System.out.println(b1); //-128
//(a++)++; 编译不通过
解释: 0111 1111
加1: 1000 0000
代表了是-128的补码
赋值运算符
public static void main(String[] args) {
short s1=10;
//s1=s1+2; //编译失败
s1+=2; //不会改变本身的数据类型
int a=10;
a/=2.0;
System.out.println(a); //5
}
int i=2;
i*=0.1;
System.out.println(i); //0
int j=2;
j*=0.5;
System.out.println(j); //1
- 练习题(是几?)
public static void main(String[] args) {
int n=10;
n+=(n++)+(++n);
System.out.println(n);
}
32
解释:n=n+(n++)+(++n) = 10 +10+12
比较运算符(关系运算符)
- 结果都是布尔型
public static void main(String[] args) {
int i=10;
int j=20;
System.out.println(i==j); //false
System.out.println(i=j); //20
}
-
结论
<<: 在一定范围内,每向左移以为,相当于*2 >>:在一定范围内,每向右移以为,相当于/2 负数也可以满足 (高位补和符号位相同的值)
-
面试题:最高效方式计算2*8?
- 当然是用2<<3 或8<<1 这两个都是一个数量级的
逻辑运算符
- 注意:逻辑运算符操作的都是boolean类型
- 开发中推荐使用短路&& 短路||
&逻辑与 &&短路与 逻辑或| 短路或|| ;逻辑非 ! 逻辑异或^ (true false为true)
//& &&运算后得到的boolean结果相同
public static void main(String[] args) {
int a=2;
if(false&a++>0){
System.out.println("ha");;
}else{
System.out.println("hi");
}
System.out.println(a); //3
int b=2;
//左边不满足,就不需要判断右边了
if(false&&b++>0){
System.out.println("ha");;
}else{
System.out.println("hi");
}
System.out.println(b); //2
}
位运算符
- & | ^是逻辑还是位运算符,取决于他操作的数据类型 操作数值的是位运算,操作是boolean是逻辑运算
int i=21;
System.out.println("i<<2 "+(i<<2));
System.out.println("i<<3 "+(i<<3));
System.out.println("i<<4 "+(i<<4));
System.out.println("i<<26 "+(i<<26));
System.out.println("i<<27 "+(i<<27));
System.out.println("i"+i);
i<<2 84
i<<3 168
i<<4 336
i<<26 1409286144
i<<27 -1476395008
i21
public static void main(String[] args) {
System.out.println(-3>>1); //-2
System.out.println(-3>>>1); //2147483646
}
三元运算符
取反所有位取相反的 6取反为-7 -7取反为6
int i=6;
System.out.println(~6); //-7
运算优先级
程序流程控制
顺序结构
分支结构
if
if else
if elseif else
- 如果if else语句中语句只有一条时候可以省略,但是建议不要省略.
-
结果是4 if else匹配就近原则
-
switch case 遇到break或到末尾接受
/*
* switch-case只能是6种结构中数据类型之一:byte short int char 枚举类型(JDK5.0新增)
* String(类型JDK7.0后新增)
* case只能声明常量,不能写表达式和变量
* case后面语句相同,可以考虑合并
* break关键字
* default 相当于if-else中的else default可自己选择有无 而且位置是灵活的,可以放在开头
* 匹配的时候还是会先匹配case,如果没有就跳到default中,如果default没break,那么会继续走下面的case*/
public static void main(String[] args) {
int number=1;
int n=1;
//不允许放布尔类型
switch (number){
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("otwo"); //otwo
break;
default:
System.out.println("都不符合");
}
}
- 给你一个2019年几月几日让你判断这是2019年的第几天?
(说明break不一定都需要加)
这样写,就避免了冗余,如果是6月的话,就先匹配到6,然后把前5个月的天数都加上了,然后最后加个day就是该年的第几天了.
- case 3:后面可以写if else等语句
循环结构
-
for(①;②;④){③} 1234234234234234顺序 可以和break配合
-
while 避免死循环
①
while(②){
③;
④;
}
-
do-while
① do{ ③; ④; }while(②) 执行过程:134234234...2
- 99乘法表简单案例
public static void main(String[] args) {
//遍历100以内的偶数,并计算所有的偶数的和
for (int i = 1; i <= 9; i++){
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j + "=" + (i * j) + " ");
}
System.out.println();
}
}
- 100内所有质数(素数) 质数:只能被1和它本身整除的自然数 最小质数是2
boolean isFlag=true;
//获取当前时间距离1970-01-01 00:00:00的毫秒数
long start=System.currentTimeMillis();
for (int j = 2; j <10000 ; j++) {
for (int i = 2; i <= Math.sqrt(j); i++) {
if(j%i==0){
isFlag=false;
break;
}
}
if(isFlag==true){
System.out.println(j);
}
isFlag=true;
}
//获取当前时间距离1970-01-01 00:00:00的毫秒数
long end=System.currentTimeMillis();
System.out.println(end);
System.out.println("花费的时间"+(end-start));
- 另一种优化
//获取当前时间距离1970-01-01 00:00:00的毫秒数
long start=System.currentTimeMillis();
int count=0;
label:for (int j = 2; j <10000 ; j++) {
for (int i = 2; i <= Math.sqrt(j); i++) {
if(j%i==0){
continue label;
}
}
//走到这的都是质数
count++;
}
//获取当前时间距离1970-01-01 00:00:00的毫秒数
long end=System.currentTimeMillis();
System.out.println(count);
System.out.println("花费的时间"+(end-start));
-
两个关键字的使用break continue
使用范围 区别 相同点 break : switch-case 循环结构中 结束当前循环 关键字后面不可以声明执行语句,根本执行不了 continue: 循环结构中 结束当次循环 关键字后面不可以声明执行语句,根本执行不了
-
可以用标签指定结束位置
label1:for (int j = 2; j <10000 ; j++) {
for (int i = 2; i <= 10; i++) {
if(i==3){
// break label1; //结束指定标识的一层循环结构
continue label1;//结束指定标识的一层循环结构当次循环
}
}
}
Scanner
//如何从键盘获取不同类型的变量:需要使用Scanner类
//具体实现步骤
//1.导包: import java .util.Scanner
//2.Scanner的实例化
//3.调用Scanner类的相关方法(next()/nextXxx),来获取指定类型的变量
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//获取int
System.out.println("请输入你的姓名:");
String name = scan.next();
System.out.println(name);
System.out.println("输入年龄");
int age = scan.nextInt();//输入1.0就会报错抛出异常
System.out.println(age);
System.out.println("请输入你的体重"); //输入90可以
double weight = scan.nextDouble();
System.out.println(weight);
System.out.println("你是否相中我了(true/false)");
boolean isLove = scan.nextBoolean(); //输入True也可以,大小写都可以
System.out.println(isLove);
}
- 随机数
double value =Math.random(); [0.0,1.0)
public static void main(String[] args) {
System.out.println((int)0.9); //0 向下取
}