第二周复习总结

目录

一、接口

1.接口的特点:

2.接口与类的复杂关系

1.类与类的关系

2.类与接口的关系

3.接口与接口之间的关系

4.接口与抽象类的区别

二、内部类

1.内部类

1.内部类的创建方式

2.内部类的特点

2.成员内部类(被private修饰)

成员内部类特点:

3.静态内部类(被static修饰)

静态内部类特点:

4.局部内部类

5.匿名内部类

三、API

1.Object

1.1概念:

1.2常用方法:

1.3equals重写解剖

2.String

2.1特点:

2.2创建String对象的方式:

2.3API常用方法

3.StringBuilder/StringBuffer

3.1特点:

3.2 常见方法

4.扩展

4.1==和equals的区别

4.2StringBuilder和StringBuffer的区别

四、正则表达式

1.2 String提供了支持正则表达式的方法

五、包装类

1与基本类型的对应关系

 2 Number

2.1创建对象:

常见方法

3 自动装箱和自动拆箱

概述:

4 BigDecimal

1.创建对象

 2.常用方法

3.舍入方式解析

六、IO

1.File文件类

1.1概述:

1.2常用方法

 2.字节流读取

2.1 InputStream抽象类

2.2 FileInputStream子类

4.3 BufferedInputStream子类

3.字符流读取

3.1 Reader抽象类

3.2 FileReader子类

3.3 BufferedReader子类

4.字节流写出

4.1 OutputStream抽象类

6.2 FileOutputStream 子类

6.3 BufferedOutputstream 子类

5.字符流写出

5.1 Writer 抽象类

5.2 FileWriter 子类

5.3 BufferedWriter子类

6.总结:IO的继承结构

七、序列化与反序列化

1.序列化:

2.反序列化

3.反序列化如何成功?

八、泛型

九、Collection

十、List接口

1.List接口的特点

2.List集合方法总结


一、接口

1.接口的特点:

  1. 接口使用interface关键字
  2. 类要实现接口要使用implements关键字实现
  3. 接口中全部都是抽象方法和静态常量
  4. 接口和抽象类一样不能实例化
  5. 接口没有构造方法,实现类使用的super()是父类的无参构造   如果父类没有指定实现类的父类,super()代表的才是Object的无参构造
  6. 接口不是类

2.接口与类的复杂关系

1.类与类的关系

只是存在继承关系 ,而且是单继承

2.类与接口的关系

类可以实现接口,也可以多实现

3.接口与接口之间的关系

接口与接口之间是继承关系,但是可以多继承  也可以单继承

4.接口与抽象类的区别

  1. 接口是一种用interface定义的类型抽象类是用class定义的类型
  2. 接口都是抽象方法而抽象类不是,抽象类可以有方法或者抽象类
  3. 接口都是静态常量,抽象类可以写成员变量
  4. 接口中没有构造方法,抽象类中有构造方法  但是抽象类和接口都不能实例化
  5. 接口可以多继承,抽象类只能单继承

二、内部类

1.内部类

1.内部类的创建方式

class A { //外部类
    String name;
    private int age;
    public void find(){
        System.out.println("Outer ... find()");
        
        B b = new B();
        
        b.delete();
    }
    class B{  //内部类
        int sum = 10;
        public void delete(){
            System.out.println("Innter  --- delete()");

            System.out.println(name);
            System.out.println(age);
            
        }
    }
}

2.内部类的特点

  1. 内部类可以直接调用外部类的资源,包括私成员
  2. 外部类想要调用内部类的资源,需要去创建内部对象才可以去调用
  3. A.B a = new A().new B();
    System.out.println(a.sum);
    a.delete();

    通过 外部类.内部类  变量名 = new 外部类.new 内部类 来创建内部类的对象,并调用内部类的资源

2.成员内部类(被private修饰)

public void getInner(){
        System.out.println("这是外部类");
        B b = new B();
        b.getoo();
    }
    private class B{  //内部类
        public void getoo(){
            System.out.println("这是内部类");
        }
    }

