Java大总结(一)—— 基本概念、流程控制
一、Java基本语法
1. java的常用命令
java:运行
javac:编译
2. java的开发平台
J2EE:Java 2 Platform Enterprise Edition 企业版,用于企业应用,支持分布式部署。
J2SE:Java 2 Platform Standard Edition 标准版,用于桌面应用,也是J2EE的基础。
J2ME:Java 2 Platform Micro Edition 移动版用于小型设备,是J2SE的一个子集。
3. java的可执行文件
.class文件、字节码文件
4. java跨平台
不同的平台提供不同的虚拟机
5. java环境变量配置
Path:为了在任何位置启动java程序
CLASSPATH:为了在任何位置调用.class文件
6. JDK7、8、9、10之间的区别(拓展)
jdk8加入了函数式编程
jdk9提供了交互编程
jdk10提供了局部变量类型推断、垃圾收集器接口
7. 什么是变量
拥有特定的作用域,可以在作用域内进行修改的量
8. 变量的命名规范以及习惯
命名规范:不能以数字开头,可以以字母(A-Z或者a-z),美元符($)、或者下划线(_)开始
习惯(代码规范):驼峰命名法
9. 数据类型的划分
基本数据类型:八大(由小到大byte,short,int,long,float,double,char,boolean)
引用数据类型:类、数组、接口
10. 数据类型的转换
小类型转大类型(自动转换)
大类型转小类型(强制转换)
int和char的转换
int --> char: 将数字加一个‘0’,并强制类型转换为char
char --> int: 将字符减一个‘0’
示例:
public static void main(String[] args) {
//int类型转char类型
int number = 9;
char cNumber= (char) (number+'0');
System.out.println("Number "+number+" to char is:"+cNumber);
//char类型转int类型
char cNumber2='3';
int number2=cNumber2-'0';
System.out.println("Char "+cNumber2+" to number is:"+number2);
}
11. Java的缺省(默认)类型
整数类型缺省int:10
浮点类型缺省double:10.0
12. 内存的划分(5个区域)
栈
作用:存储局部变量(在方法定义中或者方法声明上的变量)
特点:栈内存的数据用完就释放
堆
作用:存储new出来的东西
特点:每一个new出来的东西都有地址值,每个变量都有默认值
如:
- byte short int long——0
- float double——0.0
- char ——‘\u0000’
- boolean——false
- 引用类型——null
使用完毕就变成了垃圾,但是并没有立即回收,会在垃圾回收器空闲的时候回收
方法区
作用:存储已被Java虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等
特点:方法区中没有实例变量
本地方法区
作用:本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。在JVM规范中,并没有对本地方发展的具体实现方法以及数据结构作强制规定,虚拟机可以*实现它。
寄存器
作用:这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。
13. 运算符
算数运算符
- + (加)
- -(减)
- *(乘)
- /(除)
- %(模)
- ++(递增)
- – (递减)
比较运算符
- == 等于
- != 不等于
- > 大于
- >= 大于等于
- < 小于
- <= 小于等于
逻辑运算符
- & 逻辑与,有false则false。
- | 逻辑或,有true则true。
- ^ 逻辑异或,相同为false,不同为true。
- ! 逻辑非:非false则true,非true则false。
- && 逻辑与
-
- 最终与&结果一样。
- &&具有短路效果。左边是false,右边不执行。
- &是无论左边是false还是true,右边都会执行
- || 逻辑或
-
- ||与|结果是一样的
- ||具有短路效果。左边是true,右边不执行。
- |是无论左边是false还是true,右边都会执行
赋值运算符
- 基本的赋值运算符:=
-
- 把=右边的数据赋值给左边。
- 扩展的赋值运算符:+=,-=,*=,/=,%=
-
- += 把左边和右边做加法,然后赋值给左边
位运算符
- &
-
- 名称:位与运算
- |
-
- 名称:位或运算
- ^
-
- 名称:位异或运算
- ~
-
- 名称:按位取反
- <<
-
- 名称:左移
- >>
-
- 名称:右移
- >>>
-
- 名称:无符号右移
三元运算符
- 格式:
(关系表达式)?(表达式1):(表达式2);
- 规则:
如果关系表达式为true,运算后结果为表达式1
如果关系表达式为false,运算后结果为表达式2
14. 运算符的优先级(了解)
15. 数组
数组的声明(2种)
方式一
元素类型[] 数组名;
方式二
元素类型 数组名[];
数组的初始化(2种以及他们的区别)
方式一(静态初始化)
数据类型[] 数组名 = new 数据类型[]{元素1,元素2……};
//或者
数据类型[] 数组名 = {元素1,元素2……};
方式二(动态初始化)
数据类型[] 数组名 = new 数据类型[数组长度];
数组的定义、特性、遍历
概念
- 数组是存储多个变量(元素)的东西(容器)
特性
- 这多个变量的数据类型一致
- 数组既可以存储基本数据类型,也可以存储引用类型
遍历
核心代码(遍历一维数组arr)
for(int x = 0;x < arr.length;x ++){
System.out.println(arr[x]);
}
多维数组的定义和遍历
定义
//格式一
数据类型[][] 数组名 = new 数据类型[m][n];
//格式二
数据类型[][] 变量名 = new 数据类型[m][];//一维数组的元素个数可以动态给出
//格式三
数据类型[][] 数组名 = {{元素1,元素2,元素3},{元素1,元素2},{元素1,元素2,元素3}};
遍历
int[][] arr = new int[4][];
arr[0] = new int[2];
arr[1] = new int[5];
arr[2] = new int[6];
arr[3] = new int[7];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j]);
}
System.out.println();
}
二、流程控制
1. 顺序结构
在程序中按照顺序执行的步骤
2. 分支结构
if语句
格式
//if
if(逻辑) {
执行的语句;
}
//if - else
if(逻辑) {
执行的语句;
} else {
执行的语句;
}
//if - else if - else
if(逻辑) {
语句;
} else if(逻辑) {
语句;
} else {
语句;
}
switch语句
格式
switch(表达式){
case 值1:语句体1;break;
case 值2:语句体2;break;
······
default:语句体n+1;break;
}
注意事项
表达式取值:byte、short、int、char、jdk5版本以后支持枚举类型、jdk7版本以后支持String
case后面只能跟常量
3. 循环结构
for
for(a;b;c){
d;
}
//a:初始化语句
//b:判断条件语句:返回布尔类型
//c:控制条件语句
//d:循环体语句块
while
//普通while循环
while (判断条件语句) {
循环体语句;
}
//do-while:循环体语句块至少执行一次
do {
循环体语句块;
}while(判断条件语句);
增强的for(foreach)
格式
for(ElementType element:arrayName) {
循环体语句;//可以使用element代表每次循环取出的数据
}
注意事项
- 只适合取数据,不能更改数据
- 只用于数组,或实现Iterable接口的集合类上:set,list
4. 递归
//案例:使用递归计算1...100的和
class Test {
public static void main(String[] args) {
int sum = add(100);
System.out.println(sum);
}
public static int add(int i) {
if(i == 1) return i;
else return add(i-1)+i;
}
}
5. 常见排序算法
冒泡排序
class Test {
public static void bubbleSort(int[] arr) {
int temp = 0;
for(int i = 0;i < arr.length - 1;i ++) {
for(int j = 0 ;j < arr.length - 1 - i;j ++) {
if(arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
public static void main(String[] args) {
int[] arr = {5,4,6,2,8,7,3,9};
bubbleSort(arr);
for(int item : arr) {
System.out.print(item);
}
}
}
选择排序
思路
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。
public class Test2 {
public static void main(String[] args) {
int[] arr = {6,8,5,2,1,7};
selectSort(arr);
for (int var : arr) {
System.out.println(var);
}
}
public static void selectSort(int[] arr) {
int k = 0;
int tmp = 0;
for(int i = 0;i < arr.length;i ++) {
k = i;
for(int j = i;j < arr.length;j ++) {
if(arr[k] > arr[j]) {
k = j;
}
}
tmp = arr[i];
arr[i] = arr[k];
arr[k] = tmp;
}
}
}
插入排序
思路
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为 。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] array={12,73,45,69,35};
int i,j,temp;
for(i=1;i<array.length;i++) {
/*
* 第一个for循环
* 把数组分成两部分,右边为未排序,左边为已排序
* 记录排序与未排序分割点temp(temp为下一个排序对象)
*/
temp=array[i];
for(j=i-1;j>=0;j--) {
/*
* 第二个for循环
* 将排序对象temp与已排序数组比较
* 当temp比最近左边的数大时(按从小到大循序排列时)
* 直接结束本次循环,进行下一个数排序
* 否则比左边这个数小时将这个数后移,腾出这个数的位置
*/
if (temp > array[j]) {
break;
}else{
array[j+1] = array[j];
}
}
array[j+1]=temp;
}
System.out.println(Arrays.toString(array));
}
}
快速排序
思路
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
public class Quick
{
public static void main(String[] args)
{
int[] ins = {2,3,5,1,23,6,78,34};
int[] ins2 = sort(ins,0,ins.length-1);
for(int in: ins2){
System.out.println(in);
}
}
public static int[] sort(int[] ins ,int start,int end){
if(start>=end){
return ins;//这个返回值并没有影响,因为这个返回值没有使用到。
}
int mid = ins[start];
int low = start;
int hight = end;
while(low < hight){
while(low < hight && ins[hight]>=mid){//
hight -=1;
}
ins[low] = ins[hight];
while(low < hight && ins[low] < mid){
low +=1;
}
ins[hight] = ins[low];
}
ins[low] = mid;
sort(ins, start, low-1);
sort(ins, low+1, end);
return ins;
}
}
6. 二分查找
思路
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
public class BSTest {
public static void main(String[] args) {
//二分查找是对有序序列进行查找,因此直接给出一个有序序列
int[] arr = {1,5,8,16,25,48,72};
int elem = 16;
int result = binerySerach(arr,elem,0,arr.length);
System.out.println(elem+"在数组的第"+(result+1)+"个");
}
public static int binerySerach(int[] arr,int elem,int head,int tail) {
if (elem > findMid(head,tail,arr)) {
return binerySerach(arr,elem,(tail-head)/2 + head,tail);
} else if (elem < findMid(head,tail,arr)) {
return binerySerach(arr,elem,head,(tail-head)/2 + head);
} else {
return (tail-head)/2+head;
}
}
public static int findMid(int head,int tail,int[] arr) {
return arr[(tail-head)/2 + head];
}
}