1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 华清远见-重庆中心-JAVA高级阶段技术总结/知识点梳理/面试题解析

华清远见-重庆中心-JAVA高级阶段技术总结/知识点梳理/面试题解析

时间:2023-04-29 11:51:14

相关推荐

华清远见-重庆中心-JAVA高级阶段技术总结/知识点梳理/面试题解析

String字符串

String是一个类,属于数据类型中的引用类型。

Java中一切使用""引起来的内容,都是这个类的实例,称为字符串对象。

字符串在定义后,值不可改变,是一个常量,实际是一个字符数组

创建字符串对象

1.使用" "赋值创建以及创建字符串的过程

2.通过构造方法创建

使用构造方法String(String str)创建

使用+拼接""和new出来的字符串对象创建

字符串String类中的常用方法

可变字符串

String字符串对象是一个常量,在定义后,值不可改变。

如果使用String类的对象,对其频繁更新时,就会不停地创建新的对象,不停引用给同一个变量。 如要执行10000次循环重新赋值的过程,就要创建10000个字符串对象,执行效率很低,这时就需要使 用可变字符串对象。

StringBuilder类

用于表示可变字符串的一个类,是非线程安全的,建议在单线程环境下使用。

StringBuffer类

用于表示可变字符串的一个类,是线程安全的,建议在多线程环境下使用。

构造方法

普通方法

注意:

以上表格中的方法都是在直接操作同一个字符串对象,每次调用方法后,原字符串都会发生变化StringBuffer和StringBuilder并没有重写equals方法,所以可变字符串的值是否相同时,调用的是 equals中原始的==判断。如果要判断两个可变字符串的值是否相同时,需要将其转换为String后调 用equals判断

可变字符串与String之间的转换

String转换为可变字符串

可变字符串转换为String(任意类型对象转换为String)

方法一:String.valueOf(Object obj)方法

方法二:对象.toString();

方法三:

方法调用时传值问题

Date类

用于表示日期时间的类,位于java.util包下

构造方法

常用方法

SimpleDateFormat类

用于格式化日期的类。

构造方法

日期模板

常用方法

Calendar类

表示日历的类,包含了很多日历相关的信息。 是一个抽象类,无法创建对象。可以通过静态方法getInstance()获取该类的一个实例。

日历字段

在Calendar类中,定义了很多被final和static修饰的常量,称为日历字段,实际一个数字,用于获取指 定信息

常用方法

包装类

Java是纯面向对象语言,宗旨是将一切事物视为对象处理。但原始类型不属于对象,不满足面向对象的思想。但原始类型在使用时无需创建对象,保存在栈中,效 率高。 为了让原始类型也有对应的类类型,达到"万物皆对象"的理念,所以就有了包装类的概念包装类就是原始类型对应的类类型。包装类通常用于字符串与原始类型之间的转换。在web应用中,从浏览器页面中获取到后台的数据,全部都是String类型,所以一定要使用转换为原始 类型的方法。

特点:

八个原始类型中,除了int和char,其余类型的包装类,都是将首字母改为大写。int对应 Integer,char对应Character包装类都是被final修饰的,不能被继承除了Character类,其余包装类都有两个构造方法:参数为原始类型或String的构造方法。 Character的构造方法只有一个,参数为char类型。这些构造方法用于将原始类型或字符串转换为 包装类对象除了Character类,其余类都有静态方法parse原始类型(String str),用于将字符串转换为相应的 原始类型除了Boolean类,其余包装类都有MAX_VALUE和MIN_VALUE这两个静态属性,用于获取对应类 型支持的最大最小值所有包装类都重写了toString()方法,用于将包装类对象转换为String对象

字符串与原始类型之间的转换

字符串转换为原始类型

使用原始类型对应的包装类,调用parse原始类型(字符串)方法

原始类型转换为字符串

使用+拼接一个空白字符串将原始类型转换为包装类后,调用toString()方法String.valueOf(原始类型数据)

装箱和拆箱

所有包装类都有一个静态方法valueOf(原始类型),将某个原始类型的数据转换为相应的包装类对 象。这个过程称为装箱boxing。所有包装类都有一个原始类型Value()方法,用于将包装类对象转换为原始类型。这个过程称为拆 箱unboxing。自动装箱和拆箱。在jdk1.5之后,为了方便原始类型和包装类之间做转换,加入了自动装箱拆箱的 概念,可以直接将原始类型和包装类对象之间互相赋值自动装箱缓冲区

