一.基础部分
Java运行需要JDK。JDK是Java开发工具,里面有JRE,JRE是Java运行环境;JRE里面有JVM,JVM是Java虚拟机。
JDK是Java开发工具包 ,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。
JRE是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。
JVM是整个Java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行
JDK中包含了JRE,JRE又包含JVM
Java程序经编译后会产生byte code。Java程序编译使用命令javac 运行使用 java 命令
Java的父亲:高斯林。现代计算机之父:冯诺依曼大佬
二.初识Java
先看一个案例:
(一). class定义的叫做类。后面的HelloWorld就是类名。
- 类名必须大驼峰
- 如果该类是public class,那么类名必须和文件名相同
(二). public访问限制修饰符
(三). public static void main(String[ ] args)这个是main方法,必须这么写
static静态修饰符; void返回值类型; main方法名; 括号里是形参; String[ ] args是字符串数组
类里面才有方法,一个类可能有很多个方法,方法名小驼峰规则。
main方法的快捷键有psvm或m或main,再加回车enter。输出的快捷键是sout加回车。
args[ ]里面没有元素,在命令行里面,如上图,是如此运行。
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello!");
System.out.println(100);
System.out.println(Integer.MAX_VALUE); //输出int型能表示的最大值
}
}
(四).注释要合理
基本知识点
标识符和关键字
标识符:包含字母数字下划线和$,不能数字开头,不能是关键字 int 3a = 20 ; err!
关键字:Java提前保留
数据类型与变量
冯诺依曼体系:
字面常量
常用八种数据类型:byte,short,int,long,float,double,char,boolean。 对于的分别为:1字节,2字节,4,8,4,8,2,没有明确规定。(8 bit = 1 byte)字符型范围[ 0, 65535 ] 不论在32位系统还是64位系统,数据类型所占字节数都是一样的。平时讲的8GB指的是8G个字节Java没有“无符号”或“有符号”说法
变量:可以修改,int a = 10; a = 20; 字符型的编码按Unicode编码规则,可以薛微看看Unicode百度百科 。 或者优快云Java char型的字符集、字符编码 。 字符编码:GBK,UTF-8... 字符集:Unicode,ASCII... char的包装类:Character
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello!");
float c = 12.5f;
System.out.println(c);
double d = 1.1;
System.out.printf("%.2f\n",d); //输出1.10 保留末尾精度
char baby = 97;
System.out.println(baby);
}
}
强制类型转换
用System.identityHashCode(变量);查看变量的地址,可以看出两者引用的值不同了?
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello!");
byte s = 2,f = 8;
byte k = (byte) (s+f); // 小于4个字节的会在运算时提升为4个字节
System.out.println(k);
}
}
布尔类型boolean由于其本身所代码的特殊含义,boolean类型与其他基本类型不能进行类型的转换(既不能进行自动类型的提升,也不能强制类型转换), 否则,将编译出错。
byte a = 130; float b = 3.5; 这两行代码会发生编译错误。
String
在Java中,有了全新的数据类型(引用数据类型):String
public class HelloWorld {
public static void main(String[] args) {
String str = "Hello";
int a = 10;
System.out.println(str);
System.out.println(a);
}
}
str和a都叫做局部变量,依然存放在栈上,拿不到具体的地址(安全性),没有所谓的\0结尾 将String和其他数据类型一起输出,在出现String之后的每个都变成字符串型。
public class HelloWorld {
public static void main(String[] args) {
int a = 10;
String str = String.valueOf(a);
System.out.println(str); //输出10
String le = "12123";
int b = Integer.valueOf(le);
int c = Integer.parseInt(le);
System.out.println(b-3); //输出12120
System.out.println(c-2); //输出12121
}
}
valueOf( ) 和 parseInt( ) 本质还是一样的,前者的底层调用了后者
字符串比较相等时,不能用==来连接两个,而应该使用第一个字符串.equals(第二个字符串),结果相等返回true,否则返回false
&和 |
& 和 | ,如果表达式结果为Boolean时,也表示逻辑运算,但与 && 和 || 相比,不支持短路求值
位运算
同理,按位异或 ^ :对应位不一样就是1,否则为0。0和任何数异或得本身; 按位取反 ~ :原1变0,原0变1。
移位运算符
左移<<:最左侧位不要,最右侧补0 右移>>:最右侧位不要,最左侧补符号位,正数补0,负数补1,对负数来说右移是特殊的 无符号右移>>>:统统补0,没有无符号左移。尖部在哪就是哪个方向的移动。
public class HelloWorld {
public static void main(String[] args) {
int a = -1, b = -3, c = -678;
System.out.println(a>>1); //输出-1
System.out.println(a>>3); //输出-1
System.out.println(b>>3); //输出-1
System.out.println(c>>3); //输出-85
System.out.println(c>>>3); //输出536870827
}
}
问题:求一个整数,在内存当中存储时,二进制1的个数。
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int x = scanner.nextInt();
int count = 0;
for (int i = 0; i < 32; i++) {
if (x == 0) break;
else if (((x >> i) & 1) == 1) count++;
}
System.out.println(count);
}
调试窗口
输入输出
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
System.out.print(a);
String name = sc.nextLine(); //遇到回车结束
System.out.println(name);
String name1 = sc.next(); //遇到空格/回车就结束了
System.out.println(name1);
sc.close();
}
}
import java.util.Random;
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Random random = new Random();
while(sc.hasNextInt()){
int n = sc.nextInt();
System.out.println(n);
int rand = random.nextInt(50)+50; //范围在[ 50,100 )
System.out.println(rand);
}//输入crtl+D结束循环
}
}
在使用某些函数时,例如Math.ma( )时,Math在package java.;ang包装里,故不需要import
方法
方法的执行 是在一块内存中进行的,这块内存叫栈。
- 方法的调用在栈上
- 当方法遇到return或者遇到右括号表示当前方法结束了。对应的方法开辟的栈帧回收了
- Java里面没有说方法的前后位置的关系
- 在方法里面交换swap(a,b),只是交换了形参的值,实参没有改变,要交换实参需要类和对象
方法重载
方法签名
在同一个作用域中不能定义两个相同名称的标识符。比如:方法中不能定义两个名字一样的变量,但是类里面可以定义两个名字一样的方法。
方法签名:在经过编译器修改过后方法最终的名字。具体方式:方法全路径名+参数列表+返回值类型,构成方法的完整的名字。
递归
递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。
递归需要起始条件和终止条件
例如:汉诺塔 汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
思路:其实我们不难发现当我们有n个盘子的时候,我们只需要将n-1个盘子从A转移到B, 再把最大的盘子从A转移到C,这个时候只剩下将n-1个盘子从B转移到C。这样的解决问题的方式实际上将原问题转化为解决移动n-1、n-2........3、2,直到移动到最后最小的盘子。
import java.util.Scanner;
public class HelloWorld {
public static void hannota(int num, char pos1, char pos2, char pos3) {
if (num == 1) {
move(pos1,pos3);
return;
}
hannota(num-1,pos1,pos3,pos2); //递归调用
move(pos1,pos3);
hannota(num-1,pos2,pos1,pos3); //递归调用
}
public static void move(char pos1, char pos2) {
System.out.printf("%c->%c",pos1,pos2);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
hannota(n,'A','B','C');
}
}
或者
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
TowerP towerP = new TowerP();
System.out.println("请输入汉诺塔的层数:");
int i = scanner.nextInt();
int move = towerP.move(i, 'A', 'B', 'C');
System.out.println("共移动:"+move + "次");
}
}
class TowerP {
int count = 0;
public int move(int num, char a, char b, char c) {
if (num == 1) {
count += 1;
System.out.println(a + "->" + c);
} else {
move(num - 1, a, c, b); //递归调用
System.out.println(a + "->" + c);
move(num -1, b, a, c); //递归调用
count += 1;
}
return count;
}
}