DAY11
Object
Object类是所有Java类的祖先,也就是说我们所说的”顶级父类”
存在于java.lang.Object,这个包不需要我们手动导包
每个类都使用Object作为超类.所有对象(包括数组)都实现这个类的方法.在不明确给出超类的情况下,Java会自动把Object类作为要定义类的超类.
常用方法介绍
toString()
本方法用于返回对应对象的字符串表示.
hashCode()
本方法用于返回对应对象的哈希码值
equals()
本方法用于指示其他某个对象是否与当前对象”相等”
练习1:Object类练习
/**本类用于测试Object类的使用*///总结://1.如果想要查看对象的属性值,需要重写toString(),否则会使用Object的默认实现,打印对象的地址值//2.如果要判断两个对象间的所有属性值相同,比较完的结果返回true,需要重写equlas(),否则会使用Object类的默认实现,==比较public class Test1_Object {public static void main(String[] args) {/**测试toString():返回该对象的字符串表示*///3.创建Student对象Student s = new Student("jack",18);//4.打印学生对象,查看属性值是否赋值成功//第一次测试:打印结果:cn.tedu.api.Student@15db9742,s对象的地址值/**查看源码的方式:按住Ctrl键,鼠标移动到目标上即可*///原因:在打印对象的s时,底层会自动调用Object类中的toString(),本来的实现方式就是打印地址值//public String toString() {return getClass.getName() + "@" +Integer.toHexString(hashCode());}//6.再次打印学生对象s//第二次测试:结果:Student [name=jack, age=18]//原因:重写了Object的toString()后,就可以打印对象的属性值了System.out.println(s);/**测试hashCode():返回对象在内存中的哈希码值*///7.调用下查看hashCode()的结果System.out.println(s.hashCode());//366712642//8.创建对象s2与s对象属性值相同Student s2 = new Student("jack",18);//第一次测试:结果:false//底层:用了==进行对象间的比较,==比较的是两个对象的地址值,s与s2是两个对象.地址值不同,所以返回false//public boolean equals(Object obj) {return (this == obj);}//需求:比较s和s2对象,如果属性值相同,就认为是用一个对象,并让equals()返回true//第二次测试:结果:trueSystem.out.println(s.equals(s2));}}//1.创建Student类并定义属性class Student{String name;int age;//2.生成构造方法//方式一:右键,选择Source,选择Generate Constructor using fields//方式二:Alt+shift+s,选倒数第三个public Student() {}//添加了含参构造后,记得手动添加无参构造public Student(String name, int age) {super();this.name = name;this.age = age;}//5.重写toString(),查看对象的属性值,否则会使用Objetc中的默认实现,查看对象的地址值//方式一:右键,选择Source,选择Generate toString()...//方式二:Alt+shift+s,选倒数第四个@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}//9.重写equlas()//需求:比较s和s2对象,如果属性值相同,就认为是用一个对象,并让equals()返回true//自己写的public boolean equals2(Object obj) {//判断,如果是学生,咱俩比较,如果连学生都不是,就返回false--匹配种类if(obj instanceof Student) {//同一个类型的对象间比较//把obj强转成Student类型,因为想用子类的特有属性,如果不转,只能用父类的属性Student argsStudent = (Student)obj;//判断:如果当前对象this和参数对象argsStudent,他们的属性&属性值完全一样,就返回trueif(this.name == argsStudent.name && this.age == argsStudent.age) {return true;}}return false;}//自动生成equlas()//方式一:右键,选择Source,选择Generate hashCode()... and equlas()//方式二:Alt+shift+s,选倒数第五个@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Student other = (Student) obj;if (age != other.age)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}
String
特点
String是一个封装char[]数组的对象,字符串不可变
通过下图中的底层实现可以看出:被final修饰,是常量
String str = “abc”; 等效于:char data[] = {‘a’, ‘b’, ‘c’};
常见方法
length()-查看字符串的长度
charAt()—定位某个字符,返回它的位置
concat()在原有的字符串上进行拼接,注意不改变原来的串
IndexOf()-某个字符开始一次出现的位置
lastIndexOf()-某个字符最后一次出现的位置
substring()-截取子串,如果参数有两个左闭右开[1,5)
equals()-判断两个串是否相等,注意String重写了Object的此方法,所以内容相同就返回true
startsWith()-判断是不是以参数开头
endsWith()—判断是不是以参数结尾
split()—以指定字符分割
trim()-去掉首尾两端的空格
getBytes()-把串转换成数组
toUpperCase()-变成全大写
toLowerCase()-变成全小写
String.valueOf(10)-把int类型的10转换成String类型
StringBuilder/StringBuffer
特点
- 封装了char[]数组
2. 是可变的字符序列
3. 提供了一组可以对字符内容修改的方法
4. 常用append()来代替字符串做字符串连接”+”
5.StringBuffer 1.0出道线程安全,StringBuilder1.5出道线程不安全
常见方法
append()
正则表达式练习:测试输入身份证号
import java.util.Scanner;/**本类用于测试正则表达式* 需求:测试输入身份证号,测试用户输入是否正确* */public class Test4_Regex {public static void main(String[] args) {//1.提示并接收用户输入的身份证号:System.out.println("请您输入您的身份证号:");String input = new Scanner(System.in).nextLine();//2.编辑正则表达式//身份证号的规律:一般都是18位,前17位都是数字,最后一位可能是数字,也有可能是xXString regex = "[0-9]{17}[0-9xX]";//3.判断,是否符合正则表达式的规则(也就是输入的是正确的身份证号吗?)if( input.matches(regex) ) {//matches()是String类提供的功能,可以用来判断字符串是否符合正则表达式的要求System.out.println("输入正确!");}else {System.out.println("输入不正确,请重新输入!");}}}
包装类
创建对象
Integer
1. new Integer(5);
2. Integer.valueOf(5);
在Integer类中,包含256个Integer缓存对象,范围是 -128到127。
使用valueOf()时,如果指定范围内的值,访问缓存对象,而不新建;如果指定范围外的值,直接新建对象。
double
1. new Double(3.14)
2. Double.valueOf(3.14)//和 new 没有区别
常见方法
Integer
static int parseInt(String s) **将字符串参数作为有符号的十进制整数进行解析**
double
Double.parseDouble();
自动装箱和自动拆箱
概述
自动装箱:把 基本类型 包装成对应的 包装类型 的过程
Integer a = 5;//a是引用类型,引用了包装对象的地址。
编译器会完成对象的自动装箱:Integer a = Integer.valueOf(5);
自动拆箱:从包装类型的值,自动变成 基本类型的值
int i = a;//a现在是包装类型,没法给变量赋值,需要把5取出来。
练习6: 自动装箱与自动拆箱测试
/**本类用来测试自动装箱与自动拆箱*/public class Test6_Box {public static void main(String[] args) {//1.定义包装类型的数据//之前的方式:创建包装类型的两种方式:Integer i11 = new Integer(127);Integer i22 = Integer.valueOf(127);//现在的方式:/**1.自动装箱:编译器会自动把基本类型int数据5,包装成包装类型Integer,然后交给i1保存* 自动装箱底层发生的代码:Integer.valueOf(5);* valueOf()的方向:int --> Interger* */Integer i1 = 5;//不会报错,这个现象就是自动装箱/**2.自动拆箱:编译器会自动把包装类型的5,拆掉箱子,变回到基本类型数据5* 自动拆箱底层发生的代码:i1.intValue()* intValue()的方向:Integer --> int* */int i2 = i1;//不会报错,这个现象就是自动拆箱}}
==和equals的区别
1.当使用==比较时,如果相比较的两个变量是引用类型,那么比较的是两者的物理地值(内存地址),如果相比较的两个变量都是数值类型,那么比较的是具体数值是否相等。
2.当使用equals()方法进行比较时,比较的结果实际上取决于equals()方法的具体实现
众所周知,任何类都继承自Object类,因此所有的类均具有Object类的特性,比如String、integer等,他们在自己的类中重写了equals()方法,此时他们进行的是数值的比较,而在Object类的默认实现中,equals()方法的底层是通过==来实现的。
StringBuilder和StringBuffer的区别
1.**在线程安全上 :
—StringBuffer是旧版本就提供的,线程安全的。@since JDK1.0
—StringBuilder是jdk1.5后产生,线程不安全的。@since 1.5
2. 在执行效率上,StringBuilder > StringBuffer > String
3.**源码体现:本质上都是在调用父类抽象类AbstractStringBuilder来干活,只不过Buffer把代码加了同步关键字,使得程序可以保证线程安全问题。
abstract class AbstractStringBuilder implements Appendable, CharSequence {
**
DAY12
BigDecimal/BigInteger
概述:
BigDecimal:常用来解决精确的浮点数运算
BigInteger: 常用来解决超大的整数运算
创建对象
BigDecimal(double val)
**将double转换为BigDecimal,后者是double的二进制浮点值十进制表示形式,有坑**!
BigDecimal(String val)
**将**String类型字符串的形式转换为BigDecimal
常用方法
Add(BigDecimal bd) : 做加法运算
Subtract(BigDecimal bd) : **做减法运算
Multiply(BigDecimal bd) : **做乘法运算
Divide(BigDecimal bd) : **做除法运算,除不尽时会抛异常
Divide(BigDecimal bd,保留位数,舍入方式) : 除不尽时使用
setScale(保留位数,舍入方式**) : 同上
pow(int n) : 求数据的几次幂
练习1:测试常用方法
/**本类用于测试浮点数运算时不精确的解决方案--BigDecimal*/public class Test1_BigDecimal {public static void main(String[] args) {//method();//使用 + - * / 完成运算,暴露浮点数运算不精确的问题method2();//使用BigDecimal来解决浮点数运算不精确的现象}public static void method2() {//20:45接着继续,大家抓紧时间完成,一会我们进IO啦//1.提示并接收用户输入的两个小数System.out.println("请输入您要计算的两个小数:");double a = new Scanner(System.in).nextDouble();double b = new Scanner(System.in).nextDouble();//2.创建工具类对象,把基本类型的a和b交给工具类对象BigDecimal来保存/**1.最好不要使用double作为构造函数的参数,不然还会产生不精确的现象,有坑!!!!*//**2.最好使用重载的,参数类型是String的构造函数,double转String,直接拼个空串就可以*/BigDecimal bd1 = new BigDecimal(a+"");BigDecimal bd2 = new BigDecimal(b+"");//3.通过BigDecimal上的方法,做精确运算//3.1定义对象来保存结果BigDecimal bd3;//3.2 add(BigDecimal bd) : 做加法运算bd3 = bd1.add(bd2);System.out.println(bd3);//3.3 subtract(BigDecimal bd) : 做减法运算bd3 = bd1.subtract(bd2);System.out.println(bd3);//3.4 multiply(BigDecimal bd) : 做乘法运算bd3 = bd1.multiply(bd2);System.out.println(bd3);//3.5 add(BigDecimal bd) : 做除法运算/**java.lang.ArithmeticException,除法运算,除不尽时会抛异常*///bd3 = bd1.divide(bd2);--方案一/**divide(m,n,o) --m是要除以哪个对象保存的值,n要保留几位,o是摄入方式,最常使用的是四舍五入*/bd3 = bd1.divide(bd2, 3, BigDecimal.ROUND_HALF_UP);//方案二:System.out.println(bd3);}public static void method() {//1.提示并接收用户输入的两个小数System.out.println("请输入您要计算的两个小数:");double a = new Scanner(System.in).nextDouble();double b = new Scanner(System.in).nextDouble();//2.做运算System.out.println( a + b );//不精确System.out.println( a - b );//不精确System.out.println( a * b );//不精确System.out.println( a / b );//不精确}}
IO简介
继承结构
In/out 相对于程序而言的输入(读取)/输出(写出)的过程.
在java中,根据处理的数据单位不同,分为字节流和字符流
字节流 : 针对二进制文件
字符流 : 针对文本文件,读写容易出现乱码的现象,在读写时,最好指定编码集为UTF-8
Java.io包下:
File
字节流:
InputStream
—FileInputStream
—BufferedInputStream
—ObjectInputStream
OutputStream
—FileOutputStream
—BufferedOutputStream
—ObjectOutputStream
字符流:
Reader
—FileReader
—BufferedReader
—InputStreamReader
Writer
—FileWriter
—BufferedWriter
—OutputStreamWriter
—PrintWriter一行行写出
Stream流的概念
数据的读写可以抽象成数据在管道中流动
流只能单方向流动
输入流用来读取à in
输出流用来写出 àout
数据只能从头到尾顺序的读写一次
File文件流
创建对象
File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新的File实例
new File(“d:/abc/a.txt”);
new File(“d:/abc”,”a.txt”);
练习**2**:测试常用方法
/**本类用于测试文件流*/public class Test2_File {public static void main(String[] args) throws IOException {//1.创建File对象//参数是具体的路径,可以是文件的路径,也可以是文件夹的路径//注意:需要手动在windows中创建D:\ready\1.txt并添加内容/**1.\在代码中具有特殊的意义,转义的作用,* 所以表示这个是一个真正的斜杠,需要转义一下*/File file = new File("D:\\ready\\1.txt");//创建的是java对象//2.测试常用方法//2.1文件与文件夹属性System.out.println(file.length());//15,获取指定文件的字节量System.out.println(file.exists());//true,判断指定文件是否存在System.out.println(file.isFile());//true,判断指定内容是否是文件System.out.println(file.isDirectory());//false,判断指定内容是否是文件夹System.out.println(file.getName());//1.txt,获取文件名System.out.println(file.getParent());//D:\ready,获取父级目录System.out.println(file.getAbsolutePath());//D:\ready\1.txt,获取绝对路径//2.2创建与删除file = new File("D:\\\\ready\\\\2.txt");/**如果指定创建文件的文件夹不存在* 会抛出异常:java.io.IOException:系统找不到指定的路径* 所以需要处理,目前的方式是抛出异常*/System.out.println(file.createNewFile());//在win中创建不存在的文件2.txtfile = new File("D:\\ready\\m");System.out.println(file.mkdir());//在win中创建不存在的单级目录file = new File("D:\\ready\\a\\b\\c");System.out.println(file.mkdirs());//在win中创建不存在的多级目录System.out.println(file.delete());//删除文件或者空文件夹,c文件夹被删除file = new File("D:\\ready\\a");System.out.println(file.delete());//由于a目录里还有b目录,所以删除不了//2.3文件列表file = new File("D:\\ready");//查看文件夹下所有文件的名称,返回值类型是String[]String[] list = file.list();System.out.println(Arrays.toString(list));/**列出文件夹中所有的文件夹和文件对象,返回值是File[]* 数组的每个元素都是File对象,可进一步操作* */File[] listFiles = file.listFiles();System.out.println(Arrays.toString(listFiles));System.out.println(listFiles[0].length());}}
练习**3**:递归求目录总大小
需求:递归求目录的总大小 D:\ready,步骤分析如下:
1.列出文件夹中的所有资源—listFiles()—>File[]
2.判断,当前资源是文件还是文件夹—文件夹大小为0,文件大小需要累加
—是文件,求文件的字节量大小length(),累加就行
—是文件夹,继续列出文件夹下的所有资源—listFiles()—>File[]
—判断,是文件,求文件的字节量大小length(),累加就行
—判断,是文件夹,再一次列出文件夹下的所有资源
—……重复操作
也就是说,规律就是:只要是文件夹,就需要重复步骤1 2
/**本类用来递归求目录总大小*/public class Test3_FileSumRecursion {public static void main(String[] args) {//1.指定要求哪个目录的总大小/**注意:此处指定的目录必须是真实存在的* 如果传一个不存在的文件夹会报错,如果是传了一个空文件夹,大小为0*/File file = new File("D:\\ready");//2.调用size()求目录大小long total = size(file);//3.接收结果并打印System.out.println("文件夹的总大小为:"+total);}private static long size(File file) {//1.列出文件夹中的所有资源--listFiles()-->File[]File[] fs = file.listFiles();//2.遍历数组,获取每file对象//2.1定义变量,记录总和long sum = 0;for(int i = 0;i < fs.length ; i++) {//2.2通过下标操作当前遍历到的资源File f = fs[i];//2.3判断,当前资源是文件还是文件夹--文件夹大小为0,文件大小需要累加if(f.isFile()) {//--是文件,求文件的字节量大小length(),累加就行sum += f.length();//相当于:sum = sum + f.length();}else if(f.isDirectory()) {//--是文件夹,继续列出文件夹下的所有资源,1 2步骤--listFiles()-->File[]/**方法的递归,递归现象,就是在方法的内部调用方法自身*/sum += size(f);}}return sum;//把sum记录的值返回调用位置}}
字节流读取
InputStream抽象类
此抽象类是表示字节输入流的所有类的超类/抽象类,不可创建对象哦
FileInputStream子类
直接插在文件上,直接读取文件数据
创建对象
FileInputStream(File file)—直接传文件对象
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定FileInputStream(String pathname)—传路径
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定
BufferedInputStream子类
BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组(默认8k大小)。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。
创建对象
BufferedInputStream(InputStream in)创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
练习**5**:字节流读取案例
/**本类用于测试文件的读取*/public class Test4_In {public static void main(String[] args) {method();//字节流的读取method2();//高效字节流的读取}public static void method() {InputStream in = null;try {//1.创建字节流读取对象//new InputStream();//报错:抽象父类不可以创建对象//FIS传入的参数是一个File对象//InputStream in2 = new FileInputStream(new File("D:\\ready\\4.txt"));//FIS传入的参数是一个路径,保证此路径下的文件是存在且有内容的in = new FileInputStream("D:\\ready\\4.txt");//2.开始读取,read()每次读取1个字节,如果读到了数据的末尾,返回-1// System.out.println(in.read());//97// System.out.println(in.read());//98// System.out.println(in.read());//99// System.out.println(in.read());//-1//3.1定义变量,记录读到的数据int b;while((b = in.read()) != -1) {//3.2返回值为-1的时候表示没有数据了,循环结束//3.3打印每次读取到的内容System.out.println(b);}} catch (IOException e) {e.printStackTrace();//打印错误信息到控制台} finally {//try-catch-finally,finally中的代码一定会被执行,常用于关流try {//4.释放资源in.close();} catch (IOException e) {e.printStackTrace();}}}public static void method2() {BufferedInputStream in = null;try {//1.创建高效字节流读取对象//new InputStream();//报错:抽象父类不可以创建对象//BIS是高效的读取流// in2 = new BufferedInputStream(// new FileInputStream(new File("D:\\ready\\4.txt")));in = new BufferedInputStream(new FileInputStream("D:\\ready\\4.txt"));//2.开始读取,read()每次读取1个字节,如果读到了数据的末尾,返回-1// System.out.println(in.read());//97// System.out.println(in.read());//98// System.out.println(in.read());//99// System.out.println(in.read());//-1//3.1定义变量,记录读到的数据int b;while((b = in.read()) != -1) {//3.2返回值为-1的时候表示没有数据了,循环结束//3.3打印每次读取到的内容System.out.println(b);}} catch (IOException e) {e.printStackTrace();//打印错误信息到控制台} finally {//try-catch-finally,finally中的代码一定会被执行,常用于关流try {//4.释放资源in.close();} catch (IOException e) {e.printStackTrace();}}}}