异常

当程序没有按开发人员的意愿正常执行,中途出现错误导致程序中断,出现这种情况,就称为异常。 学习异常就是认识异常的种类,如何处理异常和避免异常出现。

异常的产生

异常在程序中以对象的形式存在。当代码执行过程中出现异常,虚拟机会自动创建一个异常对象,如果 没有对象该异常对象进行处理,就会导致程序中断,不再执行后续代码。

异常的分类

异常在程序中以对象的形式存在,就有相应的类。 所有的异常类,组成了一个"异常家族"。

Error错误

如果出现xxxxError,如StactOverFlowError,栈空间溢出,无法通过额外的代码解决,只能修改源码。

Exception异常

如果出现xxxxException,如NullPointerException,空指针异常,可以通过额外的代码去解决。

运行时异常RuntimeException,如果一个异常类属于RuntimeExcption异常类的子类,称为运行时异常,可以通过编译,可以不 用处理,运行时可能抛出异常对象。编译时异常,如果一个异常类属于Exception异常类的子类,称为编译时异常,无法通过编译,必须处理异常后 才能编译运行。

处理异常

通常所说的处理异常,是指处理Exception类的子类异常。 处理异常的目的,就是保证程序正常执行。

方式一:try-catch-finally语句

这种方式处理异常,无论会不会抛出异常,都能让程序正常执行。

执行流程:先执行try中的代码,当出现异常,与后续catch中的异常类型进行匹配,如果匹配到对应的 类型或异常父类型,则执行大括号中的代码,最终一定执行finally中的内容。

try-catch-finally使用时注意

try、catch、finally都不能单独使用,try需要配合catch或finally或catch和finally一起使用执行try中的内容时,当某行代码抛出异常,不再执行try中该行代码后续的内容无论try中的代码是否会抛出异常,finally中的代码一定会执行如果代码会抛出多个异常,可以使用多个catch进行捕获,需要将异常子类放在最前,异常父类放 在最后在try中定义的内容,无法在try之外的地方使用try中如果有return,不影响finally的执行,finally优先于return执行

方式二:throws关键字

这种方式,可以让编译时异常通过编译。 在定义方法的时候,通过该关键字声明可能抛出的异常。 用法:方法的参数部分之后,添加"throws 异常类型1,异常类型2..."

throw和throws

throws表示用于声明方法有可能出现的异常。使用时写在方法的小括号之后throw用于手动抛出异常对象。使用时,写在方法体中,常用于满足某种情况时,强制中断程序 用法:throw 异常对象;

自定义异常

如果需要在某种情况下中断程序, 可以自定义一个异常类,再通过throw关键字手动抛出。

自定义异常步骤

1.定义一个类,继承某个异常类

如果继承的是RuntimeException,表示自定义的异常类属于运行时异常,该异常对象可以不用处 理如果继承的是非RuntimeException,表示自定义的异常类属于编译时异常,该异常对象必须要处 理

2.可选操作。定义带参构造方法,参数为异常信息,调用父类中的构造方法

数组和集合

数组的特点

数组中保存的元素都是有序的,可以通过下标快速访问数组中保存的数据都是同一种类型数组的长度在定义后,无法改变 数组无法获取其中保存的元素实际数量

集合的特点

能保存一组数据,可以有序可以无序集合的容量可变集合中可以保存不同类型的数据可以获取集合中保存的元素实际数量

集合框架(集合家族)

Collection还有父接口Iterable,但Iterable接口不算严格意义上的集合的根接口。它称为迭代器,是用 于遍历集合元素的一个工具接口。 所有集合的根接口为Collection接口和Map接口,位于java.util包中。

Collection接口

该接口有两个核心子接口:List和Set。

这两个接口都可以保存一组元素,List接口保存元素时,是有序可重复的;Set接口保存元素时,是无序 不重复的。

List接口(有序可重复)

有序集合,元素可以重复,允许保存null,可以通过索引获取对应位置上的元素。 在该接口继承Collection接口的同时,又拓展了一些操作元素的方法,如添加到指定索引、根据索引删 除、获取指定索引的元素、截取子集合的方法等。

构造方法

ArrayList实现类

采用数组实现的集合可以通过索引访问元素,可以改变集合大小。如果要在其中插入或删除元素时,会影响后续元素 该集合中保存的都是引用类型,即便保存了数组123,也保存的是Integer类型的123,而不是int类 型的123该集合查询效率高,中途增加和删除元素效率低