成员内部类特点:

  1. 成员内部类被private修饰以后,无法被外界直接创建创建对象使用
  2. 所以可以创建外部类对象,通过外部类对象间接访问内部类的资源

3.静态内部类(被static修饰)

静态内部类特点:

  1. 静态资源访问时不需要创建对象,可以通过类名直接访问
  2. 访问静态类中的静态资源可以通过". . . "链式加载的方式访问
TestCs.Inner inner = new TestCs.Inner();
inner.show();

TestCs.Inner.show2();

//测试方法重写
class TestCs{
    public void show1(){}

    static class Inner{
        public void show(){}
        public static void show2(){
            System.out.println("静态内部类的静态方法");
        }
    }
}

4.局部内部类

class TestCs{
    public void eat(){
        class TestSs{
            String string = "12";
            public void cces(){
                System.out.println("我是局部内部类");
            }
        }
        TestSs testcs = new TestSs();
        testcs.cces();
    }
}

5.匿名内部类

public class Test {
    public static void main(String[] args) {
        //接口
        Inter1 inter1 = new Inter1() {
            @Override
            public void save() {
                System.out.println("aas");
            }

            @Override
            public void get() {
                System.out.println("123");
            }
        };
        inter1.get();
        //抽象
        Inter2 inter2 = new Inter2() {
            @Override
            public void drink() {
                System.out.println("123");
            }
        };
        //普通
        new Inter3().powerUp();
    }

}
//测试方法重载
/**
 * 1.重载方法名+参数列表确实具体调用哪个方法
 * **/
interface Inter1{
    //定义接口中的抽象方法
    void save();
    void get();
}
//创建抽象类
abstract class Inter2{
    public void play(){
        System.out.println("Inter2...play()");
    }
    abstract public void drink();
}
//创建普通类
class Inter3{
    public void study(){
        System.out.println("什么都阻挡不了我想学习赚钱的决心");
    }
    public void powerUp(){
        System.out.println("我们会越来越强的!");
    }
}

总结:





匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用

三、API

API的概念:

API是一些预先定义函数,目的是用来提供应用程序与开发人员基于某软件或者某硬件得以访问一组例程的能力,并且无需访问源码或无需理解内部工作机制细节

API是一种通用功能集,有时公司会将API作为其公共开放系统,也就是公司制定自己的系统接口标准,当需要进行系统整合,自定义和程序应用等操作时,公司所有成员都可以通过该接口标准调用源代码.

1.Object

1.1概念:

Object类是所有Java类的祖先,也就是说我们所说的”顶级父类”
它存在于java.lang.Object,这个包不需要我们手动导包
需要注意的是:每个类都使用Object作为超类.所有对象(包括数组)都实现这个类的方法.
在不明确给出超类的情况下,Java会自动把Object类作为要定义类的超类.


1.2常用方法:

toString()本方法用于返回对应对象的字符串表示
hashCode()本方法用于返回对应对象的哈希码值

equals()

本方法用于指示其他某个对象是否与当前对象”相等”

toString重写前:返回的是哈希码值

toString重写后:返回的对象的类型+属性+属性值

hashCode重写前:返回对应对象的int类型的哈希码值

hashCode重写后:重写后根据属性生成

equals重写前:比较两个对象的地址值

equals重写后:比较两个对象的类型+所有属性与属性值 

1.3equals重写解剖

     第一步比较:   if (this == o) return true; 

      this:调用本类的对象s1   o代表的是传入的对象s2

                ==   比较的是地址值

                如果地址值相同就返回true

     第二步比较:if (o == null || getClass() != o.getClass()) return false;

        o == null  判断是否为空  如果为空则为true

        getClass()  获取对象类class  

        如果有一个条件满足则就返回false

  第三步:Student student = (Student) o;

