1. for(int=1; i<=10;i++``){syso} |
|
2. for 和 while 的区别:for里的int 是在括号里的,在循环内部,会被自动回收,提高内存使用效率。 while 里的int变量是不会被回收的。![截图区别]() |
|
| 3. do while: 先执行后判断,至少执行一次。 |
|
| while:先判断后执行 |
|
| # 补充 |
|
| - 八大基本类型:1.整数:long short int 2. 小数 float double 3.字节:byte 字符:char 布尔值:boolean |
|
- float和double不能放在一起 float a=2.33f; double b=2.33; |
|
| - long有八个字节,int有四个 |
|
- long c=5; int d=(long) c; 强制类型转变 |
|
| - 1byte=8bit |
|
| - 强制类型转变: 类型 变量名=(要被转化的类型)值 |
|
如:int a=(long)10; |
|
| - break:结束当前循环 注:多层循环需要添加标签,标明跳到哪 |
|
| - continue:跳过当前循环 |
|
| - return:结束一个方法,结束所有 |
|
| - i++:先执行再加一次 ++i:先加一次再执行 |
|
- ![图片]() |
|
- 比较大小的图片 ![图片]() |
|
| # 短路效应 |
|
| - &&:双个代表只会判断前一个,若符合条件则后一个不会被执行,容易造成短路效应 |
|
| - &:单个的前后两个都会执行一次 |
|
| - ``` |
| int a=1; |
| int b=1; |
| if(a++>0 |
| System.out.println(a); |
| System.out.println(b); |
| } |
| ``` |
|
|
|
|
| # 字符图片代码 |
|
![tupian]() |
|
| ## 画笔工具 |
|
![TUPAIN]() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| # java概述 |
|
| 面向对象的编程语言 |
|
| ### JDK与JRE |
|
| - JDK:JAVA的开发和运行环境,JDK是给开发人员用的,其中包含了JAVA的开发工具以及JRE,所以安装了JDK就不用安装JRE了。 |
| - JRE:JAVA的运行环境,其中包括虚拟机和JAVA程序所需的核心类库等,如果想要运行一个开发好的JAVA程序,电脑就只需安装JRE。 |
| - 虚拟机:JAVA运行的所有变量都是跑在内存上的,虚拟机就是在实际内存上开辟一块区域,所有的JAVA程序都是运行在虚拟机上的,与电脑的实际操作系统无关,所以JAVA就可以在各种系统中运行 |
| - 各种操作系统的CPU处理方式不同,内存设计不同导致同一个程序不能在各种操作系统中运行,所以就出现了虚拟机的功能 |
|
| ### JAVA三个体系 |
|
| - JavaSE--------标准版 开发客户端 ,并不能做网站 |
| - JavaEE--------(Enterprise Edition)企业版、网站、服务端 EE包含SE |
| - JavaME-------移动端 |
|
| ### JAVA与C++的不同及JAVA的优点 |
|
| - C++是面向过程的编程语言 |
| - JAVA可以 垃圾自动回收 |
| - JAVA可以 多线程(多个任务同时进行) |
| - 跨平台(环境不同一样可以运行),一次编译,到处运行 |
|
| ### JAVA环境安装 |
|
| - 找到环境变量,编辑系统变量 |
| - 变量名命名为:JAVA_HOME |
| - 变量值为JDK的下载路径,进入到能看到bin的目录,不进bin |
|
| - 修改系统变量中的path,复制:%JAVA_HOME%\bin 及 %JAVA_HOME%\jre\bin |
| - 注:WIN7两句话需要用分号隔开 |
|
| - 验证是否安装完成,打开小黑窗,分别输入java javac |
|
| - eclipse安装企业版的,就是Enterprise |
|
| # Eclipse基本使用方法 |
|
| - 隐藏左方行数:空白区域,右键————Show Line Numbers |
|
| - 挑选最下方的视窗: Window--Show View |
|
| - 格式化:Source----Format |
|
|
|
|
|
| # 小知识点: |
|
| - 自己写的代码是 .JAVA,经过编译之后是 .class |
| - 输出语句中 System.out.println();的换行,是在打印完括号内的内容后才进行换行 |
| - 自己命名的标识符不能用数字打头,且不能是JAVA里的关键字(如: int int=1),这样是不行的 |
| - 在使用long时,如果超过了Int的表示范围,即超过21亿的范围,需要在赋值后面加上大写L(如:long a=222L),小数的float在赋值时也需要加上f。 |
| - a++与++a: |
| - a++是先执行一次a,再对a进行加一 |
| - ++a先对a进行加一,再执行a |
|
| - 快捷键:ctrl+alt+↓是快速复制选中行 Ctrl+d是删除 Alt+↑是往上对调换位置 |
|
|
|
|
|
|
|
| # 八大基本类型 |
|
| - 整数: |
|
| - short 2个字节,默认值0 ,占8个bit |
| - int 4个字节,默认值0, 占16个bit |
| - long 8个字节,默认值0L,占32个bit |
|
| - 小数: |
|
| - float 4个字节,默认值0.0f |
| - double 8个字节,默认值0.0d |
|
| - 字节: byte 1字节,默认值0,表示范围为 -128~127 |
|
| - 一个字节占8位,最大值127用二进制表示为 0111 1111,(即:1+2+4+8+16+32+64=127)第一位表示正负号:0为正,1为负 |
|
| - 最小值-128用二进制表示为:1000 0000 这个二进制表示128,同时第一位为1,表示负的,所以是-128 |
|
| - 举例:127加2之后是-127 |
|
| - 如:127的二进制是0111 1111,加1之后1000 0000是128,但是一个字节只有8位,不能再往前进1,二进制的第一位表示正负号,所以变成了-128,这时候再加1,就是-127 |
|
| - 其实就是一个首尾相连的圈,127再加的话就到了-128,-128再减的话就到了127 |
|
|
|
| - 字符:char 2字节 表示范围为 0~65535 |
|
| - 布尔值:Boolean 理论上是1bit,但单个 使用往往占4个字节,具体视所处编译环境。 |
|
|
|
| #### int和char依据ASCII表可以相互转换 |
|
| char i=97,使用输出语句后输出的是字母a ,就是依据ASCII表找出97对应的字母。 |
|
| # 二进制 |
|
| 由1开始,之后呈2的指数倍增加 |
|
| 8 4 2 1 |
|
| - 0001————1 |
| - 0010————2 |
| - 0100————4 |
| - 1000————8 |
| - 1000 0————16 |
| - 1000 00————32 |
|
| 用二进制表示15为:1+2+4+8 即为1111 |
|
| 用二进制表示127为:128-1 即为10000000-0001 01111111 |
|
| # 运算符 |
|
| - 除法中使用int时: |
| - int a=9; int b=6; int c=a/b; System.out.println(c); 答案为1. |
| - 因为c是整数,所以除法不能整除时,只输出商 |
|
| - 取余时: |
| - x%?= 结果的范围是 0~x-1 |
| - 想要有x种情况,就对x+1取余 |
|
| ### 缩写 |
|
| - a=a+1 可以写为 a++ |
| - a=a+6 可以写为 a+=6 |
|
|
|
|
|
|
|
|
|
| # 位运算符 |
|
|
|
|
|
|
|
|
| ### 按位与(&) |
|
| - 两个数都为true(1),那么答案为true(1) |
| - 如:7&5=5 |
| - 7的二进制为0111 5的二进制为0101 每一位都& 结果为0101 换算为十进制就是5 |
|
| - 如:13&7=5 |
| - 13: 1101 7: 0111 每一位都& 结果为0101 换算为十进制为5 |
|
| ### 按位或( |
|
| - 两个数有一个是true(1),那么答案为true(1) |
| - 如:13 |
| - 13: 1101 7: 0111 每一位都对应的 |
|
| ### 按位异或(^) |
|
| - 两个数都为true(1)或者都为false(0),那么异或的结果为false(0),两数一个为true,一个为false,结果为true(1) |
|
| - 一个数对另一个数异或两次,该数本身不变 |
| - 两数数值的交换,如:a=5,b=9 |
| - 第一种方法:定义一个c,c=a,a=b,b=c |
| - 第二种方法:a=a^b b=a^b a=a^b |
| - 第一步的a=a^b 那么b=a^b时 将a替换为a^b : b=abb,依据上面的结论,a连续异或两次b,a的值不变,那么b=a;第三步:将a替换为a^b, b在上一步已经变成a了,那么 a=aba,依据结论 a=b; |
| - 异或交换其实就是依据结论:将a赋值给b,直接将a异或两次b:b=abb 之后再将b赋值给a,依据结论:a=baa,但是,前提必须先将a=ab,之后再根据结论将ab的部分替换为a就可以了 |
| - 第三种方法:a=a+b b=a-b//a+b-b-------a a=a-b//a+b-a-----b |
|
|
|
|
|
|
|
|
|
|
|
| # 左移运算与右移运算 |
|
| - 二进制的左右移动:1000>>2 : 0010 1101>>2 : 0011 |
|
| ### 结论: |
|
| - 对于一个正整数来说,左移几位,相当于乘以2的几次方,右移几位,相当于除以2的几次方 |
|
| - 如:32>>3 :4 转换为二进制就为:10 0000>>3:0100 |
|
| - 用最有效率的方法计算2*8的结果 |
| - 直接左移右移就是最有效率的方法 |
| - 2*8就是左移三位 答案为:2<<3; |
|
|
|
|
|
|
|
|
|
|
|
|
|
| # switch |
|
| 语句: |
|
| int task=5; |
|
| switch(task){ |
|
| case 1: |
|
| ? System.out.println("登录功能"); |
|
| ? break; |
|
| case 2: |
|
| ? System.out.println("2222"); |
|
| ? break; |
|
| default: |
|
| ? System.out.println("默认"); |
|
| ? break; |
|
| } |
|
| IF主要用来判断是或者不是,如果是会.......不会的话会.....,switch用于明确情况的判断,确认执行的是哪一种命令。并且switch是不能写范围的,比如成绩在某某之间。 |
|
|
|
| jdk5之前,switch不支持String 和 枚举 |
|
| # while循环 |
|
| 语句: |
|
| int j=1; |
|
| while(j<=10){ |
|
| ? System.out.println(111); |
|
| ? j++; |
|
| }j++写在花括号里面 |
|
|
|
| #### for循环和while循环的区别: |
|
| JAVA的垃圾自动回收机制,for循环的Int定义在小括号里面,出了小括号后面的代码访问不到,性能角度看for循环的效率更高一点,不会创作许多无用的变量。while循环的Int定义变量在花括号外面,后面的代码可以访问到。 |
|
|
|
| #### do while循环: |
|
| int k=1; |
|
| do{ |
|
| ? System.out.println(); |
|
| ? k++; |
|
| }while(k<=10); |
|
|
|
| #### 死循环 |
|
| - for(;??{ |
|
| ? System.out.println(); |
|
| } |
|
| - while(true){ |
|
| ? System.out.println(); |
|
| } |
|
|
|
|
|
| #### 跳出循环: |
|
| - break: |
| - 跳出(结束)当前循环 |
| - break标签(用于跳出多重嵌套循环): 在想要结束的位置加上标签和冒号,之后在break后面写上标签名 |
|
| - continue: |
| - 跳过当前循环 |
|
| - return: |
| - 结束当前方法,后面所有的代码没有意义,系统会提醒删掉 |
|
|
|
|
|
|
|
| # 数组 |
|
| 属于引用类型 |
|
| ### 注: |
|
| - 数组的元素都是同一类型 |
| - 是一个集合(与collection集合区分),仅指放的是一堆东西 |
|
| ### 一维数组: |
|
| 语法: |
|
| - Int[] a; |
| - int a[]; |
|
| 数组必须初始化才能使用 |
|
| - 静态初始化: |
| - int[] a={1,3,4,5}; |
|
| - 动态初始化: |
| - int[] b=new int[3]; |
| - b[0]=1; b[2]=5; 给元素赋值 |
|
| - 获取数组的某一个元素: |
| - System.out.printlin(a[0]); |
|
|
|
| ##### 获取每一个元素: |
|
| - for(int i=0;i<=a.length();i++){ |
|
| ? System.out.println(a[i]); } |
|
| - 倒叙输出: |
|
| - for(int i=a.length()-1;i>=0;i--){ |
|
| System.out.printlin(a[i]); } |
|
|
|
|
|
| ### 二维数组 |
|
| 语法: |
|
| - int[] [] a; |
| - int b[] []; |
| - int[] c[]; |
|
| 初始化: |
|
| - 静态初始化: |
|
| - Int[] [] a={{1,2,3},{4,5},{8}}; |
|
| - 动态初始化: |
|
| - int[] [] b=new int[5] []; |
|
| - 获取二维数组中的每一个元素: |
|
| for(int i=0;i
|
|
| ? for(int j=0;j
|
|
| ? System.out.print(a[i] [j]); } |
|
| ? System.out.prinln(); } |
|
|
|
|
|
| # Arrays类(工具类) |
|
|
|
| (1) int binarySearch(type[] a,type value):使用二分法查询value元素值在a数组中出现的索引位 |
| 置,如果a数组不包含value元素值,则返回负数。该方法要求数组已经按照升序进行了排列。 |
| (2) int binarySearch(type[] a,int fromeIndex,int toIndex,type value):与上一个方法名相同,参数 |
| 不同,称为方法重载,同样要求数组已经按照升序进行了排列。 |
| (3) type[] copyOf(type[] original,int newLength):这个方法会把original数组复制成一个新数组, |
| 其中newLength是新数组的长度,当newLength大于original的长度时,新数组的前面元素就是original |
| 的所有元素,后面所有元素使用数组类型默认值进行补充。 |
| (4) type[] copyOfRange(type[] original,int fromIndex,int toIndex):这个方法只复制original数值的 |
| from索引到to索引的元素。 |
| public class Student { |
| static { |
| System.out.println("Student 静态代码块"); |
| } |
| { |
| System.out.println("Student 代码块"); |
| } |
| public Student() { |
| System.out.println("Student 构造方法"); |
| } |
| } |
| public class StudentTest { |
| static { |
| System.out.println("北大吴彦祖"); |
| } |
| public static void main(String[] args) { |
| System.out.println("我是main方法"); |
| Student s1 = new Student(); |
| Student s2 = new Student(); |
| } |
| } |
| (5) boolean equals(type[] a1,type[] a2):如果数组a1与数组a2的长度相同,并且数值a1中元素值 |
| 与a2中元素值相同,该方法返回true。 |
| (6) void fill(type[] a,type val):该方法对数组进行赋值,将所有元素赋值为val |
| (7) void fill(type[] a,int fromIndex,int toIndex,type val):该方法仅仅对从fromIndex开始到toIndex |
| 索引的的元素进行赋值,赋值为val |
| (8) void sort(type[] a):该方法对数组a中的元素进行排序。 |
| (9) void sort(type[] a,int fromIndex,int toIndex):对数组a中的从fromIndex开始到toIndex的元素 |
| 进行排序。 |
| (10) String toString(type[] a):该方法将一个数组转换成一个字符串。按顺序把多个数组元素连缀在 |
| 一起,多个数组元素使用英文逗号和空格隔开。 |
|
|
|
|
|
|
|
|
|
| # Date类: |
|
| Date date=new Date(); |
|
| System.out.println(date); 直接得到当前日期 |
|
| System.out.println(date.getTime()); 返回毫秒值 |
|
|
|
| # 日期格式化 |
|
| #### 日期转换成字符串: |
|
| Date date=new Date(); |
|
| SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd"); |
|
| String aa=dateFormat.format(date); |
|
| System.out.println(aa); |
|
| #### 字符串转换成日期: |
|
| String aa="2000-11-11"; |
|
| SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd"); |
|
| Date brith=dateFormat.parse(aa); 这里需要抛出异常 |
|
| System.out.println( brith); |
|
|
|
|
|
|
|
|
|
|
|
|
|
| # Calendar |
|
| 语句: |
|
| ? Calendar calendar=Calendar.getInstance(); |
|
| - 这里不需要new一个Calendar,getInstance表示初始化这个类 |
|
| - 因为Calendar是一个单例 |
|
| - Calendar和Date都是表示日期的工具,他们可以相互转换。 |
|
| - ``` |
| Calendar cal=Calendar.getInstance(); |
| Date date=cal.getTime(); |
| System.out.println(date); |
| Calendar cale=Calendar.getInstance(); |
| Cale.setTime(date); |
| ``` |
|
|
|
|
|
| #### Calendar类提供的常用方法: |
|
| - calendar.add(Calendar.DATE,-2); |
|
| - 小括号内,逗号前的表示要修改的属性,后面数字写要修改的值 |
|
| - System.out.println(calendar.get(Calendar.DATE)); |
|
| - 举例:在除夕当晚最后一秒,add一秒 |
|
| ``` |
| Calendar cal = Calendar.getInstance(); |
| System.out.println(cal.getTime()); |
| cal.set(2021, 1, 15, 23, 59, 59); |
| cal.add(Calendar.SECOND, 1); |
| System.out.println(cal.getTime()); |
| ``` |
|
|
|
| - calendar.get(int field); 返回指定日历字段的值 |
|
| - 如: System.out.println("年:" + cal.get(Calendar.YEAR)); |
| - System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));月份的下标从0开始,所以取月份要加1 |
| - System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH)); |
| - System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY)); |
| - System.out.println("分:" + cal.get(Calendar.MINUTE)); |
| - System.out.println("秒:" + cal.get(Calendar.SECOND)); |
|
| - calendar.getActualMaximum(int field); 返回指定日历字段的可能拥有的最大值 |
|
| - calendar.getActualMinimum(int field); 返回指定日历字段的可能拥有的最小值 |
|
| - calendar.roll(int field,int amout); 与add方法相似,区别在于超过该字段的最大范围时,也不会向上一个字段进位 |
|
| - calendar.set(int field,int value); 将给定的日历字段设置为给定值 |
|
| - cal.set(Calendar.YEAR, 2018); |
| - cal.set(Calendar.MONTH, Calendar.FEBRUARY); |
| - cal.set(Calendar.DAY_OF_MONTH, 15); |
| - cal.set(Calendar.HOUR_OF_DAY, 23); |
|
| - calendar.set(int year,int month, int date); 设置Calendar对象的年月日 |
|
| - calendar.set(int year,int month,int date,int hourOfDay,int minute,int second);设置年月日时分秒 |
|
| - cal.set(2018, 1, 15, 23, 59, 59); |
|
| - 注:在设置完成之后输出语句:System.out.println(cal.getTime()); |
|
|
|
|
|
|
|
|
|
|
|
| # Random |
|
| 语句: |
|
| ? Random random=new Rondom(); |
|
| #### next: |
|
| - random.nextInt(); |
| - 返回int范围之内的一个随机数 |
|
| - random.nextInt(100); |
| - 返回0~100以内的一个数,但是不包括100 |
|
|
|
|
|
| # Math |
|
| ### 方法: |
|
| - Math.sqrt(); 开根号 |
|
| - Math.abs(); 求绝对值 |
|
| - Math.floor(); 四舍五入 向下取整 |
|
| - Math.round(); 四舍五入 |
|
|
|
|
|
|
|
|
|
|
|
| # Bigdecimal |
|
| 补:round是四舍五入,floor是向下取整 |
|
| - double、float浮点数在进行基本运算时会发生数据丢失现象,需要用到bigdecimal。 |
|
| 语法: |
|
| ? Bigdecimal decimal=new Bigdecimale(12.5); |
|
| #### 方法: |
|
| decimal.add(new Bigdecimal(3.5)); |
|
| add是增加,指在decimal赋值基础上增加3.5 |
|
| 加减乘除的方法: |
|
| - add() 加法 |
| - subtract() 减法 |
| - multiply() 乘法 |
| - divide() 除法 |
| - pow(int n) 取余 |
|
|
|
| # System |
|
| 方法: |
|
| - System.getenv("path"); 获取指定的环境变量值 |
| - System.getenv("JAVA_HOME"); |
| - System.getProperty("user.name"); 获取用户名字 |
| - System.getProperty("os.name"); 获取系统名字 |
| - System.currentTimeMillis(); |
| - 得到当前系统的毫秒值 |
|
|
|
| # String |
|
| String是一个类,类才有对应的方法,不需要new,基本类型是一个关键字,没有对应的方法。 |
|
| #### 方法: |
|
| String aaa="abcdef"; |
|
| - System.out.println(aaa.charAt(2)); |
|
| - charAt()是在括号内写上索引,返回对应的字符 |
|
| - System.out.println(aaa.contains("abc")); |
|
| - contains()是在括号内写上内容,判断aaa字符串中是否包含,返回的是布尔值,判断为true或者false |
| - 也可以用indexof()查找字符串中是否包含某些字符,如果返回-1,就是不包含 |
|
| - System.out.println(aaa.endsWith()); |
|
| - endsWith()是在括号写上内容,判断aaa字符串中是否是以输入内容为结尾,返回布尔值 |
|
| - System.out.println(aaa.equals()); |
|
| - equals()是判断输入的内容是否和aaa中的内容完全相等,返回的是布尔值 |
| - 不等于是 !aaa.equals(bbb) |
|
| - System.out.println(aaa.equalsIgnoreCase()); |
|
| - 注:Ignore是忽略,Case是大小写 |
| - equalsIgnoreCare()是判断内容是否相同,但是忽略了大小写 |
|
| - System.out.println(aaa.indexof()); |
|
| - indexof()是在括号内写上字符,返回对应的索引 |
| - 注:括号内不论写多少字符,返回的只有第一个字符对应的索引,如果写出的字符,在字符串中查找不出,则返回负数 |
|
| - System.out.println(aaa.isEmpty()); |
|
| - isEmpty()判断字符串是否为空 |
| - 注:bbb="" 与 bbb=null是不同的,只有前者可以用isEmpty()作判断 |
|
| - System.out.println(aaa.replace(旧的字符,新的字符)); |
|
| - replace()是替换,在逗号前输入旧的,即原本就有的字符,在逗号后输入新的,完成替换 |
| - 注:替换完成后,原本的字符串并没有改变,而是创造了一个新的字符串,需要新命名来接收新的字符串 |
|
| - System.out.println(aaa.split(",")); |
|
| - String names="tom,jack,amy,daming" |
| - split()是分割字符串,在括号内写上分割的依据,例如names字符串是根据逗号来隔开 |
| - 接收分割好的字符串时,用数组来接收:String[] name=names.split(","); |
|
| - System.out.println(aaa.substring(2,7)); |
|
| - substring()是截取字符串,中间可以加逗号填写两个数字,前面的数字表示从哪个字符开始截取,后面的表示截取到哪里,但是包前不包后,后面的索引对应的字符是不会被打印的 |
|
| - System.out.println(aaa.toCharArray()); |
|
| - toCharArray()返回的是数组,需要创建数组来接收:char[] array=aaa.toCharArray();之后需要用for循环一个一个打印出来:for(int i=0;i |
|
| - System.out.println(aaa.toLowercase()); |
|
| - toLowerCase()是把整个字符串转化成小写,与之相反是toUpperCase |
|
| - System.out.println(aaa.trim()); |
|
| - trim()是去除空格,但并不是去除所有空格,只能去除前后的空格,在字符串中间的空格并不会被去除 |
|
| - System.out.println(aaa.concat()); |
|
| - 拼接字符串 |
|
| - System.out.println(aaa.getBytes()); |
|
| - 将字符串转化为二进制的数组 |
|
| - ``` |
| String a="abcde"; |
| byte[] bytes=a.getBytes(); |
| for(Integer i:bytes){ |
|
| } |
| ``` |
|
| - 几乎每个类都可以getBytes |
|
|
|
|
|
|
|
| #### String 的内存结构 |
|
| 如:String a="hello"; a="bye"; |
|
|
|
| hello一直存在,就算a的值发生了变化,但hello并没有消失,这就叫做String定义的字符串为一个常量,一旦被赋值,不可被改变 |
|
|
|
|
|
|
|
| 使用String a="hello";定义字符串时,系统会先去堆内存(常量池)中查找有没有hello存在,如果有则会直接返回该对象的地址,如果没有,则新建该对象再返回地址值。 |
|
| 如:String a="hello"; String b="hello"; |
|
| hello在之前a的部分已经被创建过一次了,所以后面b的hello与a的hello是一样的,a与b同时指向一个hello,在常量池中不会存在两个hello |
|
|
|
| 如果使用new String(“hello”); 会创建两个对象,new String()的部分会在堆内存中,"hello"会在常量池,同时,不管new String()多少次,堆内存中都会创建多个new String() |
|
|
|
| 注:对于引用类型来说:==判断的是地址是否一样,equals方法是判断内容是否一样 |
|
|
|
|
|
| 重点:字符串如果是变量相加,先开空间,再拼接内容,既然开辟空间,那么地址一定不同 字符串如果是常量相加,先拼接,然后再常量池找,如果有就直接返回,没有再创建 |
|
|
|
|
|
|
|
|
|
| # StringBuffer和StringBuilder |
|
| 与String相比是可变的字符串 |
|
| 两者的区别:前者是线程安全的可变字符串,但是效率低,时间长。 |
|
| ? 后者线程不安全,但是效率高,时间短 |
|
| buffer表示缓冲的意思 |
|
|
|
|
|
| #### 构造方法: |
|
| - StringBuffer buffer=new StringBuffer(); |
|
| - StringBuffer buffer2=new StringBuffer("12345"); |
| - StringBuffer buffer3=new StringBuffer(60); 数字表示多大的容量,buffer3可以放多少数字 |
|
|
|
| #### 常见方法: |
|
| - 添加: |
| - append |
| - buffer.append("hello"); |
| - insert |
| - buffer.insert(3,"123"); |
| - 表示在索引为3的地方插入123 |
|
| - 删除: |
| - deleteCharAt |
| - buffer.deleteCharAt(0); |
| - 表示删除索引为0的字符 |
| - delete |
| - buffer.delete(0,3); |
| - 表示从索引为0的地方删除到索引为3的地方,同样的包前不包后 |
|
| - 替换 |
| - replace |
|
| - 反转 |
| - reverse |
| - buffer.reverse(); |
| - 将字符串反转,倒过来 |
|
|
|
|
|
|
|
|
|
| #### String与StringBuffer的互相转变 |
|
| String bbb=buffer.toString(); |
|
|
|
| ### 将数字转变为字符串: |
|
| String a=String.valueOf(b); |
|
|
|
|
|
|
|
|
|
| # 包装类 |
|
| - 各个基本类型对应的类: |
| - byte-----Byte |
| - char-----Character |
| - short-----Short |
| - float-----Float |
| - int-----Integer |
| - double-----Double |
| - long-----Long |
| - boolean-----Boolean |
|
|
|
| ### String和int的互相转换: |
|
| - 其他类型转变为String: |
|
| - ``` |
| int a=9; |
| String b=String.valueOf(a); |
| ``` |
|
|
|
| - 其他类型转变为int: |
|
| - ``` |
| String a="9"; |
| int b=Integer.parseInt(a); |
| ``` |
|
|
|
|
|
| ### 进制之间的相互转换: |
|
| - 方法: |
| - 转换为二进制: |
| - int a=Integer.toBinaryString(32); 输出后a=100000; |
| - 转换为八进制: |
| - int a=integer.toOctalString(32); 输出后 a=40; |
| - 转换为十六进制: |
| - int a=integer.toHexString(32); 输出后 a=20; |
| - 其他的进制转换方法: |
| - String a=integer.toString(8,2); 输出后 a=1000; |
| - 第一个参数填要转化的数字(是int类型),第二个参数填要转化成哪一个进制 |
| - 其他进制转换到十进制: |
| - int a=integer.parseInt("1000",2); 输出后 a=8; |
| - 第一个参数填字符串,要用引号引起来,第二个参数填当前的进制是哪一个进制,注意跟上面的区分 |
|
|
|
|
|
| ### 装箱与拆箱: |
|
| - 定义: |
|
| - 基本类型变成包装类叫装箱 |
| - 包装类变成基本类型叫拆箱 |
|
| - 自动装箱拆箱: |
|
| - ``` |
| Integer a=6; |
| int b=a; |
| ``` |
|
| - 在装箱的过程中,如果a被赋的值在-128~127之间,会挑选软件划分范围内已有的数字进行赋值,如果超过范围则会new一个Integer重新进行赋值 |
|
| - 例如: |
|
| - ``` |
| Integer i1=128; |
| Integer i2=128; |
| System.out.println(i1==i2); |
| ``` |
|
| - i1和i2已经超过了127的范围,所以这两个数字是被重新New出来的不同的地址,i1与i2的地址是不一样的,所以输出一个false |
|
|
|
|
|
|
|
| # 枚举类 |
|
| - 含义:将变量一个一个列举出来 |
| - 作用:提供变量让自己去选择 |
|
| - 关键字:在类名前面的关键字是enum |
|
| #### 与其他类的区别: |
|
| - 枚举类默认继承Enum类,而不是默认继承Object类 |
| - 使用enum定义的枚举类默认使用final修饰,不能被继承 |
| - 构造器只能使用private修饰 |
| - 枚举类的所有实例会被自动添加public static final修饰 |
|
|
|
| #### 方法: |
|
| (1) int ordinal():返回枚举值在枚举类中的索引值(第一个枚举值索引为0) |
| (2) Enum[] values():返回一个包括当前Enum类所有实例的对象数组 |
| (3) String name():返回此枚举实例的名称,这个名称就是定义枚举类时的所有枚举值之一。一般用 |
| toString()。 |
| (4) Enum valueOf(Class enumType,String name):返回指定枚举类中指定名称的枚举值。名称必 |
| 须与在该枚举类中声明枚举值时所用的标识符完全匹配。 |
| (5) String toString():返回枚举常量的名称。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| # 单例类 |
|
| - 作用:这个类的对象只能被new一次 |
|
| - 写单例类的代码: |
|
| - 声明一个当前的类对象,私有化 |
| - 构造方法私有化 |
| - 提供一个方法来做初始化 |
| - 判断当前类对象==null,返回一个New |
| - 不是null,返回对象本身 |
|
| - ``` |
| private static Singleton singleton=null; |
| private Singleton(){ |
| } |
|
| public static Singleton getIns(){ |
|
|
|
|
|
|
| } |
| ``` |
|
|
|
|
|
|
|
|
|
| # 正则表达式 |
|
| ### 特殊字符 |
|
![]() |
|
|
|
| ### 预定义字符 |
|
![]() |
|
| ### 方括号表达式 |
|
![]() |
|
| ### 花括号表达式 |
|
![]() |
|
| ### 实例 |
|
|
|
| 1、验证用户名和密码:"\w{5,15}$"、"[A-Za-z]_[0-9]"。由数字、字母、下划线组成,并且第一 |
| 个字必须为字母,长度为:5~15。 |
| 2、验证电话号码:"(\d{3,4}-)*\d{7,8}"正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx; |
| XXX-XXXXXXX XXX-XXXXXXXX XXXX-XXXXXXX XXXX-XXXXXXXX |
| 3、验证身份证号(18位数字):"[1-9]\d{16}(\d |
| 4、验证Email地址:^\w+(\w+)@\w+([-.]\w+).\w+([-.]\w+)*$;zhang_san@163.com |
| 5、只能输入由数字和26个英文字母组成的字符串:+$ 、[\w&&[_]]$”、+ ([A- |
| z]+\d?)$ |
| 6、整数或者小数:+.{0,1}[0-9]{0,2}$ |
| 7、只能输入数字:"*$" |
| 8、只能输入n位的数字:"^\d{n}$" |
| 9、只能输入至少n位的数字:"^\d{n,}$" |
| 10、只能输入m~n位的数字:"^\d{m,n}$" |
| 11、只能输入零和非零开头的数字:"^(0 |
| 12、只能输入有两位小数的正实数:"+(.[0-9]{2})?$" |
| 13、只能输入有1~3位小数的正实数:"+(.[0-9]{1,3})+$" |
| 14、只能输入非零的正整数:"^+?[1-9]\d*$" |
| 15、只能输入非零的负整数:"^-[1-9][0-9]*$” |
| 16、只能输入长度为3的字符:"^.{3}$" |
| 17、只能输入由26个英文字母组成的字符串:"+$" |
| 18、只能输入由26个大写英文字母组成的字符串:"+$" |
| 19、只能输入由26个小写英文字母组成的字符串:"+$" |
| 20、验证是否含有%&',;=?$"等字符:"[%&',;=?$\x22]+" |
| 21、只能输入汉字:"{0,}$" |
| 22、验证URL:"^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$" |
| 23、验证一年的12个月:"^(0?[1-9] |
| 24、验证一个月的31天:"^((0?[1-9]) |
| 25、获取日期正则表达式:\d{4}[年 |
|
|
|
|
|
| ### 用法: |
|
| - 步骤: |
|
| - 定义表达式 |
| - 获得用户的输入 |
| - 用这个表达式来校验用户输入是否合法 |
|
| - 代码: |
|
| ``` |
| String exp="^\d{3}$"; |
| String input="123"; |
| System.out.println(input.matches(exp)); |
| ``` |
|
|
|
| - 注:正则表达式开始必须用^ 结尾必须用$ 并且要注意转义字符 |
|
|
|
|
|
| # 国际化 |
|
| - 含义:程序在不同地区运行时,应动态的显示不同地区的语言 |
|
| ### 方法: |
|
| - 创建国际化的配置文件: |
| - 在要用到国际化的类文件src下,new一个properties 在Wizard方框内搜索files |
| - 文件名称有命名规范: |
| - baseName_language_country.properties(基本名+语言+国家) |
| - res_en_US.properties |
| - baseName_language.properties(基本名加语言) |
| - baseName.properties(只写基本名) |
|
| - 针对英国的配置文件: |
| - username=username |
| - pwd=password |
|
| - 注: |
| - 不需要加引号和分号结尾 |
| - 创建针对中国的配置文件时,需要重新创建一个配置文件 |
|
|
|
|
|
| - 在主页面中调用国际化配置文件时: |
|
| - ``` |
| Locale locale=Locale.getDefault(); //得到当前电脑所处的语言环境 |
|
|
| //如果选择其他国家的: |
| //Locale locale=Locale.US; |
|
|
| ResourceBundle bundle=ResourceBundle.getBundle("res",locale); |
| //程序加载所有"res"开头的配置文件,依据本地的语言环境选择哪个配置文件 |
|
| System.out.println(bundle.getString("username")); |
| System.out.println(bundle.getString("pwd")); |
| ``` |
|
|
|
|
|
| # Scanner |
|
| - 键盘输入: |
|
| ? Scanner scanner=new Scanner(System.in); |
|
| - 方法: |
| - int aa=scanner.nextInt(); 表示接收数字 |
| - String aa=scanner.nextLine(); 表示接收字符串 |
| - 等等等等........... |
|
| #### 需要注意的坑: |
|
| - 使用 String aa=scanner.next();一样可以接收字符串,但是它不会接收空格,只接收第一个空格之前的内容 |
| - 在使用对应的方法时,如:sacnner.nextInt(); 只接收整数的部分,后面的符号、小数、字符串等不会被接收 |
| - 如果在上一步接收时,输入了数字及回车,nextInt的部分只接收数字,回车会被下一行的nextLine();接收到,进行一次回车,所以在看到结果时相当于跳过了nextLine()的部分 |
| - 针对上述问题,我们需要在接收完数字后,再进行一次接收字符串:sacnner.nextLine(); |
|
|
|
| #### 用Scanner读取文件 |
|
| - File file=new File(“d;/tiku.txt”); |
| - Scanner scanner=new Scanner(file); |
|
| 需要抛出一个异常 |
|
| #### Scanner中读取文件的方法: |
|
| - scanner.hasNext();检测下一行有没有内容 |
| - scanner.nextLine();打印下一行的内容 |
|
|
|
|
|
| # 剪切板Clipboard |
|
| 调用剪切板的方法: |
|
| - Clipboard clipboard=Toolkit.getDefaultToolkit().getSystemClipboard();调用剪切板 |
|
| - StringSelection selection=new StringSelection("6666");把想要让剪切板复制的话写进引号内 |
|
| - clipboard.setContents(selection,null);把写出的话放进剪切板,set是设置,contents是内容 |
|
| 注:这三行的作用就是复制即ctrl+c的作用,用代码来完成复制 |
|
| - Transferable transferable=clipboard.getContents(null);拿到剪切板里的内容 Get是得到, Contents是内容 |
| - String search=(String) transferable.getTransferData(DataFlavor.stringFlavor);需要进行强制类型转换,并处理报错,因为剪切板可以复制很多类型的内容,比如图片,字符串,文件等等,所以需要设置拿到的是字符串格式。 |
|
| 注:这两步加起来才是拿到字符串的内容 |
|
| - 上面两行是复制内容,下面两行是把内容取出来 |
|
|
|
| #### 转义字符 |
|
|
|
| # 内存分配 |
|
| 如:常用类中 int a=5; |
|
| ? |
|
| ? |
|
|
|
| - 栈内存 |
| - Int a 会放在栈内存里 |
| - Scanner scanner= 会放在栈内存 |
| - int[] 会放在栈内存 |
|
| - 堆内存 |
| - new Scanner() 会放在堆内存 |
| - new int[5] 会放在堆内存 |
| - 常量池(方法区) |
| - 5会放在常量池内 |
|
|
|
|
|
|
|
| 创建对象时:分为三部分: |
|
| - 分配空间 |
| - 对象初始化 |
| - 分配地址 |
|
|
|
| # 面向对象(思想) |
|
| ### 权限修饰: |
|
| - public: 公开的,所有不同的包,不同的类全都可以访问得到。 |
| - private: 私有的,只有自己的类(同一个class)中可以访问,其他的都访问不到。 |
| - protected: 受保护的,除了不同包的其他类访问不到,其他都可以访问到,不同包的子类也可以 访问的到。 |
| - 默认:只有同一个包中的类可以访问到,不同包访问不到。 |
|
|
|
|
|
| ### 封装: |
|
| - 实际含义是:该隐藏的隐藏,该暴露的暴露 |
|
|
|
| - 全局变量:定义在类中的,所有方法都可以访问到,叫全局变量 |
|
| - 局部变量:定义在一个方法里的,只有本方法可以访问的叫局部变量 |
|
|
|
| ##### 定义变量: |
|
| ? 权限修饰符(public) + 类型(void、int、string、array[]...) + 变量名称 |
|
| 注:变量名称要用合法的JAVA标识符,首单词的第一个字母小写,后面的每一个单词首字母大写 |
|
|
|
|
|
| ##### 可变参数: |
|
| ``` |
| public static void test(int...a){ |
|
|
|
| } |
| ``` |
|
| - 当不确定参数内要传多少个时,用int... 在调用test方法时,可以任意传几个参数,同时会把a当作数组进行处理 |
|
| - 注: |
|
| - 如果一个参数里有可变参数,并且有多个参数,那么可变参数一定要放在最后一个 |
|
| - ``` |
| public static void test(int b,int...a){ |
|
|
|
| } |
| ``` |
|
|
|
|
|
|
|
|
|
| ##### 方法封装: |
|
| - -定义格式: 修饰符(private) + 返回值类型(void、int、string....) + 方法名(自定义)+ |
|
| ( 参数类型 参数名称 + , + 参数类型 参数名称) + { 代码体 + return 表达式 } |
|
|
|
| - 形式参数:在参数名称中,方法本身起的名字叫形式参数,只起一个代号的作用。 |
|
| - 实际参数:在通过 . 调用方法时,依据形式参数传进的东西是实际参数。 |
|
|
|
| - 不需要new对象就可以访问的方法封装: |
|
| ? |
|
| ? return new Person(); |
|
| ? |
|
|
|
| - 方法封装的好处:1.方便维护 2.减少冗余代码的出现 |
|
|
|
| ##### 构造方法: |
|
| - 作用:用于该类的实例对象的初始化 |
|
| - 格式: public Person(){ } |
|
| - 示例: pubilc int size; |
|
| ? |
|
| ? size=18; |
|
| ? |
|
| - 这就是给对象做了初始化,只要在另一个类中调用了Person的方法,new出了Person,那么当输出size时,默认输出18. |
| - 构造方法中也可以传参数,当传入了参数后,再调用此方法是就必须传进参数对应的类型,如果想既可以传参数,也可以不传参数,那么就再构造一个同名的方法,该方法不加任何参数,这就叫构造方法的重载 |
|
|
|
| ##### This关键字 |
|
| - this关键字总是指向该方法的对象。 |
| - 当this出现在构造方法中,this指的是该构造器正在初始化的对象,(也就是最外层的) |
| - 在普通方法中引用,this指的是调用该方法的对象 |
|
| - 作用:this关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或Field |
|
|
|
| ##### 通过set方法对对象进行初始化: |
|
| 代码: public void setSex(String sex){ |
|
| ? |
|
| ? |
|
| ##### 小结: |
|
| - 变量—————— 类对应的属性 |
| - 构造方法——————new对象的时候对对象初始化 |
| - 方法(函数)——————功能性的方法 |
|
|
|
| ##### 封装打包学生类的代码: |
|
| Demo demo=new Demo(); |
|
| Student student=new Student("tom",18,6,"3333","男"); |
|
| demo.save(student); |
|
|
|
| public void save(Student student){ |
|
| ? |
|
| ? |
|
| } |
|
|
|
| ##### 匿名对象 |
|
| 如上:Demo demo=new Demo(); |
|
| ? |
|
| - new Student只用到一次,没有给他起名字,这就是匿名对象 |
|
|
|
| ##### 值传递 |
|
| - JAVA的参数传递方式只有一种,那就是值传递 |
|
| - 值传递含义:就是将实际参数的复制品传进方法,也就是重新创建一个一模一样的参数,对这个复制品进行方法操作,而实际参数的本身并没有受到影响。 |
|
| 如:int a=5,b=5; |
|
| ? |
| ? |
|
| ? |
|
| ? |
|
|
|
| ``` |
| public void change(int a, int b){ |
|
|
|
|
| public static void main(){ |
|
|
|
| } |
| //打印后a的值依旧是10,调用方法并没有改变,因为传进去的是基本类型的副本,只有引用类型才会传进地址,最后的值会被改变,如果用change方法改变a的值的话,需要在后面return |
| ``` |
|
|
|
| 传进的是引用类型时: |
|
| - ``` |
| public void change(StringBuffer buffer){ |
|
|
| public static void main(){ |
|
|
|
| } |
| //此时打印后结果为ABC123,因为传进去的是地址,原本的值会被修改 |
| ``` |
|
|
|
|
|
|
|
|
|
| 在此次方法操作中,a和b的值依旧是5,并没有变成100,就是对a与b的复制品进行了操作,实际参数本身没有改变 |
|
| 如果想要将ab变成100的话,就需要返回a与b,在后面加return ,并将void改为Int |
|
|
|
| - 只有基本类型的值传递才是将复制品传进方法,其他类型的值传递是传进地址值的复制品,所以是可以对实际参数进行修改的 |
|
|
|
| ##### 重载 |
|
| - 方法名不可以重名,但是方法名相同时,参数列表不同时,如:方法一有两个参数,方法二有三个参数,尽管两个方法名字相同,但是可以同时存在,这叫方法的重载 |
|
| - 重载只与方法名和参数名称有关,与权限修饰符,返回值类型等无关 |
|
| - 方法名相同,参数名称不同或参数数量不同时,才叫重载 |
|
|
|
| ##### 递归 |
|
| - 含义:自己调用自己 |
|
| - 斐波那契数列: |
|
| - 1 1 2 3 5 8 13 21 34 |
|
| - 假设要求第n位的值: |
|
| public int fb(int n){ |
|
| ? |
|
| ? |
|
| ? |
|
| ? |
|
| ? |
|
| } |
|
| - 递归最重要的是找到第一个递归的出口 |
|
| ##### Static |
|
| - 特点: |
|
| - static是跟随类的出现而出现,类名出现一次,那么static后面的内容就会执行一次 |
|
| - 被类的所有对象(new一次就是一个对象)共享:在调用static修饰的变量时,不同对象调用的是同一个变量,对象一对变量b进行改变时,对象二中的变量b也会改变而不同的对象调用不被static修饰的变量时,不同的对象使用的是不同的变量,对象一修改变量a时,对象二的变量a是不会被改变的 |
|
| - 例如: |
|
| - ``` |
| static int a=1; |
| public static void main(){ |
|
|
|
|
| } |
| //此时打印的num2的a,它的值为2,因为两个对象共用的一个变量,num1做了修改,num2也会有改变 |
| ``` |
|
|
|
| - 可以通过类名直接调用 |
|
|
|
|
|
| - 注意事项 |
|
| - 在静态方法中不可以使用this关键字 |
| - 静态方法里不能访问成员变量或成员方法 因为静态方法是随着类的出现而出现,成员变量需要先New出对象,才能访问得到 |
|
|
|
| - 静态变量和成员变量的区别 |
| - 所属不同 |
| - 静态变量属于类,所以也称为为类变量 |
| 成员变量属于对象,所以也称为实例变量(对象变量) |
| - 内存中位置不同 |
| 静态变量存储于方法区的静态区 |
| 成员变量存储于堆内存 |
| - 内存出现时间不同 |
| 静态变量随着类的加载而加载,随着类的消失而消失 |
| 成员变量随着对象的创建而存在,随着对象的消失而消失 |
| - 调用不同 |
| 静态变量可以通过类名调用,也可以通过对象调用 |
|
|
|
| - 用武之地 |
| - 使用工具方法时,可以加static,因为每次使用工具都需要New出对象,过于麻烦,而加上static后,只需要使用类的名字直接用点就可以调用,不需要new对象 |
| - 只需加载或执行一次 |
|
|
|
| ##### 代码块: |
|
| - 局部代码块: |
| - 出现在方法的内部,用大括号括起来的就是局部代码块 |
| - 定义在局部代码块内的变量,出了局部代码块后,外面的访问不到 |
| - 限定变量生命周期,及早释放,提高内存利用率 |
|
| - 构造代码块 |
| - 在类中方法外出现;多个构造方法中相同的代码存放到一起,每次调用构造都执行时就可以用构造代码块,并且在构造方法前执行 |
| - 运用:当所有的构造方法中都有相同的部分时,可以把他放进构造代码块里,这样可以减少构造方法中相同的部分出现 |
|
| - 静态代码块 |
| - 在构造代码块前加上static,构造代码块是New一次,代码块的内容出现一次,静态代码块是类出现一次,就执行一次 |
|
|
|
| # 集合框架 |
|
| #### 集合和数组的区别: |
|
| - 长度 |
| - 数组的长度固定 |
| - 集合长度可变 |
|
| - 内容 |
| - 数组存储同一类型元素 |
| - 集合存储不同类型元素 |
|
| - 元素类型 |
| - 数组可以存基本类型,可以存引用类型 |
| - 集合只可以存引用类型 |
|
![image-20210713105709954]() |
|
|
|
|
|
| ### For Each循环 |
|
| - 与For循环的区别: for循环需要通过下标一个一个去找,而foreach是直接遍历每一个对象 |
|
| ``` |
| UserTable user=new USerTable("tom",19); |
| UserTable user1=new USerTable("jack",18); |
| UserTable user2=new USerTable("Amy",17); |
|
| ArrayList list=new ArrayList<>(); |
| list.add(user); |
| list.add(user1); |
| list.add(user2); |
|
| for(UserTable user:list){ |
|
| } |
| ``` |
|
|
|
| - 注: |
| - 循环前先判断集合是否为null,如果为Null会直接报空指针异常。 |
| - foreqch遍历,只可以遍历数组或者Collection,是不可以遍历map的 |
|
|
|
|
|
|
|
| ### Collection |
|
| - 是一个接口并不是一个类,所以不可以被实例化。 |
| - collection也可以有多态,可以通过Collection类型new出一个实例,如Collection collection=new ArrayList(); |
|
| 注:当传进的参数类型是Object时,代表可以传任何类型的参数,因为Object是所有类型的父类 |
|
| - collection是自动补全toString方法,是可以直接打印出元素的,而数组直接打印的话是打印地址 |
|
| - 方法: |
|
| - 1:添加功能 |
| boolean add(Object obj):添加一个元素 |
| boolean addAll(Collection c):添加一个集合的元素 |
|
| - 2:删除功能 |
| void clear():移除所有元素 |
| boolean remove(Object o):移除一个元素 |
| boolean removeAll(Collection c):移除一个集合的元素 |
|
| - 3:判断功能 |
| boolean contains(Object o):判断集合中是否包含指定的元素 |
| boolean containsAll(Collection c):判断集合中是否包含指定的集合元素 |
| boolean isEmpty():判断集合是否为空 |
|
| - 5:长度功能 |
| int size():元素的个数 |
|
| - 6:交集功能 |
| boolean retainAll(Collection c):两个集合都有的元素 |
|
| collection.retainAll(c2); |
|
| 这个功能意思是 把c2和collection的交集重新赋值给了collection,返回值类型的布尔值代表collection是否被改变过 |
|
| - 7:把集合转换为数组 |
| String[] array=(String[]) collection.toArray(); |
|
| 数组转集合:Arrays.asList(array); |
|
| #### 4:获取功能 |
|
| - Iterator iterator()(重点) |
|
| Iterator iterator=collection.iterator(); (代表获得当前集合的迭代器) |
|
| while(iterator.hasnext()){ |
|
| System.out.println(iterator.next()); |
|
| } |
|
| #### 越界报错: |
|
| - 注:该过程中需要注意,多输出一个iterator,next(),表示找的是下一个元素 |
|
| - 注意的报错:NoSuchElementException与数组的越界报错一样,都表示访问的东西不存在 |
|
| - ``` |
| Student s1 = new Student(); |
| s1.setname("Tom"); |
| s1.setage(18); |
| Student s2 = new Student(); |
| s2.setname("jack"); |
| s2.setage(20); |
| collection.add(s1); |
| collection.add(s2); |
| Iterator iterator=collection.iterator(); |
| while(iterator.hasNext()){ |
|
|
|
| ``` |
|
| ``` |
| 注:上面的代码中,第一行打印的是Tom的名字,第二行打印的是Jack的年龄,因为使用了两次hasNext(); 第二个hasNext();找的是第二个元素Jack,所以打印了Jack的年龄 |
| ``` |
|
| #### 迭代器的遍历方法: |
|
| - 使用for循环使用迭代器遍历集合: |
|
| - for(;iterator.hasnext()??{ |
| System.out.println(); |
|
| } |
|
|
|
| ### List |
|
| - List是Collection接口的一个子接口。 |
|
| - List是一个有序的集合,允许重复的元素存在 |
|
|
|
|
|
| ##### 方法: |
|
| - List继承Collection,所以Collection有的方法,List也有 |
| - void add(int index,Object element):在指定位置添加元素 |
|
| - List可以通过Get方法,利用下标获得元素,而collection没有Get方法,所以只能通过迭代器获得元素 |
|
| - List也有迭代器 |
| - iterator.nextIndex(); 返回下一个索引 |
| - interator,previousIndex(); 返回上一个索引 |
| - interator.hasPervious(); 有没有前一个元素 |
|
| ``` |
| ListIterator iterator=list.listIterator(); |
| while(iterator.hasNext()){ |
| System.out.println(iterator.next()); |
| } |
| ``` |
|
|
|
| - 删除功能,根据索引删除元素,返回的是被删除的元素 |
|
| - System.out.println(list.remove(1)); |
|
| - 修改功能,根据索引修改元素,返回被修改的原来的值 |
|
| - System.out.println(list,set(2,"mmm")); |
|
| 把下标为2的元素bbb修改为mmm,则返回bbb。 |
|
|
|
|
|
|
|
| ##### ArrayList: |
|
| - ArrayList的底层是数组,特点是查询快,增删慢 |
| - 线程不安全,效率高。 |
|
|
|
| ##### Vector: |
|
| - 底层数据结构是数组,查询快,增删慢。 |
| - 线程安全,效率低。 |
|
|
|
| ##### LinkList: |
|
| - LinkList的底层是链表,特点是查询慢,增删块 |
|
| - 线程不安全,效率高。 |
|
| - 方法: |
|
| - LinkedList list=new LinkedList(); |
|
| list.addFirst(); (在第一位添加元素) |
|
| list.addLast(); (在最后一位添加元素) |
|
| list.getFirst(); (获得第一位) |
|
| list.indexOf(); (获得元素的索引) |
|
| list.lastIndexOf(); (获得最后的索引位置) |
|
| list.removeFirst(); (移除第一个) |
|
|
|
| ##### 注: |
|
| 容器指集合 |
|
|
|
| ### ConcurrentModificationException |
|
| - 含义:并发修改异常 |
| - 并发: |
|
| - 该报错会在迭代器里出现 |
| - 假如List中有三个元素,删除第三个元素,就会并发修改异常报错 |
| - 因为,迭代器是根据原本有三个元素的List拿到的,本身是准备遍历三个元素的,但是中途删除了一个元素,两边数据不一致,同时更改了一个数据,所以才是并发修改异常 |
|
| ``` |
| ListIterator iterator=list.listIterator(); |
| while(iterator.hasNext()){ |
|
|
|
| ``` |
|
|
|
|
|
|
|
| ### Set |
|
| - 与List的区别: |
| - List有序,允许重复的值存在 |
| - Set无序,不允许重复的值存在 |
|
| ##### 方法: |
|
| - Set是Collection的子类,所以也拥有Collection所有的方法 |
|
|
|
| ##### HashSet: |
|
| - Set的实际类只有HashSet,所以HashSet的方法都是Collection的方法 |
|
|
|
| - HashSet的遍历方法: |
| - 使用迭代器 |
| - 使用for each遍历 |
| - 因为没有下标,所以不可以用for循环遍历 |
|
|
|
|
|
|
|
| - 特性: |
| - 不保证顺序 |
| - 底层数据结构是哈希表 |
| - 哈希表指数组加链表的数据结构 |
| - 哈希表:当a元素占用了数组的3位置后,另一个b元素经过哈希值的运算后得出也要占用3位置,这时就用链表的箭头从a元素指向b元素 |
|
|
|
|
|
| ##### linkedhashset |
|
| - 底层是哈希表加链表 |
| - 哈希表保证唯一性,链表保证有序 |
|
| ##### treeset |
|
| - 可以排序 |
| - 使用元素自然排序排序 |
| - 使用Comparator |
|
|
|
| ##### 注::::: |
|
| - HashSet的底层是HashMap: |
| - HashSet中的add方法调用的其实是HashMap中的put方法 |
|
| - LinkedHashSet的底层是LinkedHashMap |
| - TreeSet的底层是TreeMap |
|
| - 总结:Set其实就是Map的一部分,将Map的键抽出来就是Set |
|
|
|
|
|
|
|
| ### List和Set的使用场景区别 |
|
| 当想要添加的元素不能重复时,或者只想看最终结果都有哪些。就将元素添加在set里,否则一般情况用List |
|
|
|
|
|
|
|
|
|
| ### Collections |
|
| - Collection与Collections的区别 |
| - Collection 是单列集合的顶层接口(总的一个接口),有子接口List、Set。属于抽象类,是不能被实例化的 |
| - Collections 是针对集合进行操作的工具类,有对集合进行排序和二分查找的方法,都是静态方法,通过类名直接调用。 |
|
|
|
| ##### 方法: |
|
| - 排序方法:默认情况下是从小到大 |
|
| - Collections.sort(); |
|
| - ``` |
| List list=new ArrayList<>(); |
| list.add(5); |
| list.add(2); |
| list.add(6); |
| list.add(9); |
|
| Collections.sort(list); |
| System.out.println(list); |
| ``` |
|
| - 二分查找: |
|
| - Collections.binarySearch(List<?>list,T key ) |
| - 传进两个参数,一个列表一个元素,查找该列表内某一个元素出现在哪一个位置 |
|
| - 返回的是索引 |
|
| - 列表内的元素必须是有序的 |
|
| - 获取最大值: |
|
| - Collections.max(Collection<?> coll); 参数传集合 |
| - Collections.min(); |
|
|
|
|
|
| - 反转: |
| - Collections.reverse(List<?> list); 参数传列表 |
| - 并不是将列表里的元素排序,只是将顺序反转 |
|
| - 随机置换: |
| - Collections.shuffle(List<?> list); 参数传列表 |
| - 将列表内元素的顺序打乱 |
|
|
|
|
|
|
|
|
|
|
|
| ### Map |
|
| - Map与Collection是两个独立的体系 |
|
| - Map与Collection的区别: |
|
| - map存储元素是成对出现的,是键值对的一个体系,键是唯一的,值是可重复的 |
| - 键值对的含义是,可以给值起名字 |
| - Collection元素是单独的 |
|
| - map集合的数据结构是哈希表(哈希表就是不重复),这个数据结构只针对键有效,和值无关 |
|
| - 意思为,键是唯一的,不可重复,值可以重复 |
| - 键可以为null, 但是只可以有一个null键,因为键具有唯一性 |
|
| - 代码例子: |
|
| - ``` |
| HashMap map=new HashMap<>(); |
| map.put("aaa","5"); |
| ``` |
|
|
|
|
|
| #### HashMap: |
|
| ##### 方法: |
|
| - 添加功能: |
|
| - map.put(key,value) k写键的名称,value写赋的值 |
| - 另一个功能就是可以返回: |
| - 如果键是第一次存储的话,存储元素后,返回Null |
| - 如果键不是第一次存储的话,就用现在的值把以前的值替换掉,并返回以前的值 |
|
| - 获取功能: |
|
| - map.get(k); k写键的名称,通过get键,从而获得键对应的值 |
|
| - map.entrySet(); 得到的是键值对的一个集合 |
|
| - 该方法也可以被接收后返回: Set> kv=map.entrySet(); |
|
| - 因为返回的是一个集合,所以用set类型接收,泛型里面填Entry<> |
|
| - 在遍历Kv时,也是用遍历Set类型的方法遍历(迭代器或者for each) |
|
| - ``` |
| Set> kv=map.entrySet(); |
| Iterator> iterator=kv.iterator(); |
| while(itreatro.hasNext()){ |
|
| } |
| ``` |
|
| - map.keySet(); 获取集合中所有键的集合 这个集合用Set接收,因为键不可以重复 |
|
| - map.values(); 获取集合中所有值的集合 接收这个集合时,用collection接收 , 不能用Set, 因为值是可以重复的,用了Set后值就不可以重复 |
|
| - 删除功能: |
|
| - map.clear(); 移除所有键值对元素 |
| - map.remove(k); k写键的名称,根据键删除键值对元素,并把值返回 |
|
| - 判断功能: |
|
| - map.containsKey(k); 判断集合是否包含指定的键 |
| - map.containsValue(value); 判断集合是否包含指定的值 |
| - map.isEmpty(); 判断集合是否为空 |
|
|
|
|
|
| ##### HashMap与Hashtable的区别: |
|
| - map线程不安全,效率高 |
| - table线程安全,效率低 |
|
|
|
|
|
|
|
|
|
| #### LinkedHashMap: |
|
| - Map接口的哈希表和链接列表实现,具有可预知的迭代顺序 |
|
|
|
| #### TreeMap: |
|
| - 键是红黑树结构,可以保证键的排序和唯一性 |
|
|
|
|
|
|
|
| ### 无限嵌套的补充: |
|
| - list set map 都是可以循环无限嵌套的 |
|
| - ``` |
| List list=new ArrayList<>(); |
| list.add(usertable); |
|
List> school=new ArrayList<>(); |
| school.add(List); |
| ``` |
|
| - 一个集合嵌套一个集合时,注意泛型要填第一个集合的类型。 |
|
| - ``` |
| Person s1=new Person("tom",18); |
| Person s2=new Person("tom",18); |
| Person s3=new Person("jack",20); |
|
| HashSet set=new HashSet(); |
| set.add(s1); |
| set.add(s2); |
| set.add(s3); |
| System.out.println(set); |
| ``` |
|
| - 此时打印set,是会将所有对象都打印出来,虽然两个都是tom,18岁,但是在set内添加的是s1和s2两个不同的对象,两个对象都是New出来的,与对象里面的内容是否相同无关,所以两个tom都是可以打印的 |
|
|
|
| ### 数据结构: |
|
| #### 数组: |
|
| - 定义:相同数据类型的元素按一定顺序排列的集合。 |
|
| - 连续的存储空间 特点:查询快,但是增删慢 |
| - 如果需要增加或删除的话,就是重新开辟空间,创建另一个数组,把原本的填上去再加上需要增加的元素,删除反之 |
| - 时间复杂度:O(1) |
|
| #### 链表: |
|
| - 链表中每个元素都是一个对象,每个对象称为一个节点,包含有数据域key和指向下一节点的指针next,通过各个节点间的相互连接,最终串联成一个链表 |
| - 通常链表每一个元素都要保存一个指向下一个元素的指针 |
| - 不是连续的存储空间,用箭头一个一个指向下一个元素 特点:查询慢,增删块 |
| - 时间复杂度:O(n) |
|
| #### 队列: |
|
| - 含义:程序运行多个任务,但是一次处理不过来,把所有的任务依次放进队列,一个一个去取 |
|
| - 特点:先进先出 |
|
| #### 栈: |
|
| - 定义:限定仅在表尾进行插入和删除操作的线性表 |
|
| - 含义:好像进电梯,入口和出口是同一个,先进来的排在最后面,最后进来的排在最前面 |
|
| - 特点:后进先出,先进后出 |
|
| #### 树: |
|
| - 定义:树是n(n>=0)个结点的有限集。n=0时称为空树。在任意一颗非空树中: |
| - 有且仅有一个特定的,称为根的结点 |
| - 当n>1时,其余结点可分为m(m>0)个互不相交的有限集t1、t2、.......tm,其中每一个集合本身又是一颗树,并且称为根的子树。 |
|
| - 一对多的层级关系 |
| - 表示人物职称或者级别时,用树状图 |
| - 二叉树:一个元素只能分两个叉 |
| - 左边的放小的,右边的放大的 |
| - 如果从左往右数,那么就是依次从小到大排列 |
|
![]() |
|
| ##### 遍历方法: |
|
| 二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次 |
|
| - 前序遍历 |
| - 若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。 |
|
| - 中序遍历 |
| - 若树为空,则空操作返回,否则从根结点开始(并不是先访问根结点),中序遍历根结点最左侧的左子树,然后访问根结点,最后中序遍历右子树。 |
|
| - 后序遍历 |
| - 若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。 |
|
| - 层序遍历 |
| - 若树为空,则空操作返回,否则从树的第一层,也就是根结点开始访问,从上到下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。 |
|
| - 注:区分前序遍历和层序遍历:前序为先遍历左边,左边的全部找完再遍历右边,层序为按照层级关系,先遍历上层,按照层级顺序,一层一层找 |
|
|
|
|
|
|
|
| #### 堆: |
|
| - 含义:堆是具有下列性质的完全二叉树: |
| - 每个结点的值都大于或等于其左右孩子的结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。 |
| - 在一个堆中,根结点一定是堆中最大(小)的结点。较大(小)的结点靠近根结点 |
|
| #### 图: |
|
| - 定义:图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合 |
| - 在图形构造中,顶点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。 |
|
| - 表示人物关系 |
| - JAVA的垃圾自动回收就是图的应用,如果某个对象正在被其他对象用着,那么就不是垃圾。如果某个对象失效,或者内容为null,那么图中的连线或者节点就会消失,JAVA判定为垃圾 |
|
| ##### 遍历方法: |
|
| - 深度优先遍历: |
| - 查找所有的顶点并标记,在没有碰到重复顶点的情况下,始终查找右边的顶点,在没有通道可走的情况下,原路返回,找寻没有被标记的顶点,最终返回到起点,遍历结束,该遍历方法本质是一个递归的过程 |
|
| #### 时间复杂度 |
|
| - O(1) 表示需要查找一次就可以找到需要查找的元素 |
| - O(n) 表示要查找第几个,就需要查找第几次,查找第N个,就需要查找第N次 |
|
|
|
|
|
|
|
| # 封装业务层:MVC三层架构 |
|
| M:model(模型),指实体类 |
|
| V:view(视图),能看到的所有东西就是视图 |
|
| C:controller(终端控制器) |
|
| 前端的任何请求,都要转到后台的代码控制器,控制器拿到数据后,再交给业务层的方法,做业务处理,业务层拿到东西后再去调动数据库 |
|
|
|
| - 控制层: 接收或者返回数据/前后端的连接 |
| - 服务层:做具体的业务处理 |
| - 数据库层:做增删改查操作 |
|
|
|
| 例如:普通的代码页面中的命令行就是视图,然后选择的1.2.3接收给控制层,控制层接收数据给服务层,服务层拿到数据做具体的业务处理,服务层接收用户的输入,然后把他封装成一个对象,再传给数据库,数据库做增删改查。 |
|
|
|
|
|
|
|
|
|
| # JDBC |
|
| - 全称: java database connection |
|
| #### 配置四大参数,用于获得mysql链接 |
|
| - 用户名、密码 |
| - url(地址)(指链接谁、链接哪个IP下,哪个端口下的哪个数据库) |
| - 驱动 |
|
| ``` |
| //加载驱动 |
| Class.forName("com.mysql.jdbc.Driver") //引号内为驱动名称 |
| //填写url,用户名,密码获得链接 |
| Connection connection= DriveManager.getConnection("jdbc:mysql://127.0.0.1:3306/库名?useUnicode=true&characterEncoding=utf-8","root","root123") //如果connection没有打印null打印出地址,表示链接成功 |
|
| ``` |
|
|
|
| 注:乱码时,在填写url时加上 ?useUnicode=true&characterEncoding=utf-8 |
|
| #### 增删改查的语句 |
|
| - 构造sql语句 |
| - 获得执行sql的对象(根据connection获得statement) |
| - 往sql里赋值 |
| - 执行 |
|
| ``` |
| String sql="insert into book_table(book_name,book_author,book_price) values(?,?,?)"; //定义sql语句 |
| PreparedStatement statement=(PreparedStatement)connection.prepareStatement(sql); |
| statement.setString(1,"三国"); |
| statement.setString(2,"某某某"); |
| statement.setLong(3,500); //数字表示第几个问号 |
| statement.executeUpdate(); //执行更新操作 |
| //int result=statement.executeUpdate(); 返回数字表示影响了几行 |
| ``` |
|
|
|
| 注:直接使用Statement对象执行sql语句,拼接字符串时,会有sql注入攻击的安全隐患 |
|
| 如:select*from user_table where user_name='tom' and user_pwd='456' or 1=1; |
|
| - 删除 |
|
| ``` |
| String sql="delete from book_table where book_id=?"; |
|
|
|
|
| ``` |
|
| - 更改 |
|
| ``` |
| String sql="update book_table set book_name=? where book_id=?"; |
|
|
|
|
|
| ``` |
|
|
| - 查询 |
|
| ``` |
| String sql="select * from book_table where book_name=? and book_price=?"; |
| PreparedStatement statement=(PreparedStatement)connnection.preparedStatement(sql); |
| statement.setString(1,"三国"); |
| statement.setInt(2,200); |
|
| Resultset set=statement.executeQuery(); |
|
| while(set.next()){ |
|
|
| } |
| ``` |
|
|
|
|
|
|
|
| # IO流 |
|
| ## File |
|
| - File包含视频、图片、音频等,也包括文件夹 |
|
|
|
| ### 访问文件的相关方法: |
|
| - File file=new File("d:/text/aaa.txt"); |
| - File file=new File(String,File); |
| - 前一个表示文件的父目录(上级目录),后一个才是该文件 |
| - 前后两个参数都可以传String或者File,都表示前一个是上级目录,后一个是该文件名 |
| - file.getName(); 返回文件名 |
| - file.getPath(); 返回该文件的路径名(不常用) |
| - file.getAbsoluteFile(); 返回该文件的绝对路径(用这个) |
| - file.getParents(); 返回该文件的对应目录的父目录(也就是上级目录) |
|
| - file.renameTo(); 重命名此文件,成功则返回true,否则返回false |
| - 注:重命名时,括号内重新写上新的New File,要把重命名好的文件的路径写上,否则默认删除原文件,在当前目录重新创建该文件并重命名(该方法与剪切相同) |
|
| - file.lastModified(); 返回文件的最后修改时间,返回毫秒值 |
| - file.length(); 返回文件的长度,返回的是多少字节 |
| - file.getFreeSpace(); 得到当前盘剩余多少空间,返回的是字节 |
| - file.getTotalSpace(); 返回当前盘总共有多少空间 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| ### 文件检测相关的方法: |
|
| - file.exists(); 判断该文件是否存在 |
|
| - file.canWrite(); 判断该文件是否可写 |
|
| - file.canRead(); 判断该文件是否可读 |
|
| - file.canExecute(); 判断该文件是否可执行 |
|
| - file.isFile(); 判断该文件是否是文件,而不是文件夹 |
|
| - file.isDirectory(); 判断该对象是否是目录 |
|
| - file.isAbsolute(); 判断该文件的路径是否是绝对路径 |
|
| - file.isHidden(); 判断该文件是否是隐藏的 |
|
|
|
|
|
|
|
|
|
| ### 文件操作的方法: |
|
| - file.createNewFile(); 当文件不存在时,创建一个该File对象所对应的文件,创建成功返回true,否则false |
|
| - file.delete(); 删除该File对象 |
|
| - 注:使用该方法时,当删除的是一个文件夹且文件夹有内容时,文件夹不会被删除,如果是个空文件夹则可以删除成功 |
|
| - file.mkdir(); 在指定目录下创建该文件夹 |
|
| - 注:如果要创建层层嵌套的多个文件夹需要用.mkdirs(); |
|
| - file.mkdirs(); 创建该对象路径中的所有目录,如果上级目录不存在,会同时将上级目录创建出来 |
|
| - file.listFile(); 列出File对象的所有子文件和路径,返回File数组 |
|
| - 注:返回的对象需要用数组去接收,然后再遍历数组输出 |
|
| - 该方法只会找出File对象内的文件,不会再找出文件夹内包含的所有内容,如果要再往下一层一层查找所有,需要用到递归 |
|
| - 递归方法: |
|
| - ``` |
| public static void getFiles(File file){ |
|
|
|
|
|
|
|
|
|
| } |
| ``` |
|
|
|
| - file.listRoots(); 找到有几个盘,返回的也是数组 |
|
| - 查看盘服的大小容量: |
|
| - ``` |
| File[] roots=File.listRoots(); |
| for(File root:roots){ |
|
|
| } |
| ``` |
|
|
|
|
|
| ## io |
|
| ### 分类: |
|
| - 按照数据流向: |
| - 输入流(FileInputStream):读入数据 |
| - 输出流(FileOutputStream):写出数据 |
|
| - 按照数据类型: |
| - 字节流 |
| - 字节流可以处理任何东西,文字照片视频。用不了字符流就用字节流 |
| - 抽象基类(基类就是父类):InputStream OutputStream |
| - 用的时候用子类:FileInputStream FileOutputStream |
| - 字符流 |
| - 如果数据所在的文件通过windows自带的记事本打开并能看得懂里面的内容,就用字符流 |
| - 抽象基类(父类):Reader Writer |
| - 子类:FileReader FileWriter |
|
|
|
|
|
| ## FileOutputStream |
|
| ### 构造方法 |
|
| - FileOutputStream stream=new FileOutputStream(String); |
| - 构造参数可以再加一个boolean,代表内容不会替换,接着原本的内容追加去写 |
| - 参数String写路径的时候可以加上不存在的文件名或路径,会在新创建的文件内写内容 |
|
| ### 方法: |
|
| - stream.write(); 写出 |
| - 参数可以传int |
| - 传进的int数字,按照ASCII表被转换成了字符 |
| - 传byte[] |
| - byte[] bytes={98,99,62}; 一样打印的是字符 |
| - 传(byte[],int off,int len) |
| - 两个int,前一个Int代表从哪个索引开始传,后一个int代表传几个元素 |
| - 想要直接传字符进去: |
| - stream.write("hello".getBytes()); |
| - 将字符串转为字节数组 |
| - stream.write("\r\n".getBytes()); |
| - 对后面追加的内容进行换行 |
| - 在windows系统内换行是\r\n |
| - linux:\n |
| - mac:\r |
| - stream.close(); 关闭IO流 |
|
|
|
|
|
|
|
| ## FileInputStream |
|
| ### 构造方法: |
|
| - FileInputStream stream=new FileInputStream(); |
| - 参数只可以传String或者File(也就是文件的路径),不能加boolean |
|
|
|
| ### 方法: |
|
| - stream.read(); 读入 |
|
| - 读入方法是有返回值的,返回值类型是Int,代表读到的字符所对应的ASCII表的数字 |
|
| - stream.read();参数内什么都不传,代表只读一个字符,返回该字符在ASCII表对应的数字 |
|
| - ``` |
| int result=stream.read(); |
| System.out.println((char)result); |
| ``` |
|
| - 因为返回的是数字,所以要将数字进行强制类型转换,在前面加(char) |
|
| - 注:如果读不到字符时,返回的数字是-1 |
|
| - 用stream.read(); 一个一个字符去读一段话时,用循环来做 |
|
| - ``` |
| int by=stream.read(); //用来接收读到的每一个字符对应的数字 |
| while(by!=-1){ //读到的数字不等于-1代表读到了字符内容 |
|
|
| } |
|
|
| inputStream.close(); |
| ``` |
|
| - 缩减改进后: |
|
| - ``` |
| int by=0; |
| while((by=stream.read())!=-1){ |
|
| } |
| inputStream.close(); |
| ``` |
|
|
|
| ### 字符流读入内容: |
|
| - stream.read(byte[]); |
|
| - 传进一个字节数组,在该数组用动态初始化规定范围后,读入的就是文章中规定范围个数的字节数,读到后,把读入的内容放进字节数组中 |
|
| - ``` |
| byte[] bytes=new byte[1024]; //动态初始化字节数组的范围,读入字节的最大范围就是规定的这个数字 |
| int len=0; //字节数组的长度,也就是读到了多少个字节 |
| while((len=stream.read(bytes))!=-1){ //在读到了字节后,长度一定是大于-1 |
|
|
| } |
|
| stream.close(); |
| ``` |
|
| - 注:加上0和len的目的是防止字符数组容量过大,实际读到的内容只有一点,但是在每次转换为字符串时,字符数组中的空余内容都会被转换一次,效率低 |
|
| - 注2:在规定字节数组的容量时,注意编码格式,GBK内的一个中文字符表示两个字节,如果规定的的字节数组范围是单数时,就会有一个字符只读了一半,所以规定范围时,一定是编码格式字节数的倍数 |
|
|
|
| ### 输入流和输出流的结合: |
|
| - ``` |
| FileInputStream stream=new FileInputStream("d:/111.txt"); |
| FileOutputStream stream2=new FileOutputStream("d:/222.txt"); |
| byte[] bytes=new byte[1024]; |
| int len=0; |
| while((len=stream.read(bytes))!=-1){ |
|
| } |
| stream.close(); |
| stream2.close(); |
|
| ``` |
|
|
|
|
|
| ## BufferedInputStream |
|
| - BufferedInputStream buf=new BufferedInputStream(new FileInputStream(d:/222.txt)); |
| - 参数内传一个输入流 |
|
| ### 方法: |
|
| ? |