JAVA基础笔记
一、JAVA语言概述
两个基本概念:类、对象
三个特性:封装、继承、多态
JVM
java虚拟机(Java Virtual Machine)
Java程序在JVM上运行,JVM装在不同的操作系统上,Java程序就可以在这个操作系统中运行。这样就实现了Java程序的跨平台性。
垃圾回收机制
在C/C++等语言中,由程序员负责回收无用内存。
Java语言清除了程序员回收无用内存空间的责任:它提供一种系统级跟踪存储空间的分配情况。并在JVM空闲时,检查并释放那些可被释放的存储空间。
Java程序还是会出现内存泄漏和内存溢出问题
要看程序是如何编写的
JDK(Java Development Kit Java开发工具包)
JDK包含了java 的开发工具和JRE
其中开发工具:编译工具(javac.exe)和打包工具(jre.exe)
JRE(Java Runtime Environment Java运行环境)
包括Java虚拟机(JVM)和 Java程序所需的核心类库
如果想要运行一个开发好的Java程序,只需要安装JRE即可
二、JAVA基本语法
保留字
现有的Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时,要避免使用这些保留字
goto、const
标识符
对各种变量、方法、类等要素命名时使用的字符序列成为标识符
即只要是自己命名的都是标识符
命名规范
包名:全部小写 xxxyyyzzz
类名、接口名:所有单词首字母大写 XxxYyyZzz
变量名、方法名:第一个单词首字母小写,后面的单词首字母大写 xxxYyyZzz
常量名:所有字母都大写,多个单词时用下划线连接 XXX_YYY_ZZZ
变量
long变量赋值时,需要以l或L结尾
long l1 = 123456L;
通常使用int
float类型变量赋值时,需要以f或F结尾
float f1 = 12.1F;
通常使用 double
三、JAVA
交换两个变量的值
-
方式一
定义临时变量,常用
int temp = num1; num1 = num2; num2 = temp;
-
方式二
好处:不用定义临时变量
弊端:num1加num2的数据有可能超出存储范围;有局限性:只能适用于数值类型
num1 = num1 + num2; num2 = num1 - num2; num1 = num1 - num2;
-
方式三
使用位运算符
只适用于数值类型
num1 = num1 ^ num2; num2 = num1 ^ num2; num1 = num1 ^ num2;
三元运算符
获取两个数的最大值
int max = (m > n)? m : n;
获取三个数的最大值
// 不建议使用这个,可读性较差
int max1 = ((n1 > n2)? n1 : n2) > n3)? ((n1 > n2)? n1 : n2) : n3;
int max1 = (n1 > n2)? n1 : n2;
int max2 = (max1 > n3)? max1 : n3;
如果程序既可以用三元运算符,又可以使用if-else结构,优先选用三元运算符
原因:简介、效率高
if-else语句
注:如果if-else嵌套多层之后,换一种方法来实现,多层的嵌套影响代码可读性,也容易出错。
执行语句只有一行的话,{}不可省略。
if-else语句中,在没有{}时,if-else使用就近匹配原则。
int x = 4;
int y = 1;
if(x > 2)
if(y > 2)
System.out.println(x + y);
else \\ 就近原则
System.out.println("x is" + x);
输出x is 4
随机数 Math.random()
Math.random()是一个double类型,并且范围是[0.0, 1.0)
想要让这个Math.random() 生成别的随机数,就需要自己配。
例如获取10 - 99
int value = (int)(Math.random() * 90 -10)
\\[0.0,1.0) -> [0.0,90.0) -> [10.0,100.0)
公式:[a, b] : (int)(Math.random() * (b - a + 1) + a)
break,退出指定的for循环,continue同
label:for(int i = 1;i <= 4;i++){
// 在for循环前面添加标签
for(int j = 1;j <= 10;j++){
if(j % 4 == 0){
break label; // 退出指定的label
}
}
}
二分法查找算法
所以查找的数组必须有序
数组从小到大或者从大到小排列
从中间开始判断,如果小于中间的数,再继续从左半边的中间的数比较,以此类推,大于的话就是右半边
public static void main(String[] args){
int[] arr = new int[]{
-16, 12, 56, 123, 456, 566, 678, 789, 890};
int dest = 123;// 需要查找的数
int head = 0;// 定义首索引
int end = arr.length - 1;// 定义尾索引
int middle;// 定义中间索引
boolean flag = true;// 判断是否查询到
while(head <= end){
middle = (head + end) / 2;
if(dest == arr[middle]){
System.out.println("找到了索引下标:" + middle);
flag = false;
break;
}else if(dest < arr[middle]){
end = middle - 1;
}else if(dest > arr[middle]){
head = middle + 1;
}
}
if(flag){
System.out.println("没有找到");
}
}
排序算法
衡量排序算法的优劣:
- 时间复杂度:分析关键字的比较次数和记录的移动次数
- 空间复杂度:分析排序算法中需要多少辅助内存
- 稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。
冒泡排序
时间复杂度O(n^2)
每一趟进行的过程,从第一个元素开始,比较相邻的元素,位置不正确的就进行交换,再从交换后的元素开始比较下一个元素。从头到尾进行一次比较为一轮,每一轮得到一个最大值或者最小值,直到最后不能交换为止。
总共需要执行n - 1轮
// 冒泡排序
for(int i = 0;i < arr.length - 1;i++) {
// 总共需要进行的轮次
for(int j = 0;j < arr.length - 1 - i;j++) {
// 每一轮比较的次数
int temp;
if(arr[j] > arr[j+1]) {
// 升序或降序
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
快速排序
时间复杂度为O(nlogn)
会先把数组中最前面的数当做基准数
从两边进行检索,先从右边检索比基准数小的,检索到之后停下。
然后再从左边检索比基准数大的。
检索到之后就交换两个元素,然后再继续从右开始检索。
当两边索引相等时,把基准数和相应位置的元素交换。第一轮排序完成
第二轮排序开始,先从基准数左边的排序,左边全部都排完之后。
再排基准数右边的。
排序方式与第一轮相同
public class QuickSortTest {
public static void main(String[] args) {
// 定义数组
int[] arr = {
5, 6, 8, 1, 0, -19, 29};
// 调用排序方法
quickSort(arr, 0, arr.length - 1);
// 遍历数组
for(int i = 0;i < arr.length;i++) {
System.out.println(arr[i] + "\t");
}
}
public static void quickSort(int[] arr,int left,int right) {
/* 进行判断,如果左边索引大于右边索引,是不合法的,直接使用return结束方法
* 当上一步的最终结果是left、right、i、j都相等时,传过来的left和right就是left和left-1了
* 所以需要判断来结束
*/
// if(left > right) { // 可以直接判断之后return,也可以在符合条件下运行
// return;
// }
if(left < right) {
// 定义基准数
int base = arr[left];
// 定义i,从左边开始检索
int i = left;
// 定义j,从右边开始检索
int j = right;
// 开始检索,只要i!=j,就一直检索下去
while(i != j) {
// 先用j从右往左检索,没有检索到满足条件的就j--,继续往左检索
while(arr[j] >= base && i < j) {
j--;
}
// 再用i从左往右检索,没有检索到满足条件的就i++,继续往右检索
while(arr[i] <= base && i < j) {
i++;
}
// 交换数据
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 当满足i == j时,交换停止
// 基准数归位,交换基准数
arr[left] = arr[i];
arr[i] = base;
// 递归调用
// 先给左边的排序
// 此时,左边的排序区间是left ~ i-1
quickSort(arr, left, i - 1);
// 再给右边的排序
// 此时,右边的排序区间是i+1 ~ right
quickSort(arr, i + 1, right);
}
}
}
堆排序
归并排序
数组方法调用
- boolean equals(int[] a, int[] b) 判断两个数组是否相等。
- String toString(int[] a) 输出数组信息。
- void fill(int[] a, int val) 将制定值填充到数组之中,将原来所有的元素值都替换成val
- void sort(int[] a) 对数组进行排序(快排)。
- int binarySearch(int[] a, int key) 对排序后的数组进行二分法检索指定的值,如果返回的是负数,就是没有找到。
import java.util.Arrays;
// 1.
boolean flag = Arrays.equals(arr1, arr2);
// 2.
System.out.println(Arrays.toString(arr));
// 3.
Arrays.fill