传入对象的类型是Object,父类无法使用子类的特有属性,所以需要强转
        多态:

        向上造型:把子类型看作是父类型,花木兰替父从军 Animal a = new Cat();
        向下造型:之前转成父类型的子类对象,又想使用子类自己的特有功能了,可以向下转型
                 写法:Cat c = (Cat) a; 比如花木兰打仗完了想用自己的特有功能:化妆*/
        向下造型:把父类型Object转回子类型Student


第四步返回:

return age == student.age &&
        anInt == student.anInt &&
        Objects.equals(name, student.name);

基本类型用:==   作比较

引用类型还是用: equals比较

Objects中的equals 是比较俩个值是否相同

2.String

2.1特点:

String是一个封装char[]数组的对象,字符串不可变从被final修饰,是常量

2.2创建String对象的方式:

//第一种
String s1 = new String("我的神");
//第二种
String s3 = "我的神";
//第三种
char[] chars = new char[]{'我','的','神'};
String s5 = new String(chars);

注意:如果是第一次使用字符串,java会在字符串堆中常量池创建一个对象

        在次相同的内容时,会直接访问堆中常量池中存在的对象

public class TestString {
    public static void main(String[] args) {
        String s1 = new String("我的神");
        String s2 = new String("我的神");
        String s3 = "我的神";
        String s4 = "我的"+"神";
        char[] chars = new char[]{'我','的','神'};
        String s5 = new String(chars);
        System.out.println(s1 == s2);//flase   比较的地址值
        System.out.println(s1.equals(s2));//true   String内部重写了equals
        System.out.println(s1 == s3);//false    地址值  与   内容
        System.out.println(s1.equals(s3));//true
        System.out.println(s3.equals(s1));//true
        System.out.println(s3 == s4);//true    String有预编译的能力
        System.out.println(s5.equals(s4));//true
        System.out.println(s5.equals(s1));//true
    }
}

2.3API常用方法

int hashCode() 返回此字符串的哈希码。
boolean equals(Object anObject) 将此字符串与指定的对象比较,比较的是重写后的串的具体内容
String toString() 返回此对象本身(它已经是一个字符串!)。

int length() 返回此字符串的长度。
String toUpperCase() 所有字符都转换为大写。
String toLowerCase() 所有字符都转换为小写
boolean startsWith(String prefix) 测试此字符串是否以指定的元素开头。
boolean endsWith(String suffix) 测试此字符串是否以指定的字符串结束。

char charAt(int index) 返回指定索引/下标处的 char 值/字符
int indexOf(String str) 返回指定字符在此字符串中第一次出现处的索引。
int lastIndexOf(String str) 返回指定字符在此字符串中最后一次出现处的索引。
String concat(String str) 将指定字符串连接/拼接到此字符串的结尾,注意:不会改变原串
String[] split(String regex) 根据给定元素来分隔此字符串。

String trim() 返回去除首尾空格的字符串
byte[] getBytes() 把字符串存储到一个新的 byte 数组中
String substring(int beginIndex) 返回一个新子串,从指定下标处开始,包含指定下标
String substring(int beginIndex, int endIndex) 返回一个新子串,从执定下标开始,到结束下标为止,但不包含结束下标
static String valueOf(int i) 把int转成String

String s6 = "asdujioadoasdasdliasdjossdklasjsdklasj121";
        System.out.println(s6.length());//获取字符串的长度
        System.out.println(s6.toLowerCase());//把字符转换为小写
        System.out.println(s6.toUpperCase());//把字符转换成大写
        System.out.println(s6.startsWith("a"));//判断此字符串是否指定的元素开头
        System.out.println(s6.endsWith("a"));//判断此字符串是否指定元素结尾
        System.out.println(s6.charAt(1));//返回对应位置的值
        System.out.println(s6.indexOf("a"));//返回指定字符在此字符串中第一次出现处的索引
        System.out.println(s6.lastIndexOf("a"));//返回指定字符在此字符串中最后一次出现的索引
        System.out.println(s6.concat("ashhj"));//将指定字符串连接/拼接到此字符串的结尾,注意:不会改变原串
        String[] as = s6.split("a");//根据给定元素来分隔此字符串
        System.out.println(Arrays.toString(as));
        System.out.println(s6.trim());//返回去除首尾的字符串
        byte[] bytes = s6.getBytes();//把字符串储存到一个新的byte数组中
        System.out.println(Arrays.toString(bytes));
        System.out.println(s6.substring(10));//返回一个新子串,从指定下标处开始,包含指定下标
        System.out.println(s6.substring(10,15));//返回一个新子串,从指定下标处开始,包含指定下标到第二个指定下标结束,不包含它
        System.out.println(String.valueOf("12123"));//将int转换成String

