学习java编程 |--需要遵循其语法规范 |--在其开发环境下编程 准备开发java环境 |--安装jdk |--配置jdk jdk:含义是java提供的一套开发工具,包含jre编译器等 |--编译器(xx.java --- xx.class) |--jre(java运行环境) 环境搭建 |--JAVA_HOME=安装目录11(C:Program FilesJavajdk1.8.0_191) |--PATH = %JAVA_HOME%in jar包 |--字节码文件(xx.class)的集合 java运行源码文件步骤 --------------------------- 反编译(反编译软件:JDB) 源文件<------------------字节码文件 xx.java ------>编译------>xx.class ------------>类加载器 ------------>jre javac Test.java java Test 案例: 在桌面新建Test.java,内容如下 public class Test{ public static void main(String [] args){ System.out.println("hello world"); } } //dos下如下操作 C:UsersAdministrator>cd /d C:UsersAdministratorDesktop C:UsersAdministratorDesktop>javac Test.java C:UsersAdministratorDesktop>java Test hello world IDE |--集成开发工具 |-- |--IDEA eclise |--新建项目 |--File --> NEW -- > project --> java project -->Finish |--新建类 |--开发工具会自动编译源文件(bin) |--右击 |--run as |--application 项目的结构 |--.classpath .project .settings 这是eclipse生成的。 |--bin 字节码文件 |--src 源代码 程序入口方法 public static void main(String [] args) { } //注释 //含义:给程序员看的,一般描述当前代码的含义,方便代码的可读性。 在编译成字节码文件注释会忽略 //语法 // 单行注释 /* 多行注释 */ 文档注释 /** enter //类 //谁新建的 //时间 //作用 //方法上 //作用 //作者 //参数说明 //语法 /** * * * */ ------------------------------- //注释 //含义:给程序员看的,一般描述当前代码的含义,方便代码的可读性。 在编译成字节码文件注释会忽略 //语法 // 单行注释 /* 多行注释 */ 文档注释 /** enter //类 //谁新建的 //时间 //作用 //方法上 //作用 //作者 //参数说明 //语法 /** * * * */ java特点 |--简单 |--使用广泛 |--跨平台(一处编写处处运行) |--给不同的平台安装不同的jvm |--面向对象 |--... 关键字 |--jdk已经用的标识符 |--public void static if else .... 保留字 |--预定的,但是现在还没有使用。 标识符 |--含义:用来组成代码的符号。比如类名包名方法名变量名常量名... 组成: _ 数字 $ 英文字母 规范: 不能数字开头 中间不能有空格 类名接口名 每个单词首字母都是大写,其他小写 包名全部小写 变量名方法名,第一个单词首字母小写,其他单词首字母大写,剩余的全部小写。 常量全部大写 转义字符: 使用””把其转化成字符的本身输出,那么使用””的字符称作为转义字符。 回车 换行 ' ' " " \ ---------------------- 常量 |--含义:一旦赋值之后就不能再修改的。 |--分类 |--字面常量 10 |--final :就是在 变量 前面添加final 关键字 变量 |--含义: 变量是程序中数据的临时存放场所,并且保存的值是可以被修改的。 |--组成 数据类型 变量名 [=初始值]; |--常用操作 修改 变量名= 新值 获取 System.out.println(变量名); 比如int age = 10; age =20; //修改 System.out.println(age); //获取 |--注意 |--在同一作用范围变量不能重复定义 java |--基本数据类型 |--数字 |--整数 |--byte short int long 区别范围不一样,语法 |--小数点 |--float double |--布尔型 |--boolean |--字符 char |--引用数据类型(对象类型) |--类 |--数组 |--String |--... 运算符的种类: 赋值运算符:=、+=、﹣=、*=、/=、%= 算术运算符: +、﹣、*、/、%、++、 -- 比较运算符:>、<、>=、 <=、= =、!=、instanceof ==用法 |--用于比较基本数据类型,值是否一样 |--用于比较引用数据库类型,比较是否同一个对象(即:比较对象的内存地址) String str1 = new String("str"); String str2 = new String("str"); System.out.println(str1==str2);//false,因为new会开辟一块新的内存 instanceof 用于比较某个对象是否属于指定的类型 String str1 = new String("str"); System.out.println(str1 instanceof String); 逻辑运算符:!、&&、|| 操作数都是boolean型 案例 boolean sign = ! true; boolean sign = true && false; boolean sign = true || false; 位运算符: &、|、^ 、 ~、>>、<<、>>> 三目运算符: 表达式 ? 成立:不成立; int count = 29; int pageSize =10; int page = count%pageSize ==0 ? count/pageSize:count/pageSize+1; 数据类型转换 |--自动类型转换(存储范围较小的转成范围较大的) byte -- > short --> int -- > long -- > float --> double |--强制类型转换(存储范围较大的转成范围较小的) 注意了:可能造成数据溢出 int a = 10; byte b = (类型)a; 自动类型提升 |--byte short char int 类型的操作数进行运算符操作结果类型都是 int |--类型较小和类型较大的结果类型是较大的 案例 byte a = 1; a = a+1; //报错吗?为什么? byte a = 1; a +=1; //报错吗?为什么? 快捷键 |-- main + alt + / |--syso + alt + / |--快速运行main ctrl + f11 |--复制光标|选中 ctrl + alt + 上或下箭头 |--移动光标|选中 alt + 上或下箭头 |--多行编辑 alt + shift + a |--单行注释 ctrl + / |--多行注释 添加 ctrl + shift + / 取消 ctrl + shift + |--ctrl + z |--ctrl +1 快速修复 条件结构 if(){ } if(){ }else{ } if(){ }else if(){ }else{ } 作业 // && &区别 // || | 区别 //前置++ 后置++ 区别 //== //instanceof 含义 //类型如何转换 //JAVA如何实现跨平台 //自行定义常量、变量 //你知道的命名规范有哪些 //如何导入项目 //如何到处可执行jar文件 //eclipse设置 //设置全局编码 //调整文字大小 day3 switch |--含义: |--语法 switch(需要比较的值){ case 具体值1: //... break; case 具体值2: //... break; default: break; } |--执行流程 |--先匹配case,匹配到了执行case里面的代码,直到遇到break 或者 switch结束 注意 |--default可以放在case前面,也可以放在后面,建议后面 |--case default 建议加上break; |--switch能用在byte short char int |--String可以可以,但是需要1.7以上版本 循环 while(条件){ 循环体 } do{ 循环体 }while(条件); for(初始化一次;条件;每次循环之后执行的操作){ } 死循环 while(true){ 循环体 } do{ 循环体 }while(true); for(;true;){ } 控制 |--break; //终止当前循环 |--continue; //跳过当次循环,进行下一次 循环嵌套 |--循环包含循环 |--比如:99乘法表 TODO |--如何结束最外层循环 |--内层控制外层的循环条件 |--标签 label:for for break label; 一维数组 |--含义:存放相同数据类型的容器。内存是连续的。 |--创建的方式 |--数据类型 [] 名称; |--数据类型 [] 名称 = new 数据类型[大小; |--数据类型 [] 名称 = {元素1,...}; |--注意:创建的数组对象是存放在堆中的,数组名是放在栈中的(数值就是数组对象的首地址) |--常用操作 |--获取长度 数组名.length; |--获取System.out.println(数组名[下标]); //下标从0开始 |--修改数组名[下标] = 新值; |--常见异常 |--数组下标越界 |--空指针异常 |--循环 for(){ } 增强for |--作业 |--元素交换 二维数组 |--一维数组中元素又是一个一维数组;行和列组成 |--创建方式 |--数据类型 [][] 数组名; |--数据类型 [][] 数组名 = new 数据类型[行][列]; //行:一定要写 //列:可以不写 //如果不写:每一行都是null //如果写:每一行的列是固定的,不是null的 |--数据类型 [][] 数组名 = {{元素1,...},{元素1,...},...}; //每一行,列个数可能是不一样的 |--常见操作 |--获取多少行:数组名.length |--获取指定行的列数:数组名[指定行].length |--常见异常 |--数组下标越界 |--空指针异常 |--作业 从随机构造班级学员成绩,找出全班学员的最高分平局分 数据类似如下 [31,98,98,78,6,71,87,98] [85,58,98,78,6,72,87,98] [51,98,98,78,6,73,87,98] [61,88,68,78,6,74,37,98] [81,38,98,78,6,77,97,98] 知识点 |--Math随机生产整数 |--二维数组定义 |--二维数组数据的访问修改 |--二维遍历 -------------------------------------------------- 冒泡排序 |--原始数据9 2 5 4 |--过程 第一趟 2 5 4 9 第二趟 2 4 5 9 第三趟 2 4 5 9 查找算法 |--顺序查找 {1, 2, 3, 4, 5} 4所在的位置 |--二分查找(折半查找) {1, 2, 3, 4, 5} //有顺序 小-->大 4所在的位置 思路: 取中间值3 ,因为3!=4 && 4>3;所以下标从3开始到4结束。 ------------------------------------------------------ 方法 |--含义:处理某一个功能的代码集合。 |--好处:可以重复使用。 |--定义语法 范围修饰符 其他修饰符 返回类型 方法名([参数类型 参数名,....]){ //形参 方法体 [return 返回数据] } //入口 public static void main(String [] args){ } 范围修饰符:public private protected 不写 其他修饰符:static final synchronized 返回类型是java的数据类型其中一个 方法名:合法标识符 参数类型是java的数据类型其中一个 参数名:合法标识符 返回数据:必须和返回类型匹配 |--方法调用 方法名(实参,实参N,...); 类型 变量名 = 方法名(实参,实参N,...); |--return |--方法调用结束了。方法结束。 |--return的数据类型要和返回类型匹配 方法调用的本质 |--方法的入栈和出栈的过程。 递归 含义:有限次数的自己调用自己,如果调用的深度太深容易造成栈溢出 //方法重载 |--在同一个类中,方法的名字相同 |--必须满足如下条件 |--方法名字一样 |--参数不同 |--参数个数 |--参数的类型 |--与方法的返回类型没有关系 //面向过程 //含义: 实现一个功能的一组命令组合成为一个函数; //遇到的问题 当项目庞大的时候,函数越来越多,很容器造成命名冲突。不适合大型软件开发。 //面向对象 //含义 从现实世界中客观存在的事物出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以问题域中的事物为中心来思考问题,认识问题,并根据这些事物的本质特点,把它们抽象地表示为系统中的对象,作为系统的基本构成单位。 抽象 |--含义:只关注与处理问题相关的。 对象 |--含义:具体存在的事物。 类 |--含义:对 对象的一种分类。具有相同属性和行为。对象是类的一个实例。 //类的定义 //含义: //如何定义 //范围修饰符 其他修饰符 类名{ 0-N个属性描述; 0-N个方法描述; } //对象 //含义:类的具体存在的事物。 //常用操作 //创建对象 //设置||获取属性值 //调用对象的方法 //打印对象 //对象比较 //成员变量和局部变量 ------------------------------------------- 冒泡排序 选择排序 |--含义:选择指定位置的元素,然后将它和后面的依次比较,如果 大于 的话,就交换位置。经过一轮可以确定最小值。 2 3 1 0 一轮 2 3 1 0 1 3 2 0 0 3 2 1 二轮 0 3 2 1 0 2 3 1 0 1 3 2 三轮 0 1 3 2 0 1 2 3 --------------------------------------- 二分查找 |--前提:要有顺序 |--含义:.... 构造器 |--含义:创建并返回对象初始化对象;是一个特殊的方法 |--语法 |--修饰符 类名([参数1,...]){ 初始化逻辑 } |--特殊 |--不能return 任何数据。 |--构造器名字必须和类名一样 |--不能有返回类型,包括void 默认构造器 |--含义:自带的无参构造器,如果添加了其他构造器,默认的构造器就会失效。 |-- 匿名对象 |--含义:没有名字的对象 || 没有在栈中引用的对象; |--特点 |--只能使用一次,并且使用之后就变成垃圾对象,GC就会回收。 this |--含义:当前对象本身 |--使用场景 |--调用构造器 |--方法链 |--方法参数的二义性 GC |--Garbage Collection,是JVM中优先级较低的线程,用于回收在 堆中 没有引用的对象; |--如下场景会被回收 Persion p = new Persion(); p=null; new Persion().say(); 超出作用范围 if(true){ Persion p = new Persion(); } |--当GC回收对象的是,会先调用对象的finalize方法 |--System.gc(); //让GC执行一次回收操作。 static修饰符 成员变量细分 成员方法细分 变量细分 & 生命周期 变量类型 存放位置 生命周期开始 生命周期结束 -------------------------------------------- 作业 什么是类?什么是对象?类和对象的关系? 类是属性行为相同的方法集合的地方。 对象是通过类实例化出来的 构造器含义?构造器可以重载吗? 含义:每一个类都有一个构造器,创建并初始化对象的一种特殊方法 可以重载,但是必须不同参数类型和数量 this 含义?使用场景?并编写案例 含义:当前对象 场景:调用构造器 方法参数的二义性 this.age=age 方法链 public 类名 add(int param) { result = result+param; return this; } new 类名().add(1).add(2).add(3); super含义?使用场景?并编写案例 含义:调用本类的父类构造器 场景:当子类 继承 父类 时,需要用到super来继承父类的构造器 当父类构造器已被修改为有参构造器时,子类继承时也要改为super(参数) static修饰符可以修饰什么?什么是类级别方法?什么是对象级别方法? 修饰: 属性 代码块 方法 static属于类级别方法 封装的理解 通过在类中给变量赋予私有变量private,在加上调用setter和getter方法,实现隐藏代码,对输入输出进行限制,只允许用户调用方法来操作变量,增加安全性 继承的理解 方法重写含义?注意点有拿些? static{ } 和 {}的区别 前者加载类时就实现一次,后者调用对象一次就实现一次,后者可以实现多次 抽象类和接口的区别 抽象类 下的抽象方法,在子类中若继承了父类抽象类,则必须实现父类提供的方法,否则自身变为抽象类 抽象类不能被实例化 抽象方法不能加static 因为会需要子类的重写 抽象类中可以全部为抽象方法,也可以不一定全是抽象方法 抽象类有构造器 接口 可以实现多继承 即interface A extends B,C ().... 若一个类要实现某一个接口,则必须实现它的所有抽象方法,否则这个类就变成抽象类 多态含义?,实现机制?自行编写案例 同一个接口,使用不同的类进行不同的操作即为多态 单例含义?自行实现一个饿汉式案例 使得一个类只能被访问一次,打印出的地址都为一个样 GC是什么? 垃圾回收机制,jvm线程会在创建的对象无用时对其进行回收即自动释放,gc作用于堆内存,于栈无关 1、定义一个点类Point, 包含2个成员变量x、y分别表示x和y坐标, 2个构造器Point()和Point(int x0,y0), 以及一个movePoint(int dx,int dy)方法实现点的位置移动, 创建两个Point对象p1、p2,分别调用movePoint方法后, 打印p1和p2的坐标。[必做题] 2、定义一个矩形类Rectangle: [必做题] 2.1 定义三个方法:getArea()求面积、getPer()求周长,showAll()分别在控制台输出长、宽、面积、周长。 2.2 有2个属性:长length、宽width 2.3 通过构造方法Rectangle(int width, int length),分别给两个属性赋值 2.4 创建一个Rectangle对象,并输出相关信息 3、定义一个笔记本类,该类有颜色(char)和cpu型号(int)两个属性。 [必做题] 3.1 无参和有参的两个构造方法;有参构造方法可以在创建对象的同时为每个属性赋值; 3.2 输出笔记本信息的方法 3.3 然后编写一个测试类,测试笔记本类的各个方法。 4、定义两个类,描述如下: [必做题] 4.1定义一个人类Person: 4.1.1定义一个方法sayHello(),可以向对方发出问候语“hello,my name is XXX” 4.1.2有三个属性:名字、身高、体重 4.2定义一个PersonCreate类: 4.2.1创建两个对象,分别是zhangsan,33岁,1.73;lishi,44,1.74 4.2.2分别调用对象的sayHello()方法。 5、设计一个类Student,该类包括姓名、学号和成绩。设计一个方法,按照成绩从高到低的顺序输出姓名、学号和成绩信息。 6、定义一个汽车类Vehicle,要求如下:[选做题] 6.1属性包括:汽车品牌brand(String类型)、颜色color(String类型)和速度speed(double类型),并且所有属性为私有。 6.2至少提供一个有参的构造方法(要求品牌和颜色可以初始化为任意值,但速度的初始值必须为0)。 6.3为私有属性提供访问器方法。注意:汽车品牌一旦初始化之后不能修改。 6.4定义一个一般方法run(),用打印语句描述汽车奔跑的功能 6.5定义测试类VehicleTest,在其main方法中创建一个品牌为“benz”、颜色为“black”的汽车。 ------------- final |--常量 |--含义:类、定义常量、方法名 | |--含义:该方法不能被子类重写 |--含义:该类不能被继承 static |--含义:修饰的都属于类级别 |--可以直接通过 类名.来调用 |--修饰内容: |--方法名 |--类名. |--对象. x |--成员变量 |--成员常量 |--类名 继承 |--含义:把相同的属性、行为提取到父类,子类通过继承就可以获得父类的属性、方法 |--注意点 |--单继承 |--一切类直接或者间接的继承了Object 方法重写: |--含义:父类方法不满足子类的要求。 |--注意点 |--@overried注解表示,当前方法是重写父类的 |--重写方法的范围修饰符要>=原来的。 |--不能抛出比父类更大的异常 |--静态方法不能重写 |--final修饰的不能被重写 this |--含义:当前对象 |--使用场景 |--构造器之间调用 |--避免参数二义性 |--构造方法链 |--TODO super |--含义:父对象 |--使用场景 |--调用父类的构造器 |--调用父类的方法 |--调用父类的属性 封装 |--含义:隐藏内部实现,对外提供公共的方法。 |--如何实现 |--属性设置成private的,如果外部能设置就提供setter、如果外部需要获取就提供getter方法 |--范围修饰符能越小就越小 |--boolean 不要is开头 抽象类 |--含义:具体子类 一定 要实现父类的抽象方法. |--因为:不同的子类有不同的实现。将其实现放在父类是不合理的。 |--语法 abstract class 抽象方法 |--没有方法体的方法,抽象方法必须在抽象类中. |--语法 方法的返回类型前 abstract,并且该方法没有{}; 注意点: |--抽象类不可以是final,抽象方法不可以是final, |--抽象方法不可以是static |--抽象类可以没有抽象方法;但是抽象方法一定是在抽象类中 |--抽象类的构造器不能否全部都是私有的 |--抽象类可以有普通方法 |--具体子类是通过继承(extends) 接口 |--含义:特殊的抽象类 |--没有构造器 |--没有普通方法 |--全部方法都是抽象的 |--不能有成员变量 |--注意点 |--全部方法都是抽象的,并且修饰符 public abstract |--属性修饰符都是 public static final |--不能直接new |--具体子类是通过实现(implements) 如何选择? |--接口优先 多态 |--含义:一个事物多种状态;只有运行的时候才能确定。 |--原理 |--实现接口 |--通过继承 子类实例过程 |--含义:调用子类的构造器,会先调用父类的构造器创建父对象,然后在创建子对象。 单例 |--含义:在程序运行期间最多只会创建一次。 |--方式 |--饿汉式 |--私有的构造器--->避免外部重复new |--定义一个private static final 常量 |--对外提供public static 获取实例的方法 |--懒汉式 代码块 |--普通代码块 { //创建一个对象都会执行一次 } |--静态代码块 static{ //只会执行一次,类加载的时候 } 内存模型 |--含义: |--堆:存放对象的;(数组,User,字符串,...) |--栈:变量名 GC |--含义:Garbage Collection 是一种优先级较低的线程,会检查堆内存中没有被引用的对象,然后回收。 ---------------------------------------------------------------------------- Object |--含义:一切类的根类。 |--常见的方法 |--hasCode //根据对象的地址计算出来的。 //hasCode //含义:返回对象的哈希码值(是根据对象存放的地址),编号 //同一个对象多次调用hasCode值都是相同的。 //多次启动程序创建的同一个对象那个hasCode可能不一样。 |--equals //里面是==实现的 //一般情况会重写上述两个方法 //source-->equals hasCode |--Class clazz = getClass(); //获取的是字节码对象<----字节码文件 |--finalize //当GC回收对象会调用该方法 |--toString //打印对象 //本质打印对象.toString(); //com.neuedu.day04._01ObjectDemo@15db9742 |--类名(全限定名) com.neuedu.day04._01ObjectDemo |--简单名 _01ObjectDemo 包装类型 |基本装拆 //基本类型 变成 包装数据类型,装箱 Byte data2 = Byte.valueOf(temp); //包装类型 变成 基本数据类型,拆箱 byte data3 = data2.byteValue(); |-- 自动装拆 byte data4 = 10; Byte data5 = data4; //自动装箱 data4 = data5; //自动拆箱 |--面试 //有了基本数据类型,为什么要有包装数据类型? //包装数据类型的默认值,可以表示特殊的含义 //包装数据类型提供了其他api //解析字符串为基本数据类型:parseXX |--工具类 |--String类 //字符串 //本质:final的字符数组 //final修饰的,不能被继承 //字符串是不可变的 String str1 = "test"; String str3 = "test"; //因为有缓存功能,所以str1==str3,比较内容时可以用equal |--常用的方法 //equals equalsIgnoreCase //trim //startsWith //endsWith //replace("old str","new str") //contains //substring //indexOf //lastIndexOf //length //charAt |--stringbuilder //常用api String //SB.toString() //SB.append //SB.length() //SB.substring(start) //SB.indexOf(str) //SB.lastIndexOf(str) //SB.delete(start, end) //SB.deleteCharAt(index) //SB.replace(start, end, str) //SB.reverse //StringBuilder //含义:内容可以改变的字符串 |--stringbuffer //StringBuffer 和 StringBuilder //含义和方法基本上一样 //区别 //StringBuffer的方法有synchronized修饰 |--math //Math.ceil(x)大于x的最小整数 //Math.floor(x)小于x的最大整数 //math.round(x)正数-》四舍五入,负数-》+0.5后向下取整 //Math.round(-6.4)); 日期 //日期 //Date 不用了 //Calendar //Calendar cal = Calendar.getInstance(); 当前时间的日历对象 //SimpleDateFormat //创建方式1 //SimpleDateFormat simpleDateFormat = new SimpleDateFormat(); //simpleDateFormat.applyPattern(pattern); //创建方式2 //SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd HH:mm:ss"); //使用2 Date date = new Date(); simpleDateFormat.format(date);//将date格式化//2019年07月21 16:29:41 String result = simpleDateFormat.format(date); date = simpleDateFormat.parse(result);//将格式化后的时间进行解析2019-7-21 23:13:32 数组 //Arrays //含义:提供对数组的常用api //常用api //toString 数组转成字符串 //binarySearch 负数说明不存在 //copyOf 复制 //copyOfRange //sort 排序 异常 //ClassNotFoundException 什么类型的异常 //运行时,非检查RunTimeOutException 经验高质量代码解决 //非运行时,检查,可能产生该异常,则必须写出相应的处理代码,否则无法通过编译 //ClassNotFoundException 异常 |--含义:代码出错了 || 有可能出错。不是语法错误。 |--体系结构 Throwable |--Error (非常严重) |--栈溢出 // |--内存溢出 // |--.... |--Exception |--RuntimeExcpetion |--含义:非检查异常,代码运行着就报错了,往往都是代码不严谨。 |--方案:代码严谨性 |--常见的 |--算术异常 0/0 |--数组下标越界 |--空指针异常 |--非RuntimeException |--检查异常 |--含义:代码有可能会错误,所以要处理这些错误。不处理编译不通过。 |--处理方式 |--自行处理 try catch try finally try catch finally |--抛出 throw e 在方法声明后面throws 异常种类 //自定义异常 //含义:果Java提供的异常类型不能满足程序设计的需要,我们可以定义自己的异常类型。 //方案: |--继承Exception |--继承RuntimeException ------------------------------------------------------------------------------------------ 串行 |--含义:强调按照顺序执行 并行 |--含义:同一时刻多个事物一块执行。 并发 |--含义:一段时间范围,多个事物执行。 //时间段 单个cpu,一遍听音乐,一遍写代码, |--微观角度不行, |--宏度角度可以的。 //cpu调度 //进程 //含义:正在运行的软件 //一个软件可以可以有多个进程 //特点 //有自己独立内存,进程独享. //开软 //一遍音乐 //打游戏 xx |--音乐进程 |--游戏进程 |--聊天进程 |--.... 线程 |--含义: //执行索引(分之)。 |--使用场景 //多个任务,比如:批量发送邮件 //多线程文件下载: TODO //模拟多个人抢票 //.... |--如何创建 |--extends Thread |--implment Runnable //有线程安全问题 |--区别 |--通过继承方式不能共享同一份资源;通过实现接口方式是可以的。 |--通过实现接口方式有线程安全问题 |--java是单继承的,第一中方案不能在继承其他类,第二种方案是可以的。 // 概念 |--串行:多个事物依次执行。 |--并行:同一时刻多个事物一块发生。 |--并发:一段时间内多个事物发生。 |--进程:一个正在运行的软件(程序);都有自己 独立 的内存空间; //可以有多个进程。 |--线程:执行的索引(分之);没有独立的内存空间;不能脱离进程。 |--创建方式 |--extends Thread |--implements Runnable |--区别: //继承方式不能独立共享资源;实现接口方式可以 //实现接口方式可以继承其他类。 //实现接口方式可以共享资源,所在修改资源的时候会有线程安全问题。 //如何处理 //监视对象,监视同一时刻只能有一个线程修改资源 //同步方法 synchronized //static 字节码对象 //非static this //同步代码块 synchronized(this||字节码对象){ } //锁 try{ }finally{ //释放锁 } |--api getName getId Thread.currentThread(); //获取当前线程 setProirity //设置优先级 (1 5(default) 10) getProirity //获取优先级 join() //加入 interrput //中断 Thread.sleep(long millstime); 睡眠,不会释放锁 Object wait wait(long mills) notify notifyAll |--生命周期 |--生产者 VS 消费者 -------------------------------------------------------------- 集合 |--Map |--HashMap |--LinkedHashMap |--TreeMap |--HashTable |--Properties |--Set |--HashSet |--TreeSet |--List |--ArrayList |--含义:封装了对数组的常用操作,底层采用变长数组来存储数据。 |--LinkedList |--Vectory |--Stack |--Queue |--Deque -------------------------------------------------- 数组 [1,2,3,4,6,7] |--特点 //大小固定;下标查询快;修改快;插入慢;删除慢; |--操作 |--删除:手动移动元素 |--添加:手动移动元素 |--... class ArrayList{ private Object datas[]; private int size; //元素个数 public ArrayList(){ datas = new Object[10]; } //datas 添加一个数据 public void add(Object data){ //... if(size==10){ //扩容 datas = Arrays.copy }else{ //继续添加 } } public Object get(int index){ //... } //.......都是操作数组 } Collection |--Set |--HashSet 含义:Hash--->hasCode |--LinkedHashSet |--底层采用LinkedHashMap |--List |--LinkedList 链表 |--查找、更新慢 |--删除|添加快 |--Queue |--Deque |--Map |--HashMap |--LinkedHashMap |--Hashtable |--Properties |--可以加载配置 |--ArrayList |--SortedMap |--TreeMap 采用二叉树(红黑树) 二叉树 |--含义:采用红-黑树存储数据结构 |--api |--基本HashMap一样 |--注意点 |--要提供一个比较器或者key要实现Comparable接口 |--key |--有序,顺序和compareTo || compare 返回-1 或者 1有关系 不可以重复 |--重复的依据是compareTo || compare 返回0 |--添加的元素有没有顺序 |--Set |-- 集合 |--存放对象 |--存放对象的引用 VS 数据 ArrayList HashMap |--Vector |--方法基本上和ArrayList一样,线程安全的 回顾 ---------------- 集合 |--Collection |--List |--ArrayList:底层采用数组,是一种变长; [有序可以重复] |--Vector(线程安全的) |--Statck |--Queue(单向队列) [有序可以重复] |--Deque(双向队列) |--LinkedList(链表) 双向链表(TODO 是否循环链表) (implements List) |--Set |--HashSet(底层采用HashMap来存储的)【无序】 |--LinkedHashMap(底层采用LinkedHashMap来存储的) 【有序】 |--TreeSet .... ---------------------------- |--Map |--SortedMap 【有序】 |--重复的依据:比较返回0 |--TreeMap 【api和HashMap几乎一样】 [有序,key不可以重复] |--注意:因为需要排序,所以需要比较 |--方案一:构建TreeMap的时候传递一个比较器 |--方案二:key必须实现Comparable接口 |--hasCode一样,equals返回true |--HashMap (哈希表:存储结构数组+链表)链表:什么情况下会产生?? 【无序,key不可以是重复】 添加hasCode对应的位置有元素,但是他们两个的equals返回为false |--LinkedHashMap【有序】 |--Hashtable【无序】 syschronized |--Properties //HashMap Hastable //Hashtable是重量级的HashMap,线程安全 //HashMap的key 和 value都可以是null,Hashtable是不可以的。 //都是无序的,都实现了Map接口 ------------------------------------------------------------------------------------ ---------------------------------------------------- 泛型 |--含义:参数化类型,类型用一个参数来表示,可以确定操作数据的类型。 |--作用 |--确定数据类型 |--避免强转 |--用法 |--类接口方法返回类型方法参数 public MyArrayList<T extends BaseDTO>{ //T进一步约束,代表T 一定是BaseDTO的子类 public void add(T t){ } public T get(int index){ return null; } } |--其他用法 List<? extends XX> //? 是XX本身或者是XX的子类 List<? super XX> //? 是XX本身或者是父类 |-- public static <T> T get() { Object obj = "xx"; return (T) obj; } IO |--File |--含义:文件或文件夹 |--api |--如何创建对象 |--获取文件名 |--获取绝对路径 |--创建文件 |--判断是否存在 |--删除文件 |--判断是文件还是文件夹 |--列出子文件 |--FileInputStream |--read() |--read(byte [] temp) |--close |--FileOutputStream |--write |--close |--字符流(一个一个字符读取) Reader |--FileReader |--BufferReader //可以一行一行 Writer |--FileWriter |--BufferWriter //思路 //cope 创建输入流 input 字节 创建输出流 output //复制的逻辑(边读边写) int len = -1; byte [] temp = new byte[1024]; // while((len=input.read(temp))!=-1){ output.writer(temp,0,len); } //io //socket //swing // ----------------------------------------- Server |--ServerScoekt SS = new ScoektServler(8080); Socket socket = SS.accept(); //等待客户端连接 socket.getInputStream(); socket.getOutputStream(); //将数据响应给客户端 //自行关闭 Client |--Socket socket = new Socket("127.0.0.1",8080); socket.getInputStream(); socket.getOutputStream(); //将数据响应给客户端 //自行关闭