LinkedList实现类

采用双向链表实现的集合集合中保存的每个元素也称为节点,除首尾节点外,其余节点都保存了自己的信息外,还保存了其 前一个和后一个节点的地址如果在双向链表的数据结构中插入和删除操作节点时,不会影响其他节点的位置。如添加时新节点 时,只需要重写定义新节点的前后节点位置即可如果要查询某个节点时,需要从头结点或尾结点开始一步步得到目标节点的位置双向链表在中间插入和删除的效率高,随机读取的效率低

构造方法

常用方法

由于LinkedList既实现了List接口,又实现了Deque接口,所以还有Deque接口中的一些方法

Set接口(无序不重复)

无序集合,元素不可以重复,允许保存null,没有索引。 Set接口中没有自己定义的方法,都是继承于Collection接口中的方法

哈希表hash table

哈希表,也称为散列表,是一种数据结构,能更快地访问数据。 要保存的数据称为原始值,这个原始值通过一个函数得到一个新的数据,这个函数称为哈希函数,这个 新数据称为哈希码,哈希码和原始值之间有一个映射关系,这个关系称为哈希映射,可以构造一张映射 表,这个表称为哈希表。在哈希表中,可以通过哈希码快速地访问对应的原始值。

假设原本的数据为左侧的数组。 如果要查询10,需要遍历数组,效率不高。 通过一个特定的函数"原始值%5",得到一组新数据,让新数据重新对应元素,保存到“新数组”中,这个 “新数组”称为哈希表。 这时如果要查询10,由于哈希函数是通过%5得到了0,所以直接查询哈希表中0对应的元素即可。 整个过程中,这个函数称为哈希函数,得到的新数据称为哈希码,新数组称为哈希表,对应关系称为哈 希映射。 这个哈希函数,有一定的几率让多个原始值得到相同的哈希码,这种情况称为哈希冲突(哈希码一致,实 际值不同), 为了解决哈希冲突,可以使用"拉链法",将2这个哈希码所在的位置向链表一样进行延伸。

哈希码的特点

如果两个对象的hashCode不同,这两个对象一定不同如果两个对象的hashCode相同,这两个对象不一定相同,hashCode相同,对象不同,这种现象称为哈希冲突,"通话"和"重地"这两个字符串的hashCode相同,但是两个不同的对象

HashSet实现类

采用哈希表实现元素不能重复,无序保存,允许保存一个null本质是一个HashMap对象使用HashSet集合时,通常要重写实体类中的equals和hashcode方法

构造方法

常用方法

HashSet中没有属于自定义的方法,都是重写了父接口Set和Collection中的方法。这里参考Collection中 的方法即可。没有与索引相关的方法。

HashSet的应用

如果想要保存的对象保证不重复,且无关顺序,可以使用HashSet。如学生管理

Goods类

package com.hqyj.hashsetTest;import java.util.Objects;/** 定义商品类* 品牌、名称、价格* */public class Goods {private String brand;private String name;private int price;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Goods goods = (Goods) o;return price == goods.price &&Objects.equals(brand, goods.brand) &&Objects.equals(name, goods.name);}/** 根据所有属性生成哈希码* 如果两个对象的所有属性都一致,生成的哈希码就一致* */@Overridepublic int hashCode() {return Objects.hash(brand, name, price);}@Overridepublic String toString() {return "Goods{" +"brand='" + brand + '\'' +", name='" + name + '\'' +", price=" + price +'}';}public Goods(String brand, String name, int price) {this.brand = brand;this.name = name;this.price = price;}public String getBrand() {return brand;Main类}public void setBrand(String brand) {this.brand = brand;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}}

Main类