3.StringBuilder/StringBuffer

3.1特点:

  1. 封装了char[]数组
  2. 是可变的字符序列
  3. 提供了一组可以对字符内容修改的方法
  4. 常用append()来代替字符串做字符串连接”+”
  5. 内部字符数组默认初始容量是16:super(str.length() + 16);
  6. 如果大于16会尝试将扩容,新数组大小原来的变成2倍+2,容量如果还不够,直接扩充到需要的容量大小。int newCapacity = value.length * 2 + 2;
  7. StringBuffer 1.0出道线程安全,StringBuilder1.5出道线程不安全
     

3.2 常见方法

append()

public class TestString02 {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        StringBuffer stringBuffer = new StringBuffer();

        for (int i = 0; i < 10000; i++) {
            stringBuffer.append("1212312313");
        }

        for (int i = 0; i < 10000; i++) {
            stringBuilder.append("1212312313");
        }
    }
}

4.扩展

4.1==和equals的区别

1.当使用= =比较时,如果相比较的两个变量是引用类型,那么比较的是两者的物理地值(内存地址),如果相比较的两个变量都是数值类型,那么比较的是具体数值是否相等。
2.当使用equals()方法进行比较时,比较的结果实际上取决于equals()方法的具体实现
众所周知,任何类都继承自Object类,因此所有的类均具有Object类的特性,比如String、integer等,他们在自己的类中重写了equals()方法,此时他们进行的是数值的比较,而在Object类的默认实现中,equals()方法的底层是通过==来实现的。


4.2StringBuilder和StringBuffer的区别

1.在线程安全上 :
–StringBuffer是旧版本就提供的,线程安全的。@since JDK1.0
–StringBuilder是jdk1.5后产生,线程不安全的。@since 1.5
2. 在执行效率上,StringBuilder > StringBuffer > String
3.源码体现:本质上都是在调用父类抽象类AbstractStringBuilder来干活,只不过Buffer把代码加了同步关键字,使得程序可以保证线程安全问题。


四、正则表达式

概述:正确的字符串格式规则。
常用来判断用户输入的内容是否符合格式的要求,注意是严格区分大小写的。

在这里插入图片描述

1.2 String提供了支持正则表达式的方法

Matches(正则) : 当前字符串能否匹配正则表达式
replaceAll(正则,子串) : 替换子串
split(正则) : 拆分字符串

五、包装类

把基本类型进行包装,提供更加完善的功能。
基本类型是没有任何功能的,只是一个变量,记录值,而包装类可以有更加丰富的功能

1与基本类型的对应关系

在这里插入图片描述

 2 Number

数字包装类的抽象父类。
提供了各种获取值的方式。

2.1创建对象:

Integer integer1 = new Integer("123123");
Integer integer2 = Integer.valueOf("123123");
Integer integer3 = Integer.parseInt("123123");

注意:Integer类中包含256个Integer缓存对象,范围是 -128~127
使用valueOf()时,如果指定范围内的值,直接访问缓存对象不新建;如果指定范围外的值,直接新建对象。

Integer有一个高效的效果,数据在:(-128~127) * 在此范围内,相同的数据只会存一次,后续再存都是使用之前存过的数据

高效需要满足的条件

