总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。基础
boolean false return static静态 Scanner length float double
default默认 final不变的
1.软件:一定顺序组织的数据和指令的集合;
软件分系统软件和应用软件;
人机交互方式:图形化界面和命令行方式;
2.常用的命令:
cd\ : 退回到根目录
cd + 地址: 进入到指定的目录下
cd… : 返回上一级目录
切换盘符: 盘符字符+:
cls :清屏
dir : 列出指定目录下的所有文件和文件夹名
dos窗口不区分大小写。
3.Java语言发展史:
SUN公司91年研发,被Oracle公司收购
Jdk1.2 :
J2SE(JavaSE):标准版,桌面应用程序开发
J2ME(JavaME): 微型版----淘汰了
J2EE(JavaEE):企业版,企业应用程序
4.Java语言的特点:
面向对象,安全,开源等…
跨平台(可移植性): 在不同的操作系统上都可以运行java程序。
原理:不同平台安装jvm(java虚拟机)
Jvm才是java程序真正的执行者。
5.Java环境搭建:
Jvm:java虚拟机
JRE:java运行环境,包含了jvm和核心类库
JDK: 专门给开发人员使用,java开发工具包,包含了jre和开发工具
Jdk包含了jre,jre包含了jvm
6.在dos窗口中输入了命令:一共查找两个地方
1命令左侧的目录,如果有则执行,如果没有则找第二个地方。
2第二个地方是环境变量Path对应的值
环境变量配置:
计算机—属性—高级系统设置—高级—环境变量—系统变量----Path
Path = D:\Java\jdk1.8.0_131\bin;…….
配置技巧:
JAVA_HOME = D:\Java\jdk1.8.0_131
PATH = %JAVA_HOME%\bin;……
7.path环境变量作用:让配置的程序在任意目录下都可以执行
8.编写java应用程序:
用具有编辑性的软件都可以编写程序。
步骤:
- 创建一个.java文件
- 打开文件,编写源代码
- 编译源代码文件 javac 源文件名.java
- 执行class文件 java 类名(切记后面不要加clsaa)
注意:
1. java语言区分大小写
2. Class左边可以用修饰符修饰符,一个是public一个是空白(默认修饰符)
如果类用public修饰了,表示该类名和源文件名必须一模一样(建议)
如果类用空白修饰了,那么类名可以和源文件名不一致 - 一个源文件中可以写多个类,但是只能有一个类用public修饰,编译后,有几个类生成几个class文件
- 一个类中只能有一个入口方法,即main方法
类名的命名规范:
- 一个单词组成,单词的首字母大写,其他小写
- 如果多个单词组成,每个单词的首字母大写,其他小写,单词间没有空格
- 见名知意
3.ClassPath:类路径
告诉jvm到哪里去找要执行的class,是给jvm用的
计算级—属性—高级系统设置—高级—环境变量—系统变量----新建
ClassPath: .; D:\Java\jdk1.8.0_131\lib;
.; D:\Java\jdk1.8.0_131\lib \tools.jar; D:\Java\jdk1.8.0_131\lib \dt.jar
ClassPath:针对的是编译好的class文件,给jvm用
Path:是给操作系统用的,告诉系统到哪里找程序执行。
4.练习,输出自己名字
class Demo{
public static void main(String[] args){ //main方法
System.out.println(“李”); //输出语句,红色字体记住,多练
}
}
切记输入要用英文输入法,包括() ; ”” :等。
二.
复习:
- jvm:java虚拟机,执行class文件
- jre:java运行环境,包含:jvm和核心类库
- jdk:java开发工具包,包含:jre和开发工具
安装jdk,安装路径中不建议有空格或者是中文字符
环境变量配置: path: ……\bin; -------给系统用,到哪找程序
Classpath:类路径,.;……\lib\tools.jar;……\lib\dt.jar;
-----给jvm用,到哪去找class
编写程序步骤: - 创建.java文件,根据需求编写源代码
- 编译源代码, javac 源文件名.java,检查的是语法的错误。
- 执行class文件, java 类名,从上到下一行一行执行,检查逻辑
任务:
关键字:(如下图)
在java中,被赋予具有特殊含义的单词,并且这些单词都是小写形式。
Eg: class ,public,static,void
goto和const是java中的保留字,不使用。
标识符:
在java中,凡是让我们定义名字的地方。
分为4种:类名,变量名,方法名,常量名
规则: - 不能用数字开头
- 数字,字母,$, _ 组成
- 不能是java中的关键字
- 严格区分大小写
规范:
类名: Xxx, XxxYyyZzz
变量名: xxx,xxxYyyZzz
方法名: xxx,xxxYyyZzz
常量名: XXX, XXX_YYY_ZZZ - 注释
作用: - 用来注解说明程序的意义
单行注释: //
多行注释: /* ……/
文档注释: /**…./
注:后两个符号不能嵌套使用
工作当中养成习惯注释 - 可以调试程序
4.常量:(常量名是标识符)
不能改变的数据。必须有大写字母组成。
分6类 整数类型: 123
浮点类型: 2.34
字符类型:用一对单引号表示,’a’ ,’1’ ,’喊’ ,‘ ‘,‘+’,内容长度为1
字符串类型:用一对双引号表示,” ”,“abcd” 内容长度大于等于0
布尔类型:true 和false
空常量: null
5.数据类型:两大类(基本类型和引用类型)
Java语言是一个强类型语句,对于每一个操作的数据都有明确的类型表示。
(1)基本类型:4类,共8种
整数类型:(注:8数据位=1个字节=1 byte ,1024 byte=1 Kb)
byte :1个字节), -128-127 -2^7 – 2^7-1 //幂次=位数-1
short :2个字节, -2^15 – 2^15-1
int :4个字节, -2^31 – 2^31-1 默认
long :8个字节, -2^63 – 2^63-1
浮点类型:
float :单精度,4个字节
double :双精度,8个字节 默认
字符类型:
char :2个字节,‘‘
布尔类型:
boolean : true false
(2)引用类型:类,接口,数组,枚举
注:这里数据类型不包括字符串,即有” ”肯定不是数据类型,但‘ ’是(字符数据类型)
6.变量:(变量名是标识符)
可以改变的数据。
实质:在内存中,开辟一个空间,用于存储可以改变的数据。
声明:数据类型 变量名; eg: int num ;
赋值:变量名 = 数据; num = 100;
声明并赋值: 数据类型 变量名= 数据; eg : int num = 100;
数据类型: float long
注意:
- 变量都作用范围,范围是定义变量所属的那对大括号
- 变量必须初始化后才能使用,即赋值后才能使用
- 一对大括号内不能定义重名的变量
- 定义变量赋值必须与类型一致
7.基本数据类型间的转换: - 自动类型转换 : 小类型----》大类型
a) byte ,short ,char做运算时,首先提升类型为int类型
b) 操作数中出现了浮点类型,最终结果为浮点类型
c) boolean类型不参与类型间的转换 - 强制类型转换:大类型----》小类型
格式: 小类型 变量名 =(小类型)变量名(大类型);
注:eg: long a=243141341234234L; float b=1.23f;
float b=(float)3.14;
8.运算符:
- 算数
-
-
- / %(取模(取余数)) ++(自增) --(自减) +(字符串连接符)
注:取余时,结果的正负和%左边的被除数一样;
+:运算符两边任一边有字符串,作用:连接成大的字符串
++或–:运算时看++在前面还是后面,前加加,后加加
= 赋值
+= -= /= *= %= (可强制类型转换)
- / %(取模(取余数)) ++(自增) --(自减) +(字符串连接符)
-
- 比较
= < <= == !=
结果为:boolean(布尔型常量)
-
逻辑
连接值为boolean表达式的
eg: boolean a=true;
boolean boo=a<b&&b<c; //判断b比a大且比c小
&与,两边都是true,则结果为true
|或:两边都是false,则结果为false
!非:取反,!true = false, !false = true
^异或:两边不同则为true,相同为false(异真,同假)
&&:短路与,如果左边表达式为false,右边不再计算,直接判定结果为false;否则都要计算。
||:短路或,如果左边表达式为true,右边不再计算,直接判定结果为true;否则都要计算。 -
三元
数据类型 变量名 =
(值为boolean类型的表达式)?表达式1 : 表达式2;
对boolean类型的表达式进行判断,如果为true,最终结果为表达式1
如果为false,最终结果为表达式2.
boolean flag=10>9 ? 100;90; //三元运算符必须有一个变量接收。 -
练习(输入任意两个数可以互换)
import java.util.*;
public class Demo{
// 需求:输入任意两个数互换
public static void main(String[] args){
System.out.println("请输入a值”);
System.out.println("请输入b值”);
Scanner input=new Scanner(System.in); //获取扫描对象,a和b
int a=input.nextInt();
int b=input.nextInt(); //a和b分别输入写,不能一起直接输a,b
int c=a;
a=b;
b=c;
System.out.println(“a=”+a+”,b=”+b); //老是忘,多练
}
}
三.
位运算:
前提条件:需要将进行运算的数字转成二进制才可以进行位运算。
移位运算:
左移:<< ,被移位的数乘以2的移动次幂
右移:>>,被移位的数除以2的移动次幂
最高位补位,如果是正数补位是0,如果是负数补位是1
无符号右移>>>,被移位的数除以2的移动次幂
无论是正数还是负数,最高位补位都是0.
逻辑位运算:
&,|,^,~(取反)
异或^:一个数异或另一个数两次,结果为原来的数。
true = 1,false = 0
流程控制语句:(顺序,选择,循环)
顺序语句:从上到下,一行一行去执行。
选择语句:
–if语句:
if(布尔类型表达式){ 语句;}
if(布尔类型表达式){语句1;}else{语句2;}
if(){}else if(){}else if(){}……else{}
if(){ if(){} }
注意:如果if控制的语句有且只有一行时,可以省略大括号。
–switch语句
switch(常量表达式){ //byte short char int 枚举 String(字符串)
case 常量1:
执行语句;
case 常量2:
执行语句;break;
case 常量3:
执行语句;
……
default:
执行语句;
} //记住格式 default:执行语句;
结束switch语句的标志是:break和”}”
如果switch没有写break语句,程序编译通过,并且能运行;找到匹配的case执行后,继续向下执行,此时表达式的值不再和case后边的值进行匹配,直至遇到结束的标志。
循环语句
重复执行某些语句。
要素: 重复执行的语句 初始化变量 改变初始化变量值 循环条件
1.while(循环条件){
重复执行的语句;
}
2.do{
重复执行的语句;
}while(循环条件);
区别: -
while是先判断后执行,执行次数:0-n
-
do/while是先执行后判断,执行次数:1-n
3.for(初始化语句;条件;更改初始化变量语句){
重复执行语句;
}
注:1若循环体代码至少执行一遍,用do-while;
2若控制循环次数的变量只在循环体中使用,用for,此时for之外,变量会被释放。
记得初始化语句时加上数据类型,如for(int a=1; ;)
For和for嵌套,执行总次数=外循环次数(行)*内循环次数(列)//打印几行几列数
练习:
Scanner sc=new Scanner(System.in);
double a=sc.nextDouble();
四
//输出2–50间质数
for(int i = 2; i <= 50 ;i++){ //被除数
boolean flag = true; //认为每一个正在遍历的数都为质数
for(int j = 2; j <i; j++){ //除数
if(i % j == 0){flag = false;}
break; //结束第二个for,避免找第二个公约数
}
if(flag)
System.out.println(i);
}
(2)流程控制语句:
1.判断语句
if(boolean表达式){}else{}
2.选择语句
switch(表达式){ case 常量: break;} //表达式值类型:byte short int char String
3.循环语句
while
do/while
for
4.其他语句
break;:switch语句和循环语句。
意味着:当前语句“结束”.
如果在循环嵌套语句中出现break,那么结束的是break所在的循环。
continue;:循环语句。
意味着:结束当前正在进行中的循环,继续下一次循环.
(3)函数(方法):
定义在类中,一段独立的代码块,该代码块完成一个特定的功能,如果没有被调用那么该代码块永远不会执行。
格式:
修饰符 返回值类型 方法名(参数列表){
执行语句;
return 返回值;
}修饰符:public static /static
返回值类型: 即,数据类型 该功能的运算的结果的数据类型
void :无返回值类型,通常省略return方法名:见名知意的原则,xxxYyyZzz
参数列表:变量声明, 数据类型 变量名 eg: (int a,int b,int c)return:
1. 返回方法运算后的结果
2. 方法结束
自定义方法:
1.返回值类型
2.参数列表
java程序启动时,需在内存中开辟空间。
java程序启动,将内存进行划分,栈,堆,方法区,本地方法区,寄存器。
Java中所有函数都是在栈内存中执行的,通过return关键字出栈。
栈:
特点:先进后出
方法都是在栈中执行,通过return关键字出栈(方法结束)
方法重载:
在一个类中,允许方法名相同,但是参数列表不同,与返回值类型无关。
参数列表不同:1.参数个数不同 2.不同类型的参数的顺序不同
五
基本类型:
byte short int long char float double boolean
引用类型
数组 类 接口 枚举
数组:
一组相同类型的数据的集合。
可以理解为是:容器
格式:
动态声明:
元素类型[] 数组名 = new 元素类型[元素个数];
元素类型 数组名[] = new 元素类型[元素个数];
eg: int[] arr = new int[3]; 创建一个箱子,箱子里存放的数据为int类型,能存放3个int类型数据。
arr[2] = 100; 第三个元素存储100
System.out.println(arr[1]);静态声明:
元素类型[] 数组名 = new 元素类型[]{元素1,元素2,元素3,…};
元素类型[] 数组名 = {元素1,元素2,元素3,…};
注意:简写格式不能分两行写,必须是一行完成
eg: int[] arr =new int[] {1,2,3,4,5};int[] arr; arr = {1,3,4}; //这种写法错误
数组属性:
.length : 获取数组长度
eg: arr.length :获取名为arr数组的元素个数
jdk5.0:
for-eache:增强for循环
作用:只能用来遍历,如果想要改变数组中的元素,只能用普通for循环。
for(元素类型 变量名 : 数组/集合){
}
//遍历数组
public static void main(String[] args){
int[] arr=new int[ ]{1,2,3,4,5};
for(int a:arr){
System.out.println(a);
}
或for (int i=0;i<arr.length;i++){
System.out.println( arr[i] );
}内存分配:
寄存器,与cpu有关;
本地方法区,与操作系统方法有关
方法区:静态数据和class
栈:先进后出,方法都是在这执行
堆:
1.会分配内存地址值
2.在实体中会存放默认值
整数:0 浮点:0.0 布尔:false 字符:’\u0000’
引用类型:null
3.没有任何引用指向的实体,称为垃圾
垃圾回收机制会不定时启动处理垃圾。Jvm控制
1.引用类型的变量进行传参,实际传递的是保存在变量中指向堆中空间的地址,这种传参情况叫做引用传递,针对引用类型。
如果一个引用改变了空间中的值,对所有指向这个空间的引用都有影响?
2.基本类型的变量进行传参,实际传递的保存在变量中的常量值,这种情况叫做按值传递,针对基本类型。
如果改变一个变量的值,对其他的变量没有影响
数组:
一组相同类型的数据的集合,可以认为数据是容器。
特点:
1.存入的数据(元素)有下标,从0开始
2.容器有大小,即有长度,数组名.length---->最大下标值:数组名.length-1
格式:
元素类型[] 数组名 = new 元素类型[个数];
元素类型[] 数组名 = new 元素类型[]{元素1,元素2,.....};
元素类型[] 数组名 = {元素1,元素2,.....};
异常:
越界异常:ArrayIndexOutOfBoundsException
空指针异常:NullPointerException
int[] arr = null;
arr[0] = 20;
内存:
栈:
先进后出,方法都在栈执行,方法运行结束(return),方法就释放
堆:
1.创建的是实体容器---分配内存地址值
2.容器会存放默认值
垃圾:
没有任何引用指向的实体容器,那么该容器为垃圾。
等待垃圾回收机制(GC)处理。
引用:遍历,获取最值,求和,求平局值...
排序:
选择排序: 第0个逐步与后面每个数比,把最小放最前面;下次再用第1个逐步与后面比,
4 2 -6 9 1
2 4 -6 9 1
-6 4 2 9 1
-6 4 2 9 1
-6 4 2 9 1
-6 2 4 9 1
-6 2 4 9 1
-6 1 4 9 2
-6 2 4 9 1
-6 2 1 9 4
-6 2 1 4 9
public static int[] sort(int[] arr){
for(int i = 0; i < arr.length-1; i++){
for(int j = i+1; j < arr.length; j++){
if(arr[i]>arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
冒泡排序:相邻元素比较,如果不符合规则,则交换位置,每一轮结束都会找到当前数组中最大的元素。
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])
3,1,6,9,5
1,3,6,9,5
1,3,6,9,5
1,3,6,9,5
1,3,6,5,9
1,3,6,5
1,3,6,5
1,3,5,6
1,3,5
1,3,5
1,3
二维数组:
容器里的元素是一位数组。
动态:
元素类型[][] 数组名 = new 元素类型[元素个数][一维数组元素个数];
int[][] arr = new int[2][3]; //通俗说:大箱子里有2个小箱子,每个小箱子里有3个int类型数据
元素类型[][] 数组名 = new 元素类型[元素个数][];
数组名[下标] = new 元素类型[元素个数];
int[][] arr = new int[2][];
arr[0] = new int[3];
arr[1] = new int[2];
静态:
元素类型[][] 数组名 = new 元素类型[][]{{元素1,元素2,...},{元素1,元素2,...},....};
元素类型[][] 数组名 = {{元素1,元素2,...},{元素1,元素2,...},....};
int[][] arr = {{1,2},{3,4,5}};
特点:
数组长度:数组名.length
数组元素长:数组名[下标].length
数组最大下标值:数组名.length-1
数组元素最大下标值:数组名[下标].length-1
eclipse:
1.new - > java Project
2. ctrl + d:删除一行或多行
ctrl+alt + 向上/向下:复制代码一行或多行
alt+向上/向下:移动代码一行或多行
ctrl+/ :整行注释
3.main + alt+/ : 自动补全main方法
4.syso + alt+/ : 自动补全输入语句
类中成员:类中变量和函数
一、
面向过程:
注重强调的是过程,用角色表示可认为是执行者
面向对象:
注重强调的是对象,用角色表示可认为是指挥者
找对象–调用方法
创造对象—调用方法
类和对象的区别:
类:一类事物的相同特性(属性)和相同行为的抽取描述---class。
对象:该类事物中的一个具体的实例,通过----new
1.创建类
class 类名{
属性; —变量
行为 —方法
}
Eg:class Tool{ }
2.main函数里创建对象: 类名 对象名=new 类名(); //对象名就是变量名,
Eg:Tool tool=new Tool();
3.main函数里对象引用创建类的函数: 对象名 . 函数名(参数);
Eg: sum1=tool . getSum(scores1) ;
二、
(1)面向过程:
注重过程,可认为是执行者角色
面向对象:
注重结果,可认为是指挥者角色
找对象—调用方法
制造对象—调用方法
类和对象:
类:一类事物的共性信息的抽取定义---class
对象:该类事物中的其中一个实例---new
成员变量和局部变量区别:
局部变量:
1.定义在方法上、方法内、语句内等。
2.存放在内存中的栈中(因为函数在栈)
3.随着函数进入栈开始分配,函数出栈,则释放
4.必须有初始化值
5.只能在所属的函数内使用
成员变量:
1.定义在类中
2.存放在内存中的堆中
3.随着对象在堆中开始分配空间,随着创建对象开始分配空间,随对象空间变为垃圾被回收,则释放。
4.不赋初始化值也可以操作,因为堆有默认值
5.整个类中都可以使用
class A{
int a = 10;
public void method(){
int a = 100;
System.out.println(a);
}
}
public static void main(String[] args){ n
A a = new A();
a.method(); //输出100,这里遵循的是java的就近原则
}
匿名对象:
没有名字的对象,即没有任何引用变量所指向,例如:new Person();
1.操作属性是没有意义的
2.调用方法有点意义,只能调用一次方法,一旦该行代码结束,匿名对象成垃圾空间。
3.一般用来做参数传递:即一个对象只需要作为参数被使用一次。
引用传递和按值传递:
按值传递:
给变量赋值时,如果变量的数据类型属于8种基本数据类型,这时传递的是实际的常量值;这种数据传递的方式叫做按值传递。
使用这种方式传递数据,修改一个变量的值,对其他变量没有影响;
(byte short int long float double char boolean)
引用传递:
给变量赋值时,如果变量的数据类型不属于8种基本数据类型(也就是引用),这时传递的是堆内存中的地址;这种数据传递方式叫引用传递(按地址传递)。
使用这种方式传递数据,通过一个变量修改数据,对其他拥有这个引用的变量,都有影响;
(2)面向对象的特征:
封装 继承 多态
封装:将对象的属性或者行为隐藏起来,对外提供公共的访问方式。
private:私有的意思,权限修饰符 ,可以修饰类中的成员,只能在本类中使用。
class Stu{
private String name;
//赋值
public void setName(String name){
this.name=name;
}
//获取
public String getName(){
return name;
public void study(){
System.out.println(name+“正在学习”);
}
}
(3)局部位置和成员位置变量名重名问题:
1.this
对象的引用,谁调用了this所在的方法,那么这个this就代表谁。
应用:1在构造函数中调用其他构造函数
2.可以区分成员变量和局部变量
2.调用构造器方法
什么是构造器?
JVM创建对象时候自动调用的函数。
普通方法: 修饰符 返回值类型 方法名(参数列表){
语句;
return 返回值;
}
构造方法:
修饰符 类名(参数列表){
语句;
}
注:1.修饰符:不能被static修饰。2.无返回值类型,void也不能写
什么时候执行的?
创建对象时,自动调用与之匹配的构造器执行。
对于一个对象来说,构造方法只执行一次
构造函数作用?
主要用于创建对象时,给对象的属性进行初始化。
当类中没有定义构造方法,那么系统会提供一个构造方法,public 类名(){}确保能成功创建对象。
如果类中定义了构造方法,系统不再提供构造方法。
特点:
1.支持方法重载
2.构造函数可以调用普通函数,普通函数不能调用构造函数
3.构造函数间的相互调用,使用this(参数);语句来完成。
这个语句必须放在构造函数的第一行。
对象的实例化过程:(即创建对象过程)
Person p = new Person("张三",20);
1.在堆中开辟空间,并为该空间分配内存地址值
2.将对象的属性加载到该空间中,并赋予默认值
3.根据new关键字后边的形式找到对应的构造方法,构造方法进栈开始执行
执行前隐式3步:1.执行super()语句2.属性显示初始化3.执行构造块
4.构造方法执行完,出栈,意味着对象建立完毕
5.将空间的地址值赋值给p引用变量,p引用指向了堆中的这个实体空间
(1) System.out.println((int)(Math.random()*3+1)); //double [0.0-1.0)
(2) Scanner in =new Scanner(System.in);
// int num = in.nextInt(); //输入int类型
// String s = in.next(); //输入字符串
// System.out.println(s);
// boolean flag = true;
// String s = in.next(); //输入字符串
// if(s.equals(“y”)) //比较的是字符串的内容
// flag = false;
三、
static:
静态的意思,成员修饰符,修饰类中的变量或者是类中的方法。
修饰变量:静态变量、类变量
修饰方法:静态方法、类方法
被static修饰的成员有两种访问方式:
1.对象名.静态成员名(变量和方法)(不建议,创建对象避免造成空间浪费)
2.类名.静态成员名(变量和方法) 的加载而加载,随着类的消失而消失
静态函数特点:
1.与对象无关;即是不需要对象的,直接可以使用类名来调用;
2.优先对象进入内存中
3.静态只能访问静态,不能调用非静态函数,因为非静态函数是通过对象调用的
非静态可以访问静态也可以访问非静态
4.静态方法中不能出现与对象有关的关键字,this,super
,推理static不能修饰构造函数,因为构造函数是给对象成员变量赋初始值
5.生命周期长,随着类 静态变量:
被所有对象所共享
对于方法什么时候用static修饰,这个类是工具类或者是辅助类时,比如:Arrays,Math.
对于变量什么时候用static修饰,数据被所有对象所共享时
static String country =“中国”;
1、从保存位置:
a) 静态成员变量:方法区的静态区域
b) 非静态成员变量:堆内存中
2、从书写格式上看:
a) 静态成员变量:使用static修饰;
b) 非静态成员变量:不使用static修饰;
3、从生命周期上看:
a) 静态成员变量:类加载的时候,开始分配空间,类卸载的时候释放;
b) 非静态成员变量:创建对象的时候分配空间;对象被回收的时候释放;
4、从使用方法上看:
a) 静态成员变量:通过类名直接访问,不需要对象;静态函数同理;
b) 非静态成员变量:必须通过对象来使用;
5、从修改后的影响范围上看:
a) 静态成员变量:一旦修改,一个类的所有实例对象都会受到影响;
b) 非静态成员变量:一旦修改,受影响的只有修改它的一个对象;
所以,像圆形的圆周率这样的成员变量,一般需要定义成静态和私有的(等学习了final后,还需要定义成final的);
问:什么时候不能使用静态函数? 答:如果要使用非静态成员
代码块:
静态代码块
static{
}
放在类中成员位置上,可以定义多个
作用:用于给类进行初始化,
也可以这么说,有些工作需要在程序执行前,在类加载的时候就做,可以放静态代码块
静态成员加载顺序:
1.加载静态成员到静态区
2.加载静态变量,并根据数据类型赋默认值
3.静态变量显示赋值
4.执行静态代码块
静态变量的加载和静态代码块执行与代码的书写顺序有关。
一般情况下,为了保证运行的结果顺序不出错,通常情况都是:静态变量写在上边,下边写静态块
注意:类加载一次
构造代码块
{
}
放在类中成员位置上
优先于构造方法执行,作用是用于给所有对象进行统一初始化
如果类中有多个代码块,那么就按照顺序去执行
为什么构造代码块优先于构造函数执行?
因为在构造函数的内部隐藏了三步:
1.执行super()语句
2.属性显示初始化
3.执行构造块
其中第2步和第3步与位置顺序有关
执行时间:创建一次对象,都会执行一次构造代码块,而且在构造函数之前;
构造代码块作用:它的代码块在构造函数都会执行到,所以可将所有构造函数中都会执行的代码抽出来,放到构造代码块中。
顺序:静态代码块—构造代码块----构造函数
局部代码块
{
}
放在局部位置上,即放到函数中或者语句中
作用:控制局部变量的使用范围。
类中成员加载的顺序:
比如:Demo.class;
到方法区中找有没有Demo.class文件
1.如果找到,直接使用
2.如果没有找到,到硬盘中(如果配置了classpath,就到classpath配置的值;如果没有配置到当前目录中找)查找
1.没找到,报错
2.找到了,进行加载
1.非静态成员加载到方法区的非静态区域
2.静态成员加载到方法区的静态区域
1.静态变量默认初始化
2.静态变量显示初始化
3.静态代码块
对象的实例化过程:
比如:new Demo();
1.在堆中开辟空间,并分配地址值
2.将类中的所有非静态变量存入到空间中,并进行默认初始化
3.根据new 关键后边的代码,找到对应的构造函数,进栈执行
4.构造函数中隐藏的三步:1.super();2.变量显示初始化3.构造代码块,这三步执行完,执行函数中的其他代码
5.构造函数出栈,对象创建完成
单例设计模式:
设计模式:
通用问题的通用解决方案。
23种:
创建型:
单例设计模式:保证对象在内存中的唯一性
步骤:
1.私有化构造函数;private
2.还要有对象,因构造函数被私有,所以对象只能本类自己创建 new
为了能让别人没有对象时就能访问我这个变量,需要把变量静态化 static
为了安全,不能让人直接使用这个成员变量,需要把它私有化 private
3.要提供一个公开的方法,供别人获取这个实例; get()
为了能让别人没有对象时就能访问我这个方法,需要把方法静态化 static
四、
面向对象:
封装 继承 多态
封装:将对象的属性或者行为隐藏起来,对外提供公共的访问方式。
private:访问权限修饰符,控制属性或者是方法的访问权限,意味着是只能在本类中使用。
继承:
从一个类中创建出多个类,原有的类称为父类或者超类,基类;创建出的类称为:子类,派生类
原因:
当描述人这类事物和学生这类事物时,发现两个类中共同的属性和行为存在,即有重复的代码。
想要解决代码的重复问题。
使用继承,让类与类间产生了关系。
通过extends关键来表示类和类间的关系: class A extends B {}
子类继承了父类后:
子类相当于拥有了父类中的所有内容,构造器除外(没意义,都有自己的构造函数),私有成员(特殊)
子类还可以有自己特有的属性和行为。
注意:不能为了减少代码的编写而乱使用继承,必须是类与类间有所属关系,
即is a,子类是父类中的一种事物
特点:
一个子类只能有一个父类,一个父类可以有多个子类
在java中是一个单继承的特征,但是允许多重继承,类似于生活中的家谱
A extends B{}
B extends C{}
C extends D{}
在java中,有一个最顶级的父类,是所有对象的直接或者是间接父类----Object
继承出现后类中成员的变化:
1.变量:
子父类中出现了同名变量,建立子类对象,访问该变量,运行的是子类结果。
this: 代表的是本类对象的引用
super:代表的是父类的引用
2.方法:
子父类中出现了相同的方法的定义,但是方法体执行的内容不同,建立子类对象,调用该方法,运行的是子类的内容,这种现象称为:方法的重写或者是方法的覆盖。
*方法的重载:
在一个类中,方法名相同,参数列表不同,与返回值类型无关。
*方法重写是必须满足:
1.父类方法名和子类方法名一样
2.子类方法的权限修饰符必须大于等于父类
3.子类方法的返回值类型小于等于父类
4.不应用private修饰
5.如果父类方法是静态的,那么重写也是静态;如果父类是非静态重写也是非静态。
@Override :注解,可以用来验证是否是重写方法
override与overload有什么区别?
方法重载(overload):
在同一个类中,可以定义多个名称相同、参数列表不同的函数,叫做方法的重载(和方法的返回值类型无关)
方法重写(override):父类不满足子类要求时
在继承中,子类可以定义和父类一样的方法,在子类对象中使用的是子类中定义的方法,这叫做方法的重写;
3.构造方法:
在子类的构造器中,第一行都有一条隐藏的super()语句,它会调用父类的无参构造方法。
创建子类对象时,并没有创建父类对象,子类中只是持有一个父类的引用,即super,可以调用父类中成员。
为什么要有super()?
因为继承的属性进行初始化。子类重写父类方法,若要使用父类方法用super
Super(name,age) super.getInfo()
如果父类中没有无参构造方法,那么子类构造器的第一行,必须显示写出super(参数列表)调用父类的这个有参构造方法
或者使用this(参数列表)间接调用父类构造方法。
注意:super()和this()都是必须放在构造器的第一行,如果显示写了super就不能有this,有this了就不能写super
描述实物类:
1.属性私有化
2.构造方法
1.无参
2.有参
3.属性的get和set方法
4.用于返回对象的属性信息
好处:
1.提高代码的复用性
2.有了多态的特性
final关键字:
修饰符,表示为是最终的意思。
修饰类:表示这个类是一个最终类,不能被继承
修饰方法:表示这个方法是最终方法,不能被重写
修饰变量,既可以修饰成员变量,也可以修饰局部变量,无论修饰那个都代表是最终变量,即常量,不能被改变。 如果修饰的变量是引用类型数据,不会报错
eg : public static final double MY_PI = 3.14;
抽象类:
是一个特殊类。
具体类: 权限修饰符 class 类名{}
抽象(模糊)类 :权限修饰符 abstract class 类名{}
abstract:
修饰符,修饰类和方法,修饰符的类称为抽象类,修饰的方法称为抽象方法。
抽象类中成员:
变量,方法,构造器方法,抽象方法
特点:
1.抽象方法一定在抽象类中
2.抽象类不能实例化,即不能创建对象(因为抽象类表示本身模糊)
3.抽象类中可以没有抽象方法,目的:就是不让该类创建对象
4.抽象类是父类,子类继承抽象类后,子类想要创建对象,就必须将继承的所有的抽象方法全部覆盖;
否则子类都是抽象类。
注意:abstract不能和private,final,static组合使用
多态:
理解:一个对象具备多种形态
前提:必须有继承或者是实现
体现:父类型的引用指向子类对象
好处:提高代码的扩展性,降低代码的冗余。
弊端:不能调用子类中特有的方法。
类型转换:
向上转型(自动): Animal a = new Cat();//子类对象给赋值给父类 double b = 123;
向下转型(强转): Cat c = (Cat)a; //将父型引用转为子类int i = (int)b; (解决弊端)
由始至终创建的对象是子类对象,没有变过;而改变的是引用变量。
ClassCastException:类型转换异常 如小狗转小猫(强转)
解决强转异常:instanceof:比较运算符,结果boolean类型
判断是否是指定的类型,左边变量名(一个对象的引用),右边类名
如:if(animal instanceof Dog){
Dog dog=(Dog)animal;
dog.lookHoom();
}
使用多态创建对象特点:
编译是否通过都要看左边,即看父类能不能看到
非静态方法运行的是子类,其余都是父类结果,即运行时只有非静态函数看右边
静态成员不参与多态,因为多态和对象有关
总结:编译都要看等号左边;
运行时只有非静态函数看等号右边
五
数组:
Person[] per = new Person[5]; //多态数组
per[0] = new Student(23); //多态
per[1] = new Teacher(50); //多态
per[2] = new Person(30); //本态
接口:
特殊的类
修饰符interface 接口名{
}
成员:
常量: public static final
抽象方法: public abstract
由于是用interface定义的,所以接口中成员都是有固定修饰符的,因此,如果漏写了哪个修饰符,编译器会自动补全。
接口中的成员都是公共成员。
特点:
1.和抽象类一样,不能实例化
2.接口必须有子类,子类实现(implements)接口,子类想要建立对象,子类必须将实现的接口中的方法全部实现(重写覆盖,和抽象类类似)
类与类:单继承
类与接口: 多实现 一个类有多个接口,“,”隔开
接口与接口: 多继承
class A extends B implements C,D{}
class A extends B{}
class B implements C,D{}
作用:
1.扩展继承体系中以外的行为
2.定义规则
包:
package,相当于我们说的文件夹或者是目录
作用:
1.用于管理类文件
2.解决同名文件问题
语法:
package 包名;
位置:必须放在有效代码的最上边。
作用:告诉编译器,当前类要存放在哪里。
eg: package com;
public class Demo{
}
包名:
1.包名全部小写
2.格式: 公司域名倒置.项目名.模块名.[子模块名]*;
package com.ujiuye.cms.view;
public class Demo{
}
注意:如果类中声明了package语句,那么类名就有了限制,完整类名形式为:包名.类名
带包编译:
javac -d 目录 源文件名.java
带包执行:
java 包名.类名
import:
导入
import 包名.类名; 导入指定包中的类。
import 包名.*; 导入指定包中的所有类。
放在package下边 和声明类或者是接口的上边
public protected 默认 private
同类 - - - -
同包 - - -
不同包子类 - -
所有 -
内部类:
一个类定义到另一个类的里边,里边的类称为内部类,外部的类称为外部类。
根据书写位置:
1.成员内部类
一般成员内部类
1.不能定义静态成员(因为static特性有关,优先对象进内存)
2.可以访问所属的外部类中的所有成员,因为内部类中持有外部类的引用
私有成员内部类
1.不能定义静态成员
2.可以访问所属的外部类中的所有成员,因为内部类中持有外部类的引用
3.具备类私有的特性,意味着只能在所属的外部类中使用,外部其他不能直接访问
静态内部类
1.可以定义静态成员也可以定义非静态成员
2.只能访问所属的外部类中的静态成员,想要访问非静态成员,先创建外部类对象,再访问。
3.具备了静态的特性,与外部类的对象无关了
2.局部内部类
定义在方法中,不能使用成员修饰符修饰。
1.可以直接访问外部类中的成员。
2.想要访问所属局部位置上的变量,该变量需被final修饰才可以访问
3.匿名内部类
内部类没有名字,想要访问类中成员,因为直接创建不了对象,找父类。
前提:有继承或者实现
实质:创建子类对象
new 父类名/接口名(参数列表){
重写父类中方法;
子类特有方法
};
或 父类名 变量名 = new 父类名/接口名(参数列表){ //多态,父类引用指向子类对象
重写父类中方法;
子类特有方法
};
四
java.lang包中的类,不需要通过关键字import导入,系统自动导入该包下的类。
Object:
是所有对象的直接或者是间接父类。
boolean equals:比较两个对象是否是同一对象,即比较的是两个对象的引用
int hashCode: 返回对象的哈希值
String toString: 返回对象的字符串表现形式,格式为:包名.类名@哈希值
如果两个对象返回的哈希值相同,不能说明两个对象是同一对象,即不能说明Object类中的equals方法返回为true
如果Object类中的equals方法返回为true,说明两个对象的哈希值一定相同。
一般编写实体类:
1.私有化属性
2.添加构造方法
3.添加set和get方法
4.覆盖toString返回
(5.equals和hashCode也会覆盖)
异常:
程序运行过程中,出现了错误信息。
异常处理:
1.声明异常
用在方法上,throws+异常名,意味着谁调用有throws的方法,谁处理异常
其实并没有真正去处理异常,一直就是向上声明,交给上一级去处理
2.捕获异常
try{
可能会出现异常的代码
}catch(异常名 变量名){
处理异常的代码
}finally{
一定会执行的语句,即使遇到了return也会执行;
只有遇到了System.exit(0);(代表系统退出)不执行。
作用:释放资源操作
}
异常体系:
继承体系:
Throwable(代表java中所有异常类的最高父类):
---Exception:其他子类:编译异常,程序员需要通过代码进行处理
子类 --RuntimeException:运行时异常
---Error:错误,程序员不能通过代码进行处理
异常分类:
1.编译时异常:编译时期就检测的异常,必须做出处理
2.运行时异常:编译时期不检测,运行时检测
自定义异常:
1.java异常体系中没有定义所需异常
2.java异常体系很庞大,不方便使用
步骤:
1.继承Exception或者是RuntimeException
2.调用父类构造方法(可选)
throw:
用在方法内,主动抛出一个异常对象
如果抛出的是运行异常,可以不作出处理。
如果抛出的是编译异常,那么需要处理,处理方式一般在方法上throws
异常处理:
1.捕获异常
try{
可能出现异常的代码
}catch(异常类名 异常变量名){
处理异常代码
}finally{
一定会执行的语句,用来做释放资源操作
}
2.声明异常
throws + 异常类名,异常类名,....
用在方法上,说明这个方法有可能会出现throws后边的某一个异常,意味着谁调用谁处理。
throw:用在方法内,主动抛出一个异常对象
异常细节:
1.throws 和 throw
2.try/catch/finally可以有以下格式:
1.try/catch
2.try/catch/catch....
3.try/catch/catch..../finally
4.try/finally
注意:多个catch出现时,catch后边的异常类型从上往下看,类型可以越来越大,或者是同级类型
即:类型逐渐增大,指的是:子--子--父
3.子类重写父类方法时,如果父类方法没有throws,子类重写时不能throws编译时异常。
void show(){}
void show()throws NullPointerException,ClassCastException{}
子类重写父类方法时,如果父类方法throws编译时异常,子类重写时可以声明相同异常或者是其子类(多个)。
二、
String:
描述字符串这类事物。
该类是final类,意味着不能有子类。该类也比较特殊,只要出现了“任何内容”都做为该类的一个实例对象。
该类描述的字符串是常量,意味着以后不可以改变,因为String对象是不可改变的
String对象储存在方法区的字符串常量池中
String s=”abc”; s在内存中指向方法区中常量池中的abc字符串
String s1=new String(”abc”); s1在内存中有两个对象,一指向的是堆中new的那个对象,二指向常量池
构造方法:
String(StringBuffer buffer) :将字符串缓冲区转成String
String(StringBuilder buffer)
String():
String(String str):
String(byte[] by):将字节数组转成字符串
String(byte[] by, int offset ,int count):将字节数组中的一部分转成字符串
String(char[] ch):将字符数组转成字符串
String(char[] ch, int offset ,int count):将字符数组中的一部分转成字符串
String:
常量,不能改变
方法:
1.构造方法
2.常用方法
char charAt(index)
String substring(start,end)
String trim()
boolean equals(str)
Comparable接口:规定2个对象如何比较大小
字符串缓冲区:
缓冲区:
可以认为是容器,对其可以做增删改查四个操作。
字符串缓冲区,意味着对容器可以做增删改查操作,最终得到一个唯一的字符串常量,将其存储到字符串常量池。
StringBuffer:线程安全,jdk1.0
StringBuilder:线程不安全,jdk5.0
都是final类,可改变的字符序列。
基本类型的包装类:
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
在java.lang包,都是final类
基本类型、包装类、字符串三者之间的转换,重点学习
基本类型---》包装类:
1.包装类中的构造器方法
2.包装类中的 valueOf方法
包装类-----》基本类型
1.使用包装类中的 xxxValue()
字符串---》基本类型
1.使用包装类中的 parseXxx()方法
注意:Character类中没有这个方法.
基本类型----》字符串形式
1.使用+连接符
2.使用String类中的valueOf(num)方法
3.使用包装类中的toString(num)方法
字符串---》包装类
1.包装类中的构造器方法
2.包装类中的valueOf()方法
包装类---》字符串
1.字符串类中的vlaueOf()方法
2.包装类中重写的toString()方法
jdk5.0:针对基本类型和包装类型转换简化,有了装箱,拆箱
自动装箱:基本类型数据直接赋值给对应的包装类型的引用
基本类型---》对象形式
Integer i= new Integer(123); //原先写法
Integer i= 123;
自动拆箱:直接把包装类型引用赋值给基本类型
对象形式---》基本类型
Integer i=new Integer(123);
int num=i.intValue(); //原先写法
int num=i;
eg: Integer i2= 123;//发生自动装箱
i2=i2+456; //先i2拆箱成基本类型123,再计算和,把和再装箱成Integer对象,最后把对象地址赋值给i2.(即先拆箱,后装箱)
好处:简化了代码编写
弊端:过多使用,对性能有损耗。
Eg: //Integer数组里-128到127,用当用这些Integer类型数据时,Jvm直接去数组里找对象(不用开辟空间)
Integer i=-128;
Integer i2=-128;
System.out.println(ii2);//true
Integer i3=-129;
Integer i4=-129;
System.out.println(i3i4);//false
Integer i5=new Integer(127);
Integer i6=new Integer(127);
System.out.println(i5==i6);//false,因为有new,创立2个不同空间
正则表达式:
操作字符串的,来验证字符串是否合法等操作。
正则表达式:符号+字母+数字
Eg: \反斜线 X?:一次或0次 X*:0次或多次 X+:一次或多次
\d数字0-9 X{n}:恰好n次 X{n,}:至少n次 X{n,m}:至少n,不超m
注:1.使用转义字符表示点(.),因为.表示任何字符
String regex=”\.+”; (\转义,+代表一次或多次)
2.正则中组,叠词切割用
String regsx=”(.)\1+”(\1是规定,1是组号)
1.匹配 boolean a=s. matches(regex)
2.切割 String[] str=s. split(regex)
3.替换 String s=s.replaceAll(regex, newStr)
注:newStr,//外部其他地方想要使用正则中的组,使用$组号
4.获取
1.获取正则对象
String regex = “定义的规则”;
Pattern p = Pattern.compile(regex);
2.将正则对象与要操作的字符串相结合,得到匹配器对象
Matcher ma = p.matcher(str);
3.使用匹配器对象获取符合规则的数据
while(ma.find()){
String s = ma.group();
}
复习:
String:
常量,不可改变,可以改变的引用
常量池: 如果字符串存在,则不开辟新空间,直接使用。
常用方法:
StringBuffer/StringBuilder:
可以改变的字符序列。
append():追加
包装类:
基本类型---》包装类,Integer Character
字符串,包装类,基本类型间的转换
自动装箱和自动拆箱
Integer in = 123;
int num = in;
正则表达式:
由 字母 数字 符号 组成的有规则的字符串,可以去校验指定的字符串。
1.匹配 matches
2.切割 split
3.替换 replaceAll
4.获取
1.将正则规则封装到正则对象 Pattern p = Pattern.compile(regex);
2.将正则对象与要操作的字符串相结合,得到匹配器对象 Mathter m = p.matcher(str);
3.使用匹配器对象,获取符合规则内容, 先判断后获取 m.find(),m.group()
System:
该类final类,继承Object,不能实例化。类中方法和属性都是静态的,不需要对象。
字段:
out: 标准的输出设备
err: 标准的错误输出设备
in: 标准的输入设备
方法:
void exit(0) :系统退出
long currentTimeMills():获取当前系统时间毫秒值
Property getproperties():获取系统所有的属性名和属性值
String getProperty(name):根据name属性返回属性值
Math:
该类final类,继承Object,类中方法和属性都是静态的,不需要对象。
属性:
E :自然底数
PI:圆周率
方法:
ceil(double a):>= a 的最小整数
floor(double a): <= a 的最大整数
round(double a): 四舍五入
pow(a,b): a的b次幂
random(): 随机数
Random:
java.util
nextInt(num) :返回的是 [0,num)间的随机整数
jdk5.0特性:
1.静态导入
import 包名.类名; 导入指定的类
静态导入:导入的是静态成员(变量和方法)
语法格式:
import static 包名.类名.静态成员名;
import static 包名.类名.*;
好处:
简化了代码的编写
弊端:
阅读性变差
2.可变参数
格式: 数组类型... 变量名
eg: int... num
底层原理是:一个数组,可以按照数组的方式进行操作
注意:可变参数在方法参数列表上,只能出现一次,并且放在参数列表的最后边
3.for-each语句
for(数据类型 变量名 : 被遍历的对象(数组/集合)){
}
作用:遍历操作
java.util包
Date类:
日期类,可以精确到毫秒。该类大部分方法已过时,用Calendar类替代。
构造方法:
new Date()
new Date(long time)
DateFormat: 记:日期格式化的抽象类。 功能:完成Date对象和字符串转换
static getInstance():获取DateFormat的实例对象
Date d = new Date(); DateFormat df = DateFormat.getInstance();
String format(Date date):可以将date进行默认格式化,日期对象转字符串
String date = df.format(d); //按照默认格式,显示日期和时间
–SimpleDateFormat: 功能:完成Date对象和字符串转换,可自定义
new SimpleDateFormat(模式):当调用format方法时,可以按照指定的模式去进行格式化。
eg:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String date = sdf.format(new Date());
eg:
可以将一段表示时间日期的字符串,按照模式进行解析,解析为Date对象
String str = "2018-09-20 11:22:55";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = sdf.parse(str);
Calendar:
日历类,抽象类
static getInstance():可以获取Calendar实例对象
int get(Field):根据Field获取对应的数据
eg:
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
数组:
1.元素统一
2.长度固定
3.即可以存储引用类型也可以存储基本类型
集合:专门储存对象,
给集合保存的任何元素,都会提升为Object;从集合取出的所有元素都是Object,如果调用自身特有方法,得向下转型(强转)
1.不同类型的数据
2.长度可变
3.存储引用类型
集合框架:
java.util包:
Iterator
Collection:
—List(特有迭代器ListIterator)
—ArrayList
—LinkedList
—Vector
—Set
—HashSet
—TreeSet
Map:
—HashMap
—TreeMap
迭代器:功能:遍历集合容器的。Iterator(接口)迭代器
规则:先判断容器有没有数据,有就取出,没有就不再进行遍历
注:使用迭代器时,不能使用集合自身删除coll.remove(obj);
使用迭代器自身删除it.remove
List接口是Collection接口的子接口,继承了Collection所有方法,增加了下标
特有迭代器ListIterator(接口),比Iterator多:能从后往前,还能增删改查
jdk1.2:
Collection:
1.–List:有序可重复
(1)–ArrayList:底层数据结构为:数组,数据会在连续的空间内。查找和修改效率快,添加和删除效率慢。–线程不安全。
(2)–LinkedList:底层数据结构为:链表结构。数据可以不再连续的空间内容。查找和修改效率慢,添加和删除效率快。–线程不安全。
(3)–Vector:底层数据结构为:数组,数据会在连续的空间内。线程安全。增删改查效率都慢。(用的少)
2.–Set:无序不可重复
(1)–HashSet:底层数据结构为:哈希表算法。
元素唯一:1.hashCode(计算位置)
2.equals(比较2个对象是否相同)
(1.1)–LinkedHashSet:有序不可重复,即存取顺序一致
(2)–TreeSet:存储的元素可以按照自然顺序进行排序。
底层数据结构:二叉树
当存储自定义对象时,自定义对象不具备比较时,
1.需要实现Comparable接口,实现compareTo方法,建立比较大小的方式。
2.都是需要实现Comparator接口,实现compare方法,建立比较大小的方式。
无论使用哪种方法,都是根据实现的方法的返回值进行排序,方法的返回值是正整数 0 负整数
· 注意:
1.向TreeSet集合中存储的元素,如果是不同类型,并且没有继承关系,则不能存入
2.向TreeSet集合中存储的元素,元素有继承关系,并且父类实现了Comparable,那么集合可以存储父类和子类元素,并且可以排序。
Map:
映射,存储一对一对的数据的。 key键-value值。key不可以重复,value可以重复。
---HashMap
:key采用的哈希表算法,依赖的是hashCode和equals方法
允许null作为key和value
线程不安全
---HashTable:
:key采用的哈希表算法,依赖的是hashCode和equals方法
不允许null作为key和value
线程安全
存入的顺序和取出的顺序不一定一致。
---TreeMap
:key采用的二叉树算法,key可以按照自然顺序排序。
如果key是自定义对象:
1.自定义类实现Comparable接口,覆盖compareTo方法,建立排序方式
2.定义类实现Comparator接口,覆盖compare方法,建立排序方法。
并将实现类对象传给TreeMap的构造方法
工具类:
Collections:
Comparator reverseOrder():按照默认方式反转比较
Comparator reverseOrder(Comparator com) :按照指定的比较器反转比较
sort(List list):将list集合进行默认排序
sort(List list,Comparator com):将list集合按照器比较器方式排序
Arrays:
List asList(Object… obj):将数组转成集合
sort(数组):将数组按照默认方式进行排序
String toString(数组):将数组转成字符串
binarySearch(数组,key):二分查找指定数组中是否包含指定的key,如果包含返回key对应的下标,
如果不包含,返回负数。
Collection类中:
Object] toArray():将集合转成数组
枚举类:
jdk5.0
控制某个类能创建的对象的个数。
也是类,只不过是一个特殊的类
修饰符 enum 枚举类名{
枚举对象名
成员变量
构造方法
普通方法
抽象方法
}
泛型技术:
jdk5.0,安全机制
<元素类型>:只能写引用类型
不需要做强转了
自定义泛型:
1.泛型类:
class 类名<泛型参数名>{
}
类上定义的泛型参数在整个类中都可以使用,当创建该类对象时,才能确定泛型参数类型
2.泛型方法:
非静态方法:
修饰符 <泛型参数> 返回值类型 方法名(泛型参数 参数名){}
当调用该方法是确定泛型参数类型
静态方法:
修饰符 static <泛型参数> 返回值类型 方法名(泛型参数 参数名){}
由于静态方法不需要对象,所以不能使用类上定义的泛型
当调用该方法是确定泛型参数类型
3.泛型接口:
interface 接口名<泛型参数名>{
}
接口上定义的泛型参数在整个接口中都可以使用,当创建该接口的实现类时,才能确定泛型参数类型
interface Inter<E>{
public void a(E e);
}
class MyInter<E> implements Inter<E>{
@Override
public void a(E e) {
}
}
以上格式可以认为接口泛型具有传递性,当创建实现类对象时,确定泛型参数类型
通配符:
?:可以认为是任意类型,相当于是Object类型
泛型的限定:
上限:? extends E:代表的是能接收E类型或者是E的子类型
下限:? super E:代表的是能接收E类型或者是E的父类型
8数据位=1字节;即8bit=1byte=1B;
1024B=1KB
IO技术:
输入:程序(内存)从文件read入数据(外界数据(一般都是字节)读取到内存)
输出:程序(内存)的数据write出到文件
记忆:读入到内存,写出到文件
input,output
java.io包
IO:
File类:
描述文件或者目录的相关信息。
创建文件的方法:
createNewFile(): boolean
创建目录:
mkdir(): boolean
mkdirs(): boolean
列出:
String[] list()
File[] listFiles()
过滤器:
String[] list(FilenameFilter name)
boolean accept(File dir, String name)
dir:当前要过滤的目录
name:当前要过滤的目录其中的一个文件或者目录名
File[] listFiles(FilenameFilter name)
File[] listFiles(FileFilter pathname)
boolean accept(File pathname)
pathname:当前要过滤的目录+文件或者目录名
按照数据的流动方向:
输入流: 应用程序读取数据—read
输出流: 应用程序向某一个地方写入数据 —write
按照操作的数据:
字节流:图片,视频,音频等二进制文件
字符流:文本类型文件
IO:
按照操作的数据类型:
字节流和字符流
按照数据方向分为:
输入流 : read,应用程序从文件read入数据
输出流 : write:应用程序将数据write出到文件目的地
//字节流
//OutputStream:字节输出流的超类。定义将内存数据write出到文件的方法
//FileOutputStream:专门负责给文件中写字节数据
//BufferedOutputStream:字节输出流的缓冲区,(作用:加快写)
//
//InputStream:字节输入流的超类。定义内存从文件read入数据的方法
//FileInputStream:专门负责从文件读取字节数据
//BufferedInputStream:字节输入流的缓冲区
//
//
//字符流
//Writer:字符输出流超类
//FileWriter:写入字符文件的输出流
//OutputStreamWriter:转换流:将字符数据根据指定编码表转成字节,字符转字节的桥梁,属于输出流
//BufferedWriter:字符输出流缓冲区:newLine方法可以写一个换行
//
//reader:字符输入流超类
//Filereader:读取字符文件的输入流
//InputStreamWriter:转换流:将字节数据根据指定编码表转成字符,字节转字符的桥梁,属于输入流
//Bufferedreader:字符输入流缓冲区:readLine方法可以读取一行数据,得到是一个字符串
字节流:
输出流:
OutputStream:抽象类
:write(int)
:write(byte[])
:write(byte[] ,index,length)
:close()
FileOutputStream(目的地)
步骤:
1.创建输出流对象,并指定目的地
2.向目的地中写入数据
3.关闭输出流
输入流:
InputStream:抽象类
:int read()
: int read(byte[])
: int read(byte[] ,index,length)
:close()
FileInputStream(源头地址)
步骤:
1.创建输入流对象,并指定数据源
2.读取数据
3.关闭输入流
字节缓冲流:
BufferedInputStream(InputStream)
BufferedOutputStream(OutputStream)
int available():输入流中的方法,可以获取未读取数据的字节个数
字符流:
文本类型文件 txt
抽象类
输入流:Reader
read(),close()
---FileReader
输出流:Writer
write(),close
---FileWriter
转换流:
InputStreamReader(InputStream ,CharSetName)
OutputStreamWriter(OutputStream ,CharSetName)
当读和写两遍的编码格式不一致时
OutputStreamWriter是字符流,记得要刷新或者是关闭流
IO:
读取数据步骤:
1.根据操作数据选择对应的输入流对象,并关联要读取的文件
2.定义数组,读取数据
3.关闭流
写入数据步骤:
1.根据操作数据选择对应的输出流对象,并关联要写入数据的文件
2.向文件中写入数据
3.关闭
注意:如果是字符流,要刷新
编码:
将字符数据转成字节数据的过程,即将看的懂的转成看不懂的
解码:
将字节数据转成字符数据的过程,即将看不懂的转成看的懂的
乱码:
编码和解码的时候,使用的编码表不一致,导致再解码的时候出现的错误的数据。这些数据被称为乱码。
BufferedReader:
String readLine()
BufferedWriter:
void newLine()
装饰设计模式:
在原有对象的基础上,增强原有对象的功能。
键盘录入:
System.in == InputStream
java.util.Scanner
功能流:
Properties:(可读可写,属于map集合体系)
java.util
可以存储key-value,但是key和value必须是字符串形式
可以将Properties中存储的数据保存到文件,也可以将文件中的数据存储到集合中
SequenceInputStream:
合并流,字节输入流,可以将文件按照顺序进行读取
序列化和反序列化:
序列化:写 ObjectOutputStream,按照字节的顺序写数据;(对象持久保存)
可以将堆内存中对象直接写到文件中
反序列化:读 ObjectInputStream,按照字节的顺序读取数据
基本类型,字符串,数组,集合,包装类等对象都可以直接进行序列化
自定义对象序列化,需要实现Serializable接口,实质序列化的是对象的属性值
如果某个属性不想要进行序列化,使用static(不建议)和transient(建议)(瞬态关键字)
被序列化的类中必须添加一个版本号
与底层代码有关的一些对象不可以进行序列化,比如System,Thread
RandomAccessFile:随机访问流对象,既可以读数据,也可以写数据。
seek(position):可以跳到指定的位置,进行读写操作
getFilePointer():获取当前指针位置
PrintStream和PrintWrite:打印流
PrintStream ps = System.out;
Debug:
F6:下一步
F5:进入到方法中
F7:跳出方法
Junit:
@Test:方法测试
@Before和@After分别实在@Test执行前和执行后执行。
@BeforeClass和@AfterClass需要用在静态方法上,分别是在类加载和程序结束各执行一次
多线程:
进程:正在运行中的程序
线程:属于进程,是进程中一个可以独立运行的代码片段
进程需要依赖cpu执行,cpu某一时刻只能执行一个进程,我们看到的多个进行并发运行的现象,是因为cpu做着告诉的切换动作。
实质一个进程可由多个线程组成,cpu实质切换的每个进程中的线程。
进程中只是有一个线程-----单线程程序
进程中有多个线程----多线程程序
使用Thread的getName()获取线程名称,currentThread()得到当前对象引用
Thread. currentThread().getName()
创建线程的方式:
1.继承Thread
1.定义类继承Thread
2.在类中重写run方法
3.在main方法中,创建Thread的子类对象,并调用start方法启动线程
2.实现接口Runnable
1.定义类实现Runnable接口
2.实现run方法
3.创建Thread对象,并将实现给传递给Thread对象
4.调用start方法启动线程
建议使用实现接口方式,实现程序的多线程
继承弊端:
1.java是单继承,不能再去继承其他类
2.破坏了继承体系
多线程出现的数据安全问题:
同步代码块解决:实质:锁定操作共享数据的代码
synchronized(对象锁){
共享数据代码
}
好处:解决了多线程的安全问题
弊端:效率降低了
前提:
1.两个或者是两个以上的线程
2.使用的是同一个锁对象
单例模式:
饿汉式:弊端:如果想要使用类中的其他成员,而不需要对象时,造成空间浪费
懒汉式:弊端:多线程中不能保证对象的唯一性(可加入同步)
死锁:
程序卡到某个地方,不继续向下执行。
注意:开发中不能写出死锁。
锁的嵌套容器出现死锁。
synchronized:
修饰符,可以修饰方法,修饰的方法具备了同步的特性,也会有锁。
非静态同步方法的锁对象是:this
静态同步方法的锁对象是:类名.class
线程的生命周期:
新建状态:new Thread()
可运行状态:start(),有执行资格,等待cpu的调度
正在运行状态:执行run()
终止状态:run()结束,stop()
阻塞状态:主动放弃执行资格,cpu不再调度
JDK5将同步代码块中的锁,修改为Lock接口,自动获取和释放锁变成手动,需try{}finally{}
线程优先级:默认是5,高优先级线程的执行优先于低优先级线程。
创建的线程:可分为前台线程和后台(守护)线程
前台线程:当程序运行时,只要有任何一个线程没有运行结束,此时这个程序就不会停止。
后台线程:需要依赖前台线程存在,如果所有前台线程全部运行结束,这时不管后台线程任务是否结束,程序也会停止。
网络通信要素:
1.IP地址
DNS:域名解析成ip
本地回环地址:127.0.0.1 == localhost
2.端口号
3.传输协议:
通讯的规则
UDP:
发送方与接收方法不需要建立连接
以数据包形式发送数据,每个包不能超过64k
由于不许要建立连接,速度快, 不可靠的协议
eg:
QQ,微信,屏幕共享软件等 邮局
TCP:
客户端和服务端需要建立连接,“三次握手”
传送大量数据
由于建立好连接,速度慢,可靠协议
eg:打电话
反射:
类加载器:
其实就是一个工具,用来加载class文件
加载一个class,就会创建一个java.lang.Class对象,该对象也是反射的源头。
三个类加载器:
BootStrap --引导类加载器,加载jre\bin\rt.jar
ExtClassLoader --扩展类加载器,加载jre\bin\ext*.jar
AppClassLoader --应用加载器,加载classpath配置的类
加载器加载类时,采用的是全盘委托机制,即从子类加载器逐级向上委托,从父类向下去加载。
类记载器还有一个缓存机制:如果类加载过了,则不会再加载,而是直接使用。
反射就是把Java类中的各种成分映射成一个个的java对象(加载类,解剖出类的各个组成部分)。
变量--------Field
构造方法------------Constructor
方法---------------Method
Class:
获取类对象
1. getClass()
2. .class
3. forName()
方法
String getName():返回类名
int getModifiers:获取类所有修饰符信息
获取构造方法
1.Constructor<?>[] getConstructors()
Constructor<T> getConstructor(Class<?>... parameterTypes)
创建对象:
1.newInstance() ----Class
2.Object newInstance(Object... initargs)
2.Field[] getFields() : 公共的属性
Field[] getDeclaredFields() :所有属性
Field getDeclaredField(String name) :参数为属性名
Field getField(String name)
void set(Object obj,Object value) :obj 属性所属的对象 value:属性值
void setAccessible(true):打破私有权限
3.Method[] getMethods(): 继承和本类
Method[] getDeclaredMethods(): 本类
Method getDeclaredMethod(String name, Class<?>... parameterTypes) name:方法名 parameterTypes:参数类型
Method getMethod(String name, Class<?>... parameterTypes)
Object invoke(Object obj,Object... value))
动态代理:
目标对象
代理对象
需要:
InvocationHandler
Proxy
Lambda表达式理解:
Lambda是一个匿名函数,可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。
Lambda表达式:
从匿名类到Lambda转换
例如1:
例如2:
Lambda表达式语法:
Lambda表达式在Java中引入了新的语法元素和操作符。“->”该操作符被称为Lambda操作符或者是箭头符号,将Lambda表达式分为两部分:
左侧:指定了Lambda表达式所需要的所有参数
右侧:指定了Lambda体,即Lambda表达式要执行的功能。
语法格式1:
无参数,无返回值,Lambda体只有一条语句
语法格式2:
一个参数,无返回值
如果参数只有一个,参数的小括号可以省略。
语法格式3:
两个参数,并且有返回值
参数类型可以省略,因为可由编译器推断得出,称为“类型推断”。
如果Lambda体只有一条语句,return和大括号可以省略。
Lambda表达式无需指定类型,程序依然可以编译,这是因为javac根据程序的上下文,在后台推断出了参数类型,因此依赖上下文环境。
函数式接口:
- 函数式接口:只包含一个抽象方法的接口
- @FunctionalInterface注解检验是否是函数式接口
- 可以通过Lambda表达式创建该接口的对象。
- 自定义函数式接口
Java四大核心函数式接口:
Function:
Consumer:
Supplier:
Predicate:
其他接口:
StreamAPI:
Java.util.stream.*;
Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤、映射等数据操作。使用StreamAPI对集合数据进行操作,就类似于使用SQL语句执行的数据库查询语句。也可以进行并行操作。因此,StreamAPI提供了一种高效且易于使用的处理数据的方式。
什么是Stream?
是数据渠道,用于操作数据源(数组,集合等)所生成的数据序列。
集合讲的是数据,stream讲的是计算。
注意:
- stream自己不会存储数据
- Stream不会改变源对象。相反,会返回一个持有结果的新的stream
- Stream操作是延迟执行的,意味着等待需要结果的时候才执行
Stream操作的步骤: - 创建stream
一个数据源(如:数组、集合等),获取一个stream - 中间操作
一个中间操作链,对数据源的数据进行操作 - 终止操作(终端操作)
一个终止操作,执行中间操作链,并产生结果
创建stream方法:
在Java8中对Collection接口进行了扩展,提供了两个获取Stream方法:
- default Stream stream()
- default Stream parallelStream()
在Java8中Arrays类中的静态方法stream()可以获取数组流:
static Stream stream(T[] array):返回一个流
可以使用静态方法Stream.of(),通过显示值创建一个流,可以接收任意数量的参数。
public static Stream of(T… values) :返回一个流
可以使用静态方法Stream.iterate()和Stream.generate(),创建无限流
迭代:public static Stream iterate(final T feed,final UnaryOperator f)
生成:public static Stream generate(Supplier s)
中间操作:
多个中间操作可以连接起来形成一个流水线,除非流水线上触发了终止操作,否则中间操作不会执行任何的处理。而在终止操作时一次性全部处理,称为“惰性求值”。
筛选和切片:
映射:
排序:
Stream的终止操作:
终止操作会从流的流水线生成结果。