1.Java语言发展史
詹姆斯·高斯林
(James Gosling)
- 任职于Sun公司的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak;1995年5月以Java的名称正式发布;
- 1996年获得第一笔投资1亿元;
- 1998年提出jdk1.2,更名为java2
- 之后推出jdk1.3 jdk1.4
- 2005年更名为jdk5.0,进行了大幅的版本改进
- 2006年sun公司宣布将Java作为免费软件对外发布
- 2007年3月起,全世界所有的开发人员均可对Java源代码进行修改
- 2007年推出jdk6.0
- 2009年4月Oracle以74亿美元收购了sun公司
- 2011年7月由Oracle正式发布jdk7
- 2014年3月正式发布了java8
版本:1.0 - 1.1 - 1.2 - 1.3 - 1.4 - 1.5
5.0 - 6.0 - 7.0 - 8.0…
2.Java语言特点
- 简单性 、高性能、编译性、解释性、面向对象、分布式处理、健壮性、安全性、可移植、开源、跨平台
- 什么是跨平台性?
通过Java语言编写的应用程序在不同的系统平台上都可以运行。
原理:==它首先将源代码(.java)编译成字节码(.class),然后依赖各种不同平台上的虚拟机来解释执行字节码,从而实现了“一次编写,到处运行”==的跨平台特性。
3.JDK、JRE、JVM区别
JDK
(Java Development Kid)是 Java 语言的软件开发工具包,是针对 Java 开发人员的产品,是整个 Java 的核心,包括了 Java 运行环境 JRE、Java 工具和 Java 基础类库。JRE
(Java Runtime Environment,Java 运行环境)是运行 JAVA 程序所必须的环境的集合,包含 JVM 标准实现及 Java 核心类库。JVM
(Java Virtual Machine,Java 虚拟机)是整个 Java 实现跨平台的最核心的部分,能够运行以 Java 语言编写的软件程序。- 注意:
- 在JDK的安装目录下有一个jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib合起来就称为jre;
- JDK有javac.exe而JRE里面没有,javac指令是用来将java文件编译成class文件的。
- 配置环境变量:
- JAVA_HOME:该配置是要配置jdk的安装目录,来明确要使用哪个版本的jdk。在开发过程中我们通常会使用一些开发软件(如eclipse、tomcat,NetBeans等)是通过JAVA_HOME来找到jdk的(环境变量JAVA_HOME的值就是jdk安装的路径),所以我们不配置JAVA_HOME的话那我们使用eclipse时可能要受到影响了。
- PATH:系统会在path配置的值中,寻找可执行文件。需要把jdk\bin添加到path中。我们用到的java命令,如java命令把.java文件翻译成.class文件、java执行.class文件等,这些命令java,javac等都是通过我们配置的PATH环境变量找到相应的java.exe和javac.exe文件的,然后计算机才能正确识别并执行我们输入的java命令。
- CLASSPATH:在java开发过程中我们会用到很多开发人员已经帮我们写好的标准类库,而我们要用这些类库的话必须告诉计算机如何找到它们,而设置CLASSPATH环境变量即可使计算机找到它们。jdk1.5 之后就不用再配置 CLASSPATH了。
Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。
4.运行与工作原理
- 1.编译:通过javac命令将java的源文件也就是.java文件编译成.class文件。
- 2.执行:
- 先启动java虚拟机,不同的操作系统有不同的jvm,因此java跨平台。
- 再通过JVM加载HelloWorld.class字节码文件。并加载main方法执行程序。
5.基本数据类型(八种)
6.ASCII表
char要输出字符串本身,字符要用单引号括起来:char a=‘M’; 输出:M
7.变量交换
首尾相连
int c=a;
a=b;
b=c;
8.引用类型
引用类型是一个对象类型。它的值是指向内存空间的引用,就是地址,所指向的内存中保存着变量所表示的一个值或一组值。如:类,接口,数组。
9.进制前缀
0x——16进制
0——8进制
\u——char类型,16进制
10.基本类型的类型转换
- 小到大(隐式转换)
Byte a =120;
Int b=a;//直接转
- 大到小(显式转换)
需要强制类型转换
int xx = 356;
byte y=(byte) xx;
注意:小数转成整数,小数直接舍弃
11.浮点数的特殊值
Infinity 无穷大 例:3.14/0
Nan not a number 例:0/0.0
12.运算符
优先级:
13. 变量
变量的使用原则:就近原则。尽量控制到最小范围。
- 成员变量:定义在类里方法外,不用赋值也有默认值。
作用域:是整个类中,类消失了,变量才释放。 - 局部变量:定义在方法里,或者局部代码块中。必须手动初始化,来分配内存。如:int i=5;
作用域:也就是方法里或者局部代码块里,方法运行完内存就释放了。
14.三种循环的区别
三种循环都可以互相代替
- 1.for:知道循环次数;
- 2.while/do while:当循环次数不确定时;
- 3.while:先判断,不符合规则,不执行代码;
- 4.do while:代码最少被执行一次,再去判断,符合规则,再次执行代码。
15.方法
被命名的代码块,方法可以含参数可以不含参数,可以提高代码的复用性。
修饰符 返回值 方法名(【参数】){
方法体;
}
方法重载:
方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数列表(参数的个数和类型不同)。
16.数组(Array)
创建数组:
- 动态初始化:int[] a = new int[5];
- 静态初始化:
- int[] a ={1,2,3,4,5,6,7,8};
- int[] a =new int[]{1,2,3,4,5};
数组工具类Arrays:
Arrays.toString
(数组):把数组里的数据,用逗号拼接成一个字符串;Arrays.sort
(数组):把数组里的数据进行排序,默认由小到大;Arrays.copyOf
(数组,新的长度):把数组复制成一个指定长度的新数组。
二维数组:
二维数组可以看成数组为元素的数组,例如:
- 静态初始化:
- int a[][] = {{1,2},{3,4,5},{6,7,8,9}};
- int[][] a={{1,2,3},{4,5,6},{7,8,9}};
- int[][] arr=new int[][]{{1,2,3},{4,5,6}};
- 动态初始化:
- int[][] a = new int[2][3]; //初始化为默认值,int型为0
class Demo2_Array {
public static void main(String[] args) {
int[][] arr = new int[3][2];
//这是一个二维数组
//这个二维数组中有3个一维数组
//每个一维数组中有2个元素
System.out.println(arr); //打印二维数组
System.out.println(arr[0]); //打印二维数组中的第一个一维数组
System.out.println(arr[0][0]);//打印二维数组中的第一个一维数组中的第一个元素
}
}
17.算法
术语说明:
- 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
- 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;
- 内排序:所有排序操作都在内存中完成;
- 外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行;
- 时间复杂度(O): 一个算法执行所耗费的时间。
- 空间复杂度:运行完一个程序所需内存的大小。
冒泡排序
:如果有n个数
,则遍历n-1
轮,一共比较n(n-1)/2
次。
遍历若干次要排序的数列,每次遍历时,它都会从前往后依次比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,经过第一轮遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。重复此操作,直到整个数列都有序为止!
package day0000;
import java.util.Arrays;
import java.util.Random;
public class TT {
public static void main(String[] args) {
int[] arr = new int[]{43, 36, 45, 18, 24,9,20,32};
int[] arrnew = f1(arr);
System.out.println(Arrays.toString(arrnew));
}
private static int[] f1(int[] a) {
//外循环控制遍历轮数,如果5个数字,遍历4轮就行
for (int i = 0; i < a.length-1; i++) {
//内循环控制每轮比较次数,循环次数和外循环一样
for (int j = 0; j < a.length-1; j++) {
if(a[j]>a[j+1]){
int t = a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
return a;
}
选择排序
:(Selection-sort)是一种简单直观的排序算法。
- 工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
n个记录
的直接选择排序可经过n-1趟
直接选择排序得到有序结果。- 表现最稳定的排序算法之一,因为无论什么数据进去都是O(n2)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。理论上讲,选择排序可能也是平时排序一般人想到的最多的排序方法了吧。
- 代码的执行时间 T(n)与每行代码的执行次数 n 成正比,人们把这个规律总结成这么一个公式: T(n) = O(f(n))
/**
* 选择排序
* @param array
* @return
*/
public static int[] selectionSort(int[] array) {
if (array.length == 0)
return array;
for (int i = 0; i < array.length; i++) {
int minIndex = i;
for (int j = i; j < array.length; j++) {
if (array[j] < array[minIndex]) //找到最小的数
minIndex = j; //将最小数的索引保存
}
int temp = array[minIndex];
array[minIndex] = array[i];
array[i] = temp;
}
return array;
}
插入排序
(Insertion Sort):是一种简单直观的排序算法。
工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
希尔排序
:
1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序
。
归并排序
:是建立在归并操作上的一种有效的排序算法。
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
快速排序
:
基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
- 快速排序(Quick Sort)使用分治法策略。
- 算法描述:
在数据序列中选择一个元素作为基准值,每躺从数据序列的两端开始交替进行,将小于基准值元素交换到序列前端,将大于基准值的元素交换到序列后端,介于两者之间的位置则成为基准值的最终位置。同时,序列被划分成两个子序列,再分别对两个子序列进行快速排序,直到子序列长度为1,则完成排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
堆排序
:(Heapsort)
是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
计数排序
:
不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
桶排序
是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。
基数排序
是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。