Integer有一个高效的效果,但是必须满足3个条件:
        * 1.是Integer类型
        * 2.使用valueOf()的创建方式
        * 3.数据在-128~127的范围内
        * 满足以上条件,相同的数据只会存一次,后续再使用都是以前存过的数据*/
 

常见方法

static int parseInt(String s) 将字符串参数作为有符号的十进制整数进行解析

使用parseInt()将String类型的数据转为int类型 

使用parseDouble()将String类型的数据转为double类型

3 自动装箱和自动拆箱

概述:

自动装箱:把 基本类型 包装成对应的 包装类型 的过程

Integer a = 5;//a是引用类型,引用了包装对象的地址。
编译器会完成对象的自动装箱:Integer a = Integer.valueOf(5);

自动拆箱:从包装类型的值,自动变成 基本类型的值

int i = a;//a现在是包装类型,没法给变量赋值,需要把5取出来。
编译器会完成自动拆箱:int i = a.intValue();

自动装箱:编译器会自动把基本类型int 5,包装成包装类型Integer
        * 然后交给i3来保存,自动装箱底层发生的代码Integer.valueOf(5);
        * valueOf()的方向: int --> Integer
自动拆箱:编译器会自动把包装类型的i1拆掉"箱子",变回基本类型数据127
        * 然后交给i4来保存,自动拆箱底层发生的代码:i1.intValue();
        * intValue()的方向:Integer -> int
 

4 BigDecimal

BigDecimal:常用来解决精确的浮点数运算不精确的问题

1.创建对象

方式一 :
BigDecimal(double val)
将double转换为BigDecimal,后者是double的二进制浮点值十进制表示形式,有坑!
方式二 :
BigDecimal(String val)
将String类型字符串的形式转换为BigDecimal

 2.常用方法

Add(BigDecimal bd) : 做加法运算
Subtract(BigDecimal bd) : 做减法运算
Multiply(BigDecimal bd) : 做乘法运算
Divide(BigDecimal bd) : 做除法运算,除不尽时会抛异常
Divide(BigDecimal bd,保留位数,舍入方式) : 除不尽时使用
setScale(保留位数,舍入方式) : 同上
pow(int n) : 求数据的几次幂

3.舍入方式解析


ROUND_HALF_UP 四舍五入,五入 如:4.4结果是4; 4.5结果是5
ROUND_HALF_DOWN 五舍六入,五不入 如:4.5结果是4; 4.6结果是5
ROUND_HALF_EVEN 公平舍入(银行常用)
比如:在5和6之间,靠近5就舍弃成5,靠近6就进位成6,如果是5.5,就找偶数,变成6
ROUND_UP 直接进位,不算0.1还是0.9,都进位
ROUND_DOWN 直接舍弃,不算0.1还是0.9,都舍弃
ROUND_CEILING(天花板) 向上取整,取实际值的大值
朝正无穷方向round 如果为正数,行为和round_up一样,如果为负数,行为和round_down一样
ROUND_FLOOR(地板) 向下取整,取实际值的小值
朝负无穷方向round 如果为正数,行为和round_down一样,如果为负数,行为和round_up一样
 

六、IO

1.File文件类

1.1概述:

封装一个硬盘路径字符串,对这个路径可以执行一次操作

可以封装        文件的路径、文件夹路径、不存在的路径

1.2常用方法

在这里插入图片描述

 2.字节流读取

字节流是由字节组成的,字符流是由字符组成的.
Java里字符由两个字节组成.字节流是基本流,主要用在处理二进制数据。
所以字节流是比较常用的,可以可以处理多种不同种类的文件,比如文本文档/音频/视频等等

2.1 InputStream抽象类

常用方法:
abstract int read() 从输入流中读取数据的下一个字节
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
int read(byte[] b, int off, int len) 将输入流中最多 len 个数据字节读入 byte 数组,off表示存时的偏移量
void close() 关闭此输入流并释放与该流关联的所有系统资源

2.2 FileInputStream子类

创建对象
FileInputStream(File file)—直接传文件对象
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定FileInputStream(String pathname)—传路径
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定