package com.hqyj.hashsetTest;import java.util.HashSet;import java.util.Iterator;public class Main {public static void main(String[] args) {//创建一个HashSet集合HashSet<Goods> hs = new HashSet<>();//创建几个Goods对象//g1、g2、g3的属性不同,生成的hashcode不同,都能添加Goods g1 = new Goods("康师傅", "冰红茶", 3);Goods g2 = new Goods("康师傅", "红烧牛肉面", 5);Goods g3 = new Goods("农夫山泉", "矿物质水", 2);//g3与g4的属性相同,生成的hashcode相同,继续判断equalsGoods g4 = new Goods("农夫山泉", "矿物质水", 2);//第一次添加,一定可以添加hs.add(g1);//第二次添加,对象的属性不同,hashcode不同,可以添加hs.add(g2);//第三次添加,对象的属性不同,hashcode不同,可以添加hs.add(g3);//第四次添加,对象的属性相同,hashcode相同,再判断equals结果,true,视为已存在,无法添加hs.add(g4);/** HashSet没有可以通过索引获取对象的方法,所以无法使用普通for循环遍历* 这里可以使用增强for循环* */for (Goods g : hs) {System.out.println(g);}/** 可以使用迭代器遍历HashSet集合中的所有元素* *//*Iterator<Goods> it = hs.iterator();while (it.hasNext()) {Goods goods = it.next();System.out.println(goods);}*/}}

Map接口

Map称为映射,数据以键值对的形式保存。保存的是键与值的对应关系。 键称为Key,值称为Value,键不能重复,键允许出现一个null作为键,值无限制。 键和值都是引用类型。 如,yyds就是一个键key,代表了一个含义:“永远单身”即为值value。

HashMap实现类

构造方法

遍历集合中元素的方式

遍历List集合

方式一:普通for循环

方式二:增强for循环

方式三:迭代器

泛型

一种规范,常用于限制集合中元素的类型,省去遍历元素时判断是否为对应类型和转型的过程

用法

在定义集合遍历时,在类后面写上<引用数据类型>

集合类或接口<引用数据类型>集合变量名 = new 集合实现类();

文件类File

Java中的File类,表示本地硬盘中的文件(文件和目录)的一个类。 通过这个类创建的对象,可以操作对应的文件。

构造方法

常用方法

斐波那契数列

package com.hqyj.FileTest;public class Test2 {public static void main(String[] args) {//兔子问题//有一对兔子在第三个月开始,每个月都能生一对小兔子//如果所有兔子不死亡,且每次生下的都是一雌一雄,问10个月后共有多少对兔子//1月 2月 3月 4月 5月 6月 7月 8月 9月 10月//1 1 2 3 5 8 13 21 34 55//斐波那契数列//f(n)=f(n-1)+f(n-2) n>2Test2 t = new Test2();System.out.println(t.f(20));}/** 递归方法* */public int f(int n) {if (n > 2) {return f(n - 1) + f(n - 2);}return 1;}}

递归遍历文件夹

package com.hqyj.FileTest;import java.io.File;import java.util.Date;public class Test3 {//查看某个目录下的所有文件public static void main(String[] args) {File source = new File("E:\\adobe");Test3 t = new Test3();t.fun(source);}/** 递归遍历文件夹* */public void fun(File source) {//输出某个目录中超过3个月未使用且大于500MB的文件/*long start = source.lastModified();long end = System.currentTimeMillis();if ((end - start) / 1000 / 3600 / 24 > 90 && source.length() / 1024 /1024 > 500) {System.out.println(source.getName() + "\t" + newDate(source.lastModified()) + "\t" + source.length() / 1024 / 1024);}*///判断是否为目录if (source.isDirectory()) {//将其展开for (File child : source.listFiles()) {//因为子文件有可能是目录,继续调用本方法fun(child);}}}}

IO

I:Input输入

O:Output输出

流Stream

在Java中,流用于表示计算机硬盘与内存之间传输数据的通道。将内存中的数据存入到硬盘中,称为写write,也称为输出Output。将硬盘中的数据存入到内存中,称为读read,也称为输入Input。

流的分类

Java中将流定义为类,以对象的形式表现流。流有"四大家族",是所有流的父类。

字节输入流InputStream

FileInpuStream、ObjectInputStream

字节输出流OutputStream

FileOutputStream、ObjectOutputStream

字符输入流Reader

FileReader、BufferedReader、OutputStreamWriter

字符输出流Writer

FileWriter、BufferedWriter、InputStreamReader

FileInputStream文件字节输入流

按字节读取硬盘中的文件。

构造方法

常用方法

FileOutputStream文件字节输出流

按字节将内存中的数据写入到硬盘中。

构造方法

常用方法

使用FileInputStream和FileOutputStream 读写时的注意事项

在通过FileInputStream对象使用read(byte[] bytes)方法时,每次读取指定数组的字节,将读取到 的字节保存在字节数组中,该方法返回读取到的字节数量。如果最后一次读取的字节数不足字节数 组的大小时,只会将读取到内容覆盖数组中最前的几个元素。所以会导致读取到的内容多于实际内 容。在通过FileOutputStream对象使用write(byte[] bytes)方法时,会将字节数组中的所有内容写入到 输出流中,在最后一次写入时,可能会写入多余的内容。所以在写入时,最好使用write(byte[] bytes,int off,int lef)方法,表示将字节数组中的内容,从off开始写入len个。

如有word.txt文件,其中保存aaabbbccc

FileInputStream fis = new FileInputStream("d:/word.txt");FileOutputStream fos = new FileOutputStream("d:/copy.txt");byte[] bytes = new byte[4];//第一次读取4个字节,即aaab,count为4int count=fis.read(bytes);//写入数组中的全部内容fos.write(bytes);//第二次读取4个字节,即bbcc,count为4count=fis.read(bytes);//写入数组中的全部内容fos.write(bytes);//第三次读取1个字节c,覆盖数组中的第一个元素,即数组现在为cbcc,count为1count=fis.read(bytes);//写入数组中的全部内容fos.write(bytes);//最终会写入aaabbbcccbccfos.write(bytes,0,count);//这样最后一次只会写入实际读取到的cfos.close();fis.close();

使用FileInputStream和FileOutputStream 实现单文件的复制

package com.hqyj.IOTest;import java.io.*;public class CopyFile {public static void main(String[] args) throws IOException {//定义原文件和目标文件File source = new File("F:\\221001\\录屏\\FileInputStream和FileOutputStream.mp4");File target = new File("F:\\221001\\copy.mp4");//定义文件字节输入流,用于读取原文件FileInputStream fis = new FileInputStream(source);//定义文件字节输出流,用于写入文件FileOutputStream fos = new FileOutputStream(target);/*//调用无参的read()方法,表示读取一个字节,返回读取到的字节int read = fis.read();//如果能读取到内容while (read > -1) {//将读取到的内容写入到文件中fos.write(read);//继续读取read = fis.read();}*///定义一个字节数组,大小为8MBbyte[] bytes = new byte[1024 * 1024 * 8];//按字节数组读取,返回读取到的字节数量int count = fis.read(bytes);//循环读取写入while (count > -1) {//将读取的字节数组写入到文件中// fos.write(bytes);//如果调用该方法,最后一次会多写入上一次残留的数据fos.write(bytes,0,count);//如果调用该方法,实际读取到了多少字节就写入多少count = fis.read(bytes);}fis.close();fos.close();if (target.exists()) {System.out.println("复制成功");}}}

文件夹的复制

package com.hqyj.IOTest;import java.io.*;public class CopyDirectory {public static void main(String[] args) {/*File source = new File("F:\\221001\\录屏\\流的基本概念.mp4");File target = new File("F:\\221001\\copy.mp4");copyFile(source, target);*/File source = new File("F:\\221001\\笔记");File target = new File("F:\\221001\\笔记副本");/** source F:\221001\笔记* target F:\221001\笔记副本* 1.调用copyDir方法,判断发现source是一个文件夹,创建目标文件夹target:“F:\221001\笔记副本”* 2.遍历source,如其中有xxx.md文件,即child* 此时的source是F:\221001\笔记\xxx.md,即child* 此时的target是F:\221001\笔记副本\xxx.md,用File(File parent,String child)构造方法表示这个目标文件* 所以创建File newTarget = new File(target,child.getName())** */copyDir(source, target);}/** 定义复制文件夹的方法* */public static void copyDir(File source, File target) {//如果是文件,调用单文件复制的方法if (source.isFile()) {copyFile(source, target);} else {//如果是文件夹//创建要复制的目标文件夹target.mkdir();//展开原文件夹for (File child : source.listFiles()) {//定义复制后的新目标文件//如source为F:\221001\笔记\day1.md时,递归调用的target为F:\221001\笔记副本\day1.mdFile newTarget = new File(target, child.getName());//这里使用File(File parent,String child)构造方法创建target对象//递归调用的原文件依然是当前遍历出来的子文件,目标文件就是最终复制的F:\221001\笔记副本\day1.mdcopyDir(child, newTarget);}}}/** 定义单文件复制的方法* */public static void copyFile(File source, File target) {FileInputStream fis = null;FileOutputStream fos = null;try {//创建用于输入输出的流对象fis = new FileInputStream(source);fos = new FileOutputStream(target);//定义字节数组byte[] bytes = new byte[1024 * 1024 * 8];//按数组读取int count = fis.read(bytes);while (count != -1) {fos.write(bytes, 0, count);count = fis.read(bytes);}} catch (FileNotFoundException e) {System.out.println("文件不存在" + e);} catch (IOException e) {System.out.println("读写异常" + e);} finally {try {if (fis != null) {fis.close();}if (fos != null) {fos.close();}} catch (IOException e) {System.out.println("关闭流对象异常" + e);}}}}

BufferedReader缓冲字符输入流

自带缓冲区(字符数组)的字符输入流。默认字符数组大小为8192,每次最多读取8192个字符。 在读取纯文本文件(txt或md)时,首选该类。

构造方法

常用方法

读取文本练习

package com.hqyj.ReaderAndWriter;import java.io.*;public class Test2 {public static void main(String[] args) throws IOException {/*File file = new File("F:\\221001\\笔记\\Java基础回顾.md");//FileReader(File file)Reader fr = new FileReader(file);//BufferedReader(Reader in)BufferedReader br = new BufferedReader(fr);*///创建带有缓冲区的字符输入流对象BufferedReader br = new BufferedReader(new FileReader("F:\\221001\\笔记\\Java基础回顾.md"));//循环判断是否还有字符while (br.ready()) {//读取整行System.out.println(br.readLine());}//关闭最大的流对象即可br.close();}}

BufferedWriter缓冲字符输出流

自带缓冲区(字符数组)的字符输出流

构造方法

常用方法

写入文本练习

package com.hqyj.ReaderAndWriter;import java.io.*;import java.text.SimpleDateFormat;import java.util.*;import java.util.logging.SimpleFormatter;public class Test3 {public static void main(String[] args) throws IOException {File file = new File("221001.txt");//创建缓冲字符输入流对象,读取文本BufferedReader br = new BufferedReader(new FileReader(file));//创建集合,保存读取到的姓名ArrayList<String> list = new ArrayList<>();//循环读取文件中的所有字符while (br.ready()) {String name = br.readLine();list.add(name);}//关闭br.close();//打乱集合中的元素Collections.shuffle(list);//创建日期字符串String today = new SimpleDateFormat("yyyy.MM.dd").format(new Date());//创建缓冲字符输出流,用于写文本,文件名为"日期+作业情况.txt",如果每次都是新建,这样写// BufferedWriter bw = new BufferedWriter(new FileWriter(today + "作业情况.txt"));//如果要追加,在new FileWriter("文件名",true)设置BufferedWriter bw = new BufferedWriter(new FileWriter(today + "作业情况.txt",true));//写入字符串bw.write("姓名\t\t是否完成");//换行bw.newLine();Scanner sc = new Scanner(System.in);//随机3个人for (int i = 0; i < 3; i++) {String name = list.get(i);System.out.println(name + "完成情况:");String str = sc.next();//写入读取到的内容bw.write(name + "\t\t" + str);//换行bw.newLine();}bw.close();}}

ObjectOutputStream对象字节输出流(序列化)

序列化:将对象转换为文件的过程 被序列化的对象,必须要实现Serializable接口。 这个接口是一个特殊的接口,没有定义任何方法,只是给该类加上标记,表示该类可以被序列化

构造方法

常用方法

ObjectInputStream对象字节输入流(反序列化)

反序列化:将文件转换为对象的过程

构造方法

常用方法

序列化和反序列化案例

Person类,实现Serializable接口

package com.hqyj.ObjectStream;import java.io.Serializable;/** 如果希望该类的对象能序列化,写入对象到本地,必须要实现Serializable接口* Serializable接口中没有任何方法,是一个标记接口,表示该类的对象可以被序列化* */public class Person implements Serializable {private String name;private int age;private String sex;//省略getter/setter和toString()}

Main类

package com.hqyj.ObjectStream;import java.io.*;import java.util.ArrayList;public class Test1 {public static void main(String[] args) throws IOException,ClassNotFoundException {Person p1 = new Person("王海", 22, "男");Person p2 = new Person("赵敏", 24, "女");Person p3 = new Person("刘涛", 21, "女");ArrayList<Person> list = new ArrayList<>();list.add(p1);list.add(p2);list.add(p3);//创建OutStream的实现类,设置写入的文件路径OutputStream os = new FileOutputStream("F:\\221001\\person.p");//创建对象输出字节流,参数为OutStream类型ObjectOutputStream oos = new ObjectOutputStream(os);//调用writeObject(Object obj)方法,将对象写入到硬盘中(序列化)oos.writeObject(list);oos.close();//创建对象输入字节流,将上一步保存的文件进行反序列化ObjectInputStream ois = new ObjectInputStream(newFileInputStream("F:\\221001\\person.p"));//使用readObject()方法,将写入的文件进行读取(反序列化)ArrayList<Person> pList = (ArrayList<Person>) ois.readObject();for (Person person : pList) {System.out.println(person);}ois.close();}}

网络编程

InetAddress类

表示IP对象的一个类

public static void main(String[] args) throws UnknownHostException {//获取本机的ip对象// InetAddress ip = InetAddress.getLocalHost();//获取域名// System.out.println(ip.getHostName());//获取真实ip地址// System.out.println(ip.getHostAddress());//getByName(域名) 得到域名对应的ip对象//localhost域名表示本机,对应的ip地址为127.0.0.1InetAddress ip = InetAddress.getByName("localhost");//获取域名System.out.println(ip.getHostName());//获取ip地址System.out.println(ip.getHostAddress());}

Socket类和ServerSocket类

都属于Socket(套接字)对象,表示网络中的某个端点

Socket指普通端ServerSocket指服务器端

使用套接字对象实现两个端点(Socket和 ServerSocket)之间发送文件

服务器端

package com.hqyj.uploadTest;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import .InetAddress;import .ServerSocket;import .Socket;import .UnknownHostException;/** 使用套接字对象,实现客户端向服务端发送文件** 定义服务端套接字对象* */public class Server {public static void main(String[] args) throws IOException {//以本机创建服务端套接字对象ServerSocket server = new ServerSocket(8899, 100,InetAddress.getLocalHost());//等待客户端连接,返回连接的客户端套接字对象Socket client = server.accept();//定义要将读取到的数据写入到本地的文件字节输出流对象FileOutputStream fos = new FileOutputStream("上传文件.md");//获取客户端与服务端的输入流对象,读取发送的数据InputStream is = client.getInputStream();//定义读取的字节数组byte[] bytes = new byte[1024 * 1024 * 8];int count = is.read(bytes);while (count != -1) {//将读取到的数据写入到本地fos.write(bytes, 0, count);count = is.read(bytes);}fos.close();is.close();}}

客户端

package com.hqyj.uploadTest;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;import .Socket;/** 定义客户端套接字对象* */public class Client {public static void main(String[] args) throws IOException {//创建客户端套接字对象,连接指定的服务端套接字对象Socket client = new Socket("192.168.31.39", 8899);//获取客户端与服务端的输出流对象OutputStream os = client.getOutputStream();//成功连接后,将某个文件发送给服务端//定义要发送的文件对象File file = new File("F:\\221001\\笔记\\面向对象部分回顾.md");//读取要发送的文件FileInputStream fis = new FileInputStream(file);//定义字节数组byte[] bytes = new byte[1024 * 1024 * 8];//循环读取要发送的文件int count = fis.read(bytes);while (count != -1) {//将读取到的数据写入到客户端套接字与服务端套接字的通道中os.write(bytes,0,count);count = fis.read(bytes);}fis.close();os.close();}}

面试题总结

字符串相关面试题

可变字符串面试题

比较String、StringBuilder和StringBuffer的区别

相同点:

这三个类都可以表示字符串。都提供了一些操作字符串的方法。这三个类中有相同的方法,如charAt()、indexOf()等这三个类都是被final修饰的类,不能被继承

不同点:

String定义的字符串是一个常量。可变字符串定义的字符串是一个变量String类中的方法,调用后,不会改变原本字符串的值;可变字符串类中的方法,调用后,会改变 原本字符串的值StringBuilder是非线程安全的可变字符串类,StringBuffer是线程安全的可变字符串类,其中的方 法被synchronized修饰

异常相关面试题

以下代码输出的结果是:final、finally、finalize的区别final是一个修饰符,被final修饰的属性称为常量,方法不能被重写,类不能被继承finally是try-catch-finally结构中的关键字,在无论是否抛出异常,都会执行的代码块finalize是Object类中的方法,finalize()在某个对象被回收前调用的方法

个人总结

这个阶段的学习起来虽然比面对对象容易理解,但是内容很多,学到后面就不知道前面的就学了啥,还是要多花时间看一下笔记,温故而知新,加强一下记忆。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。