4.3 BufferedInputStream子类

BufferedInputStream 为另一个输入流添加一些功能,在创建BufferedInputStream 时,会创建一个内部缓冲区数组(默认8k大小)。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。

创建对象
BufferedInputStream(InputStream in)
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。

3.字符流读取

常用于处理纯文本数据,读写容易出现乱码的现象,在读写时,最好指定编码集为UTF-8

3.1 Reader抽象类

用于读取字符流的抽象类。

常用方法:
int read() 读取单个字符
int read(char[] cbuf) 将字符读入数组
abstract int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分
int read(CharBuffer target) 试图将字符读入指定的字符缓冲区
abstract void close() 关闭该流并释放与之关联的所有资源

3.2 FileReader子类

用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。

创建对象
FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader
FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader

3.3 BufferedReader子类

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

创建对象
BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流

4.字节流写出

4.1 OutputStream抽象类

此抽象类是表示输出字节流的所有类的超类.输出流接受输出字节并将这些字节发送到某个接收器.

常用方法:
Void close() 关闭此输出流并释放与此流相关的所有系统资源
Void flush() 刷新此输出流并强制写出所有缓冲的输出字节
Void write(byte[ ] b) 将b.length个字节从指定的byte数组写入此输出流
Void write(byte[ ] b,int off ,int len) 将指定byte数组中从偏移量off开始的len个字节写入输出流
Abstract void write(int b) 将指定的字节写入此输出流

6.2 FileOutputStream 子类

直接插在文件上,直接写出文件数据

构造方法(创建对象):
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的文件输出流
FileOutStream(File file)
创建一个向指定File对象表示的文件中写入数据的文件输出流
FileOutStream(File file,boolean append)—如果第二个参数为true,表示追加,不覆盖
创建一个向指定File对象表示的文件中写入数据的文件输出流,后面的参数是指是否覆盖原文件内容

6.3 BufferedOutputstream 子类

该类实现缓冲的输出流,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必每次针对字节写出调用底层系统

构造方法(创建对象):
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,用以将数据写入指定的底层输出流

5.字符流写出

5.1 Writer 抽象类

写入字符流的抽象类

常用方法:
Abstract void close() 关闭此流,但要先刷新它
Void write(char[ ] cbuf) 写入字符数组
Void write(int c) 写入单个字符
Void write(String str) 写入字符串
Void write(String str,int off,int len) 写入字符串的某一部分
Abstract void write(char[] cbuf,int off,int len)写入字符数组的某一部分

5.2 FileWriter 子类

用来写入字符文件的便捷类,此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的.如果需要自己自定义这些值,可以先在FileOutputStream上构造一个OutputStreamWriter.

构造方法(创建对象):
FileWriter(String filename)
根据给定的文件名构造一个FileWriter对象
FileWriter(String filename,boolean append)
根据给定的文件名以及指示是否附加写入数据的boolean值来构造FileWriter

5.3 BufferedWriter子类

将文本写入字符输出流,缓冲各个字符,从而提供单个字符,数组和字符串的高效写入.可以指定缓冲区的大小,或者接受默认的大小,在大多数情况下,默认值就足够大了

构造方法(创建对象):
BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流

6.总结:IO的继承结构

1.主流分类

按照方向进行分类:输入流 输出流(相对于程序而言,从程序写数据到文件中是输出)
按照传输类型进行分类:字节流 字符流
组合: 字节输入流 字节输出流 字符输入流 字符输出流
2.学习方法:在抽象父类中学习通用的方法,在子类中学习如何创建对象
3.字节输入流:

InputStream 抽象类,不能new,可以作为超类,学习其所提供的共性方法
--FileInputStream 子类,操作文件的字节输入流,普通类
--BufferedInputStream 子类,缓冲字节输入流,普通类


4.字符输入流

Reader 抽象类,不能new,可以作为超类,学习其所提供的共性方法
--FileReader,子类,操作文件的字符输入流,普通类
--BufferedReader,子类,缓冲字符输入流,普通类


5.字节输出流:

OutputStream 抽象类,不能new,可以作为超类,学习其所提供的共性方法
--FileOutputStream 子类,操作文件的字节输出流,普通类
--BufferedOutputStream 子类,缓冲字节输出流,普通类


6.字符输出流

Writer 抽象类,不能new,可以作为超类,学习其所提供的共性方法
--FileWriter,子类,操作文件的字符输出流,普通类
--BufferedWriter,子类,缓冲字符输出流,普通类
 

七、序列化与反序列化

1.序列化:

  1. 将程序中对象的各项信息,序列化输出到文件中保存
  2. 使用的流是ObjectOutputStream
  3. 使用的方法是out.writeObject(目标对象);
  4. 注意:如果一个类的对象想要被序列化,那么这个类必须实现Serializable接口
//序列化
    private static void mt1() {
        ObjectOutputStream oos = null;

        try {
            oos = new ObjectOutputStream(new FileOutputStream("D:\\ready\\aa.txt"));
            Student student = new Student("我的",19);
            oos.writeObject(student);
            System.out.println("恭喜你,序列化成功!!!");
        } catch (IOException e) {
            System.out.println("恭喜你,序列化失败!!!");
            e.printStackTrace();
        }finally {
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

2.反序列化

  1. 将之前输出到文件中的数据,读取回程序中,并把读到的数据重新恢复成对象
  2. 使用的流是ObjectinputStream
  3. 使用的方法是in。readObject();
  4. 注意:反序列化指定的文件路径,必须和序列化输出的文件路径一样
  5. 注意:自定义需要重写toString()方法财库查看对象的属性和属性值,否则打印的是地址值
  6. 注意:一次序列化操作对应一次反序列化,或者UID必须保持一致,如果不一致,会报错
//反序列化
    private static void mt2() {
        ObjectInputStream ois = null;

        try {
            ois = new ObjectInputStream(new FileInputStream("D:\\ready\\aa.txt"));
            Object object = ois.readObject();
            System.out.println(object);
            System.out.println("恭喜你,序列化成功!!!");
        } catch (Exception e) {
            System.out.println("恭喜你,序列化失败!!!");
            e.printStackTrace();
        }finally {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

3.反序列化如何成功?

核心:Student类中的UID,与反序列化流中的UID保持一致

第一种:一次序列化对应一次反序列化【推荐】

第二种:一次序列化后不修改Student中的内容,然后反序列化

将Student中的UID写成固定值

注意:反序列化流持有的UID与Student类中的UID不一致时,反序列化会失败

比如:使用自动生成的UID,先序列化,然后修改Student,再来反序列化,这样就会失败

八、泛型

  1. 泛型,不是指一种具体的类型,而是说,这里有个类型需要设置。那么后续具体需要色湖之成什么类型,就得看具体的业务
  2. 泛型通常与集合一起使用,用来限制集合中存入的元素类型,泛型具体设置成什么类型,那么这个集合只能存这个类型的元素
  3. 泛型可以把报错的时机提前,用于在编译期检查集合的元素类型,只要不是泛型设置的类型,就报错,通不过编译
  4. 泛型只在编译时生效,编译通过以后,说明符合语法规范,泛型就会被抛弃,编译生成字节码文件中没有泛型
  5. 泛型的类型必须使用引用类型、
  6. 泛型方法:如果想要在方法上使用泛型,必须俩处同时出现

第一:一个是方法的参数列表中的参数类型

第二:方法返回值类型前的泛型类型,表示这是一个泛型方法

九、Collection

Collection是一个集合层次中的跟接口

public class TestCollection {
    public static void main(String[] args) {
        Collection<Integer> c = new ArrayList<>();

        c.add(123);
        c.add(123);
        c.add(213);
        c.add(12345);

        System.out.println(c);//打印集合,查看集合中的元素
        System.out.println(c.hashCode());//获取集合对象的哈希码值
        System.out.println(c.toString());//打印集合的具体元素
        System.out.println(c.equals(123));//false,集合对象c与值200是否相等
        System.out.println(c.contains(123));//判断是否包含指定的元素200
        System.out.println(c.isEmpty());//false,判断元素是否为空
        System.out.println(c.remove(100));//移除集合中指定的元素
        System.out.println(c.size());//返回集合的元素个数
        Object[] objects = c.toArray();//将指定的集合转为数组Object[]
        System.out.println(Arrays.toString(objects));

        //测试多个集合间的操作
        Collection<Integer> c2 = new ArrayList<>();

        c2.add(123);
        c2.add(4556);
        c2.add(14);
        System.out.println(c2);

        c.addAll(c2);//将c2集合放到c1集合当中
        System.out.println(c.containsAll(c2));//判断当前集合c是否包含指定集合c2中的所以的元素
        System.out.println(c.removeAll(c2));//删除c集合中属于c2集合的所以元素
        System.out.println(c.retainAll(c2));//取c集合与c2集合的交集(公共元素)

        Iterator<Integer> iterator = c.iterator();
        while(iterator.hasNext()){
            Integer next = iterator.next();
            System.out.println(next);
        }


    }
}

十、List接口

1.List接口的特点

  1. List集合是有下标
  2. List集合是有顺序的
  3. List集合可以存放重复的数据

2.List集合方法总结

public class TestList {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("我的世界");
        list.add("永远的神");
        list.add("相信自己");
        list.add("一定可以");

        System.out.println(list);

        System.out.println(list.contains("相信自己"));//判断集合是否包含指定元素
        System.out.println(list.equals("相信自己"));//集合对象与string数据不等
        System.out.println(list.isEmpty());//判断集合是否为空
        System.out.println(list.remove("相信自己"));//移除集合中指定的元素
        System.out.println(list.size());//获取集合中元素的个数
        System.out.println(Arrays.toString(list.toArray()));//将集合转成数组

        list.add("小蝴蝶");//追加到最后面
        list.add(1,"亿万富翁");//在指定的索引处添加元素
        System.out.println(list.indexOf("我的世界"));//获取指定元素第一次出现的索引
        System.out.println(list.lastIndexOf("我的世界"));//获取指定元素最后一次出现的索引
        System.out.println(list.remove(5));//根据索引删除元素,并将被删除的元素返回
        System.out.println(list.get(3));//获取指定索引处的元素
        System.out.println(list.set(3,"蝎子精"));//修改指定索引处元素的值


        //测试集合间的操作
        List<String> list1 = new ArrayList<>();
        list1.add("12");
        list1.add("13");
        list1.add("14");
        list1.add("15");

        System.out.println(list1);
        System.out.println(list.addAll(list1));//将list1集合添加到list集合中
        System.out.println(list.addAll(1,list1));//将list1集合元素添加到指定位置
        System.out.println(list.containsAll(list1));//判断list集合中是否包含list2集合中的所有元素
        System.out.println(list.removeAll(list1));//移除list集合中属于list2集合中的所有元素
        //遍历方法1
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        //遍历方法2
        for (String s : list) {
            System.out.println(s);
        }
        //遍历方法3
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }
        //遍历方法4
        ListIterator<String> stringListIterator = list.listIterator();
        while(stringListIterator.hasNext()){
            System.out.println(stringListIterator.next());
        }
        //反向
        ListIterator<String> stringListIterator1 = list.listIterator();
        while (stringListIterator1.hasNext()){//判断是否有下一个元素可迭代
            System.out.println(stringListIterator1.next());
            if (!stringListIterator1.hasNext()){//直到迭代器没有下一个元素可迭代--到最后了
                System.out.println("开始逆序:");
                while (stringListIterator1.hasPrevious()){//判断是否有上一个元素可迭代
                    System.out.println(stringListIterator1.previous());
                }
                break;//终止循环,不然会一直从头到尾,再从尾到头迭代
            }
        }
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值