java--------------

0基础学it,月薪过万,就来黑马程序员

黑马程序员,成就it黑马

java

java特点:Java的特点和优点_语言 (sohu.com)

最大的优点就是与平台无关,在Windows9x、WindowsNT、Solaris、Linux、MacOS以及其它平台上,都可以使用相同的代码。“一次编写,到处运行”的特点【高可移植性】,使其在互联网上广泛采用。

java和C++对比

即java的新特性

1) 提供了对内存的自动管理,程序员无需在程序中进行分配、释放内存,那些可怕的内存分配错误不会再打扰你了;

2) 去除了C++语言中的令人费解、容易出错的“指针”,用其它方法来进行弥补;

3) 避免了赋值语句(如a=3)与逻辑运算语句(如a==3)的混淆;

4) 取消了多重继承这一复杂的设施。

解释型语言效率低,速度慢;编译型语言效率高,速度快。

java是解释性语言,C++是编译型语言,

go是编译型语言,【go静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。】

和go的对比,以及对go的了解

go是09年公开发布,其创始人之一创造了Unix系统和C语言,还有UTF-8编码

Go的编码是Utf-8

服务器编程分布式系统数据库代理器网络编程内存数据库云平台微服务区块链等这些领域或者行业的应用和实施。

图标

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BmzFEckv-1647592964110)(java.assets/image-20210830162458019.png)]

套接字

进行网络传输的一套API,本质上是可以在网络使用的流

## 网络基本概念:

7层,就是说,只要你在网上传数据,都是要经过这7 层的

物理层

数据链路层:转换信号

网络层

传输层-udp、tcp

会话层,应用层,表示层

这些都是后三层的协议

http,ftp,pop3,SMTP,这两个是在用在邮件

重点是传输层(要学的)

IP地址:在网络中标记主机,ipv4,

已经有ipv6地址了。

当万物互联的时候,ipv6也不够用了

所以推出了ipv9了,

平时上网,使用的ip地址都是动态分配的,就是说,这次上网是这个网址,下次可以就变了。提高IP地址的利用率

一般来说都是用动态ip,都是公用的

静态ip费用太贵

ip地址标记主机,端口号标记程序,

端口:计算机与外界交互的媒介,

端口号:0-65535

一部分被计算机内部占用,

80端口号,是被浏览器占用,

一般来说0-1024被计算机内部占用,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vq8Z7qpD-1647592964111)(java.assetsimage-20210617182402040.png)]

记忆IP地址比较麻烦,所以出现了域名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cy0owmOK-1647592964112)(java.assetsimage-20210617182431490.png)]

域名倒着看,一级:com

二级baidu

有时候会加。cn(也是一级域名)

去掉cn,然后一级域名表示分类

com表示商业网站,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64ap7PWO-1647592964112)(java.assetsimage-20210617182710996.png)]

二级是公司具体的名字,三级就是表示其分类了,百度新闻

dns解析服务器:j将域名和ip地址对应,当你输入域名的时候,会先到dns服务器中先解析成对应的ip,然后顺着ip找这个地址,每个网络中都会有一个dns解析服务器,默认存在每一个电脑中都会有一个微型的dns,全球的互联网中会有一个公告的dns

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZZcadebD-1647592964112)(java.assetsimage-20210617183311028.png)]

当你输入一个域名,然后你的电脑dns会对其进行解析,然后如果没有找到,那么就会向上请求,到你电脑所链接的局域网中寻找,如果还是没有找到,继续向上请求寻找,一直没找到,。最后可能是该网址你写错了

,当找到后,就会告诉你下级的dns,然后没有该地址的dns就会刷新一下保存该dns,每一个dns都会存一下,刷新一下,下次寻找,就不用往上找了,因为本机存的有了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88AiKWDK-1647592964113)(java.assetsimage-20210617183730544.png)]

反射

在web中会用得到

udp

基于流的,不建立连接,不可靠,

依靠网络进行传输,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cqXOTTpc-1647592964113)(java.assetsimage-20210617192258230.png)]

视频聊天

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Su9ydBEc-1647592964113)(java.assetsimage-20210617193902208.png)]

idea添加异常,用alt+enter

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h66tqrPf-1647592964113)(java.assetsimage-20210617193929782.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3oDFKXr-1647592964114)(java.assetsimage-20210617193951549.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cuQXzBes-1647592964114)(java.assetsimage-20210617195936177.png)]

接收端

package com.itheima;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPReceiverDemo {
    public static void main(String[] args) throws IOException {
        //创建套接字对象,绑定端口号
        DatagramSocket ds = new DatagramSocket(8090);
        //准备数据包,
        DatagramPacket dp =new DatagramPacket(new byte[1024],1024);
        //接收数据
        ds.receive(dp);
        //关流,这个是非常耗费流量的,所以用完一定要关
        ds.close();
        //将数据从数据包中解析出来,我们不需要全都,所以需要获取一下长度
        //获取数据包的底层数组
        byte[] bs = dp.getData();
        //获取数据的实际大小
        int len=dp.getLength();

        System.out.println(new String(bs,0,len));
		//获取发送过来的主机的地址
        System.out.println(dp.getAddress());
         //获取发送过来的主机的端口号
        System.out.println(dp.getPort());
    }

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ooDT24ua-1647592964114)(java.assetsimage-20210617200623005.png)]

发送端

package com.itheima;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class UDPSenderDmo
{
    public static void main(String[] args) throws IOException {
        //创建一个udp套接字对象
        DatagramSocket ds = new DatagramSocket();
        //准备数据包,并将数据放入数据包中


        DatagramPacket dp = new DatagramPacket("hello~~~".getBytes(),"hello~~~".getBytes().length,
                new InetSocketAddress("localhost",8090));
        //发送数据包
        ds.send(dp);
        //关流
        ds.close();
    }

}

先运行接收端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qswOtekj-1647592964115)(java.assetsimage-20210617200722845.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bu2Gb2AX-1647592964115)(java.assets/image-20210618131833609.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-98GsFWOY-1647592964115)(java.assets/image-20210618132352898.png)]

udp分发送端和接收端

tcp分客户端和服务器端

tcp三次握手

客户端发起连接,

服务器端接收连接

客户端再次发起连接

tcp不进行封包,没有数据包的概念,所以只能用流来传输数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHq3Ca8U-1647592964116)(java.assets/image-20210618191008704.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Me4n6q7C-1647592964116)(java.assets/image-20210831152107683.png)]

IDE就是编译器

继承extend

黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

1.1 继承概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RePAowQP-1647592964116)(java.assets/image-20210716133150883.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Em2fG9DX-1647592964116)(java.assets/image-20210716133321039.png)]

继承就是提取出多个类中共有的属性和方法,然后提取,作为父类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eGfyHXBb-1647592964117)(java.assets/image-20210716133402701.png)]

面向对象三大特征:封装、继承、多态。

面向对象的三大基本特征,五大基本原则 - 风之之 - 博客园 (cnblogs.com)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JjSUkAia-1647592964117)(java.assets/image-20210716133437512.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hj98dE5E-1647592964117)(java.assets/image-20210716133644804.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cr1krdB6-1647592964118)(java.assets/image-20210716133635231.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ghtThCgh-1647592964118)(java.assets/image-20210716133728936.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dE5uCvYD-1647592964118)(java.assets/image-20210804003259641.png)]

重写父类方法,需要加override

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wPcyZmSV-1647592964118)(java.assets/image-20210804003412604.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RzUbjCmI-1647592964119)(java.assets/image-20210804003423094.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UvDIvjaG-1647592964119)(java.assets/image-20210716133743670.png)]

1.2 继承的好处和弊端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0BtQuqJm-1647592964119)(java.assets/image-20210716133945350.png)]

【继承的好处】:

  • 使子类具有父类的属性和方法,还可以在子类中重新定义,追加方法和属性。

  • 子类在访问成员方法和变量的时候,都是一样的顺序,先找子类,再找父类

  • 子类重写父类方法的时候,需要加@Override

  • 子类根本不可能重写父类的私有方法。

  • 子类不可以多继承,但是可以多层继承。

  • 比如儿子继承父亲,父亲继承爷爷,即儿子拥有爷爷属性

1.3 继承中【变量】的访问特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OoZgcKkK-1647592964119)(java.assets/image-20210716134318759.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-06EUKikH-1647592964120)(java.assets/image-20210716134418973.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0T3VuGaS-1647592964120)(java.assets/image-20210716134513863.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l239gMoA-1647592964120)(java.assets/image-20210716134555464.png)]

换个写法:

package demo;

class FU{
    //年龄
    public int age=40;
}
class ZI extends FU{
    public int height = 175;
    public int age=20;
    public void show(){
        int age=30;
        System.out.println(age);
        System.out.println(height);
    }
}

public class DEMO {
    public static void main(String[] args) {
        ZI Z=new ZI();
        Z.show();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n9xbftE6-1647592964120)(java.assets/image-20210804103130421.png)]

1.4 super

this代表的本类的成员变量的访问

super可以访问父类中的成员变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UEb1Rz8X-1647592964121)(java.assets/image-20210716135036570.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAc4KOzG-1647592964121)(java.assets/image-20210804103900423.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bg8tgcZK-1647592964121)(java.assets/image-20210804103910976.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aezjgjtH-1647592964121)(java.assets/image-20210716135302619.png)]

1.5 继承中构造方法的访问特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IFRC1ay1-1647592964122)(java.assets/image-20210716140125577.png)]

父类:

package com.itheima_04;

public class Fu {

    /*
    public Fu() {
        System.out.println("Fu中无参构造方法被调用");
    }
    */

    public Fu() {}

    public Fu(int age) {
        System.out.println("Fu中带参构造方法被调用");
    }

}

子类:

package com.itheima_04;

public class Zi extends Fu {

    public Zi() {
//        super();  这个是默认会有的
//        super(20);
        System.out.println("Zi中无参构造方法被调用");
    }

    public Zi(int age) {
//        super();
//        super(20);
        System.out.println("Zi中带参构造方法被调用");
    }

}

测试类

package com.itheima_04;
/*
    测试类
*/
public class Demo {
    public static void main(String[] args) {
        //创建对象
        Zi z = new Zi();
        Zi z2 = new Zi(20);
    }
}

1.6 继承中【成员方法】的访问特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-21uFTJ0Q-1647592964122)(java.assets/image-20210716140536275.png)]

父类:

package com.itheima_05;

public class Fu {

    public void show() {
        System.out.println("Fu中show()方法被调用");
    }

}

子类:

package com.itheima_05;

public class Zi extends Fu {

    public void method() {
        System.out.println("Zi中method()方法被调用");
    }

    public void show() {
        super.show();
        System.out.println("Zi中show()方法被调用");
    }
}

测试类:

package com.itheima_05;

/*
    测试类
 */
public class Demo {
    public static void main(String[] args) {
        //创建对象,调用方法
        Zi z = new Zi();
        z.method();
        z.show();
        //报错
//        z.test();
    }
}

1.7 super内存图

链接:内存过程讲解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTTXYO96-1647592964122)(java.assets/image-20210716140800699.png)]

1.8 方法重写(添加@Override)

package com.itheima_06;

/*
    手机类
 */

public class Phone {
    public void call(String name) {
        System.out.println("给" + name + "打电话");
    }
}

重写父类方法的时候,很容易把方法写错,为了帮助大家检验这个东西,添加@Override,这个说明,下面的内容是重写的父类,这个注解,可以帮助我们了解方法声明的准确性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KM8Uayts-1647592964122)(java.assets/image-20210716141916000.png)]

package com.itheima_06;

/*
    新手机
 */
public class NewPhone extends Phone {

    /*
    public void call(String name) {
        System.out.println("开启视频功能");
//        System.out.println("给" + name + "打电话");
        super.call(name);
    }
    */

    @Override
    public void call(String name) {
        System.out.println("开启视频功能");
//        System.out.println("给" + name + "打电话");
        super.call(name);
    }

}



package com.itheima_06;
/*
    测试类
 */
public class PhoneDemo {
    public static void main(String[] args) {
        //创建对象,调用方法
        Phone p = new Phone();
        p.call("林青霞");
        System.out.println("--------");

        NewPhone np = new NewPhone();
        np.call("林青霞");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OJZQEOzs-1647592964123)(java.assets/image-20210716142019150.png)]

1.9 方法重写的注意事项

子类根本不可能重写父类的私有方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S2FCdQuD-1647592964123)(java.assets/image-20210716142649184.png)]

也就是说,如果父类是“默认”,那么子类就得用public

package com.itheima_07;

public class Fu {

    private void show() {
        System.out.println("Fu中show()方法被调用");
    }

    /*
    public void method() {
        System.out.println("Fu中method()方法被调用");
    }
    */

    void method() {
        System.out.println("Fu中method()方法被调用");
    }
}


package com.itheima_07;

public class Zi extends Fu {

    /*
    @Override
    private void show() {
        System.out.println("Zi中show()方法被调用");
    }
    */

    /*
    @Override
    public void method() {
        System.out.println("Zi中method()方法被调用");
    }
    */

    @Override
    public void method() {
        System.out.println("Zi中method()方法被调用");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BO8rxAov-1647592964123)(java.assets/image-20210716142738544.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iIE3pGuA-1647592964124)(java.assets/image-20210716142812340.png)]

1.10 Java中【继承的注意事项】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l8f8mjc7-1647592964124)(java.assets/image-20210716142925606.png)]

但是可以多层继承。

比如儿子继承父亲,父亲继承爷爷,即儿子拥有爷爷属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rv8m9JU5-1647592964124)(java.assets/image-20210716143059711.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9KlT1ZGN-1647592964124)(java.assets/image-20210716143133359.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wtGBCo4z-1647592964125)(java.assets/image-20210716143141981.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fSgK7tNe-1647592964125)(java.assets/image-20210716143156744.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hgLIgX2g-1647592964125)(java.assets/image-20210716143213776.png)]

extend继承,创建一个类的子类

implement是实现,可以实现多个接口

extends与implements的不同

extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,也可以调用父类初始化 this.parent()。而且会覆盖父类定义的变量或者函数。这样的好处是:架构师定义好接口(这里的接口是指父类的成员函数和变量),让工程师实现就可以了。整个项目开发效率和开发成本大大降低。

JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了。实现父类,子类不可以覆盖父类的方法或者变量。即使子类定义与父类相同的变量或者函数,也会被父类取代掉。

格式:

class A extends B implements C,D,E

一个类通过关键字implements声明自己使用一个或者多个接口。

在类的声明中,通过关键字extends来创建一个类的子类。

class 子类名 extends 父类名 implenments 接口名

{…

}

若同时用到 extends 和 implements 的时候,extends 必须放在 implements 关键字之前。

说的很好:

Java 继承 | 菜鸟教程 (runoob.com)

java只能单继承,不能多继承

1、为什么使用继承

从已有的类派生出新的类,称为继承。

在不同的类中也可能会有共同的特征和动作,可以把这些共同的特征和动作放在一个类中,让其它类共享

因此可以定义一个通用类,然后将其扩展为其它多个特定类,这些特定类继承通用类中的特征和动作。

继承是 Java 中实现软件重用的重要手段,避免重复,易于维护,易于理解

super 关键字

super 表示使用它的类的父类。super 可用于:

  • 调用父类的构造方法;
  • 调用父类的方法(子类覆盖了父类的方法时);
  • 访问父类的数据域(可以这样用但没有必要这样用)。

调用父类的构造方法语法:

super();  

或   

super(参数列表);

注意:super 语句必须是子类构造方法的第一条语句。不能在子类中使用父类构造方法名来调用父类构造方法。 父类的构造方法不被子类继承。调用父类的构造方法的唯一途径是使用 super 关键字,如果子类中没显式调用,则编译器自动将 super(); 作为子类构造方法的第一条语句。这会形成一个构造方法链。

静态方法中不能使用 super 关键字。

调用父类的方法语法:

super.方法名(参数列表);

如果是继承的方法,是没有必要使用 super 来调用,直接即可调用。但如果子类覆盖或重写了父类的方法,则只有使用 super 才能在子类中调用父类中的被重写的方法。

implements关键字

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

this 和super的区别

this 代表本类对应的引用

Super 代表父亲存储空间的标识(可以理解为父亲引用)可以操作父亲 的成员

使用方法:

A:调用成员变量

·this.成员变量 调用本类的成员变量

·super.成员变量 调用父类的成员变量

B:调用构造方法

·this(…) 调用本类的成员变量

·Super(…)调用父类的成员变量

C:调用成员方法

·this.成员方法 调用本类的成员方法

·super.成员方法 调用父类的成员方法

继承:

public class zi extends fu{

//重写父类方法

}

多态

1.1 多态概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iWkzDyWs-1647592964125)(java.assets/image-20210722130822704.png)]

package com.itheima_01;

public class Animal {

    public void eat() {
        System.out.println("动物吃东西");
    }
}


package com.itheima_01;

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}


package com.itheima_01;
/*
    多态:
        同一个对象,在不同时刻表现出来的不同形态

    举例:猫
        我们可以说猫是猫:猫 cat = new 猫();
        我们也可以说猫是动物:动物 animal = new 猫();
        这里猫在不同的时刻表现出来了不同的形态,(猫既是猫,也是动物)这就是多态

    多态的前提和体现
        有继承/实现关系
        有方法重写
        有父类引用指向子类对象
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //有父类引用指向子类对象
        Animal a = new Cat();	//这就体现出多态了
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QKra4Zrj-1647592964126)(java.assets/image-20210804111331187.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7FJS8QQV-1647592964126)(java.assets/image-20210804111342875.png)]

1.2 多态中成员访问特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eIp7fr5Q-1647592964126)(java.assets/image-20210722131945402.png)]

package com.itheima_02;

public class Animal {

    public int age = 40;

    public void eat() {
        System.out.println("动物吃东西");
    }

}



package com.itheima_02;

public class Cat extends Animal {

    public int age = 20;
    public int weight = 10;

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void playGame() {
        System.out.println("猫捉迷藏");
    }

}



package com.itheima_02;

/*
    测试类
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //有父类引用指向子类对象
        Animal a = new Cat();

        System.out.println(a.age);
//        System.out.println(a.weight);

        a.eat();
//        a.playGame();	这个不能调用,会报错

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LMkVlpVG-1647592964126)(java.assets/image-20210804112209386.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDnglFQz-1647592964127)(java.assets/image-20210804112241153.png)]

这就引出了,接下来的多态的好处和弊端了

1.3 多态的好处和弊端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNTB6dHV-1647592964127)(java.assets/image-20210722132828917.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCF1zH0A-1647592964127)(java.assets/image-20210722135404586.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gGAReyyT-1647592964127)(java.assets/image-20210722135515202.png)]

其实也是多继承

package com.itheima_03;

public class Animal {

    public void eat() {
        System.out.println("动物吃东西");
    }

}



package com.itheima_03;

/*
    测试类
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //创建动物操作类的对象,调用方法
        AnimalOperator ao = new AnimalOperator();
        Cat c = new Cat();
        ao.useAnimal(c);


        Dog d = new Dog();
        ao.useAnimal(d);


        Pig p = new Pig();
        ao.useAnimal(p);

    }
}



package com.itheima_03;

/*
    动物操作类
 */
public class AnimalOperator {

    /*
    public void useAnimal(Cat c) { //Cat c = new Cat();
        c.eat();
    }

    public void useAnimal(Dog d) { //Dog d = new Dog();
        d.eat();
    }
    */

    public void useAnimal(Animal a) {
        //Animal a = new Cat();
        //Animal a = new Dog();

        a.eat();
//        a.lookDoor();
    }


}



package com.itheima_03;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

}



package com.itheima_03;

public class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    public void lookDoor() {
        System.out.println("狗看门");
    }

}



package com.itheima_03;

public class Pig extends Animal {

    @Override
    public void eat() {
        System.out.println("猪吃白菜");
    }
}

1.4 多态中的转型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tONNzJpo-1647592964128)(java.assets/image-20210722141145777.png)]

这个可以帮助我们实现使用子类的特有功能

多态中访问成员方法,编译看左边,访问看右边

package com.itheima_04;

public class Animal {

    public void eat() {
        System.out.println("动物吃东西");
    }

}



package com.itheima_04;

/*
    向上转型
        从子到父
        父类引用指向子类对象

    向下转型
        从父到子
        父类引用转为子类对象
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //多态
        Animal a = new Cat(); //向上转型
        a.eat();
//        a.playGame();

        /*
        //创建Cat类的对象
        Cat c = new Cat();
        c.eat();
        c.playGame();
        */

        //向下转型
        Cat c = (Cat)a;
        c.eat();
        c.playGame();
    }
}



package com.itheima_04;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void playGame() {
        System.out.println("猫捉迷藏");
    }

}

1.5 多态转型内存图解

多态转型内存图解(对于这种堆和栈,建议看视频)

案例:多态版猫和狗

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-clFLLpxX-1647592964128)(java.assets/image-20210722141946509.png)]

package com.itheima_06;

public class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat() {
        System.out.println("动物吃东西");
    }
}




package com.itheima_06;

/*
    测试类
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //创建猫类对象进行测试
        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();

        a = new Cat("加菲", 5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();

    }
}



package com.itheima_06;

public class Cat extends Animal {

    public Cat() {
    }

    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}



package com.itheima_06;

public class Dog extends Animal {

    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6WqxaY1T-1647592964128)(java.assets/image-20210724110410955.png)]

抽象类

1.1 抽象类概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tUv5EthB-1647592964129)(java.assets/image-20210727154032011.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tzO28Hqr-1647592964129)(java.assets/image-20210727154707886.png)]

package com.itheima_01;

public abstract class Animal {

    /*
    public void eat() {
        System.out.println("吃东西");
    }
    */

    public abstract void eat();
//没有方法体
}



package com.itheima_01;

/*
    测试类
 */
public class AnimalDemo {

    public static void main(String[] args) {
        /*
        Animal a = new Animal();	//抽象类不能创建对象
        a.eat();
        */
    }
    

}

1.2 抽象类的特点

抽象类参照多态的形式创建对象,既然是多态,那么就要有继承,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-11BqCGXA-1647592964129)(java.assets/image-20210727155345431.png)]

package com.itheima_02;
/*
    抽象类
 */
public abstract class Animal {
    //抽象方法
    public abstract void eat();

    public void sleep() {
        System.out.println("睡觉");
    }

}



package com.itheima_02;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}



package com.itheima_02;

public abstract class Dog extends Animal {

}



package com.itheima_02;

/*
    测试类
 */
public class AnimalDemo {
    public static void main(String[] args) {
//        Animal a = new Animal();
        Animal a = new Cat();
        a.eat();
        a.sleep();
    }
}

1.3 抽象类的成员特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c0QsVyE8-1647592964130)(java.assets/image-20210727160853553.png)]

package com.itheima_03;

/*
    抽象类
 */
public abstract class Animal {

    private int age = 20;
    private final String city = "北京";

    public Animal() {}

    public Animal(int age) {
        this.age = age;
    }


    public void show() {
        age = 40;
        System.out.println(age);
//        city = "上海";
        System.out.println(city);
    }

    public abstract void eat();

}



package com.itheima_03;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}



package com.itheima_03;

/*
    测试类
 */
public class AnimalDemo {
    public static void main(String[] args) {
        Animal a = new Cat();
        a.eat();
        a.show();
    }
}

案例:抽象类版猫和狗

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hs166prS-1647592964130)(java.assets/image-20210727161251567.png)]

package com.itheima_04;

public abstract class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public abstract void eat();
}



package com.itheima_04;
/*
    测试类
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //创建对象,按照多态的方式
        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName()+","+a.getAge());
        a.eat();
        System.out.println("--------");

        a = new Cat("加菲",5);
        System.out.println(a.getName()+","+a.getAge());
        a.eat();4
    }
}



package com.itheima_04;

public class Cat extends Animal {

    public Cat() {
    }

    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}


package com.itheima_04;

public class Dog extends Animal {

    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

接口

1.1 接口概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BAigApLf-1647592964130)(java.assets/image-20210720092156512.png)]

接口是一种公共的规范,只要符合该规范,都可以使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PdDxsU7K-1647592964130)(java.assets/image-20210720092357218.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eONtRdOa-1647592964131)(java.assets/image-20210720092411056.png)]

类实现接口,而不是继承接口,所以用implement,而不是extend

接口的实例化,采用多态的形式

抽象类可以不重写

1.2 接口的特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1kd4D53A-1647592964131)(java.assets/image-20210720094131488.png)]

接口是一个抽象的内容,主要是对行为进行抽象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVmBEzbN-1647592964131)(java.assets/image-20210720095431375.png)]

定义一个接口

package com.itheima_01;
/*
    定义了一个接口
 */
public interface Jumpping {

    //定义了一个抽象方法
    public abstract void jump();

}

实现接口

package com.itheima_01;
//类实现接口
public class Cat implements Jumpping {

    @Override
    public void jump() {
        System.out.println("猫可以跳高了");
    }
}

这个是不想重写jupping中的方法,那么就要继续用abstract关键字,然后这个类就变成了抽象类,抽闲类在实现接口的时候,可以不重写方法,但是其子类在继承的时候,还是要重写接口中的方法

package com.itheima_01;

public abstract class Dog implements Jumpping {
        //如果实现类不想重写jupping中的方法,那么就使用abstract关键字,那么这个类就变成了抽象类,抽象类在实现接口的时候,可以不重写方法,但是其子类在继承的时候,还是要重写接口中的方法
}

测试类,就是用多态的方式,进行实例化,然后

package com.itheima_01;

/*
    测试类
 */
public class JumppingDemo {
    public static void main(String[] args) {
//        Jumpping j = new Jumpping();  //接口不能这样被实例化

        Jumpping j = new Cat(); //采用多态的方式进行实例化,使用他的实现类对象,进行实例化
        j.jump();

    }
}

1.3 接口的成员特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MaUxGL7i-1647592964131)(java.assets/image-20210727164858726.png)]

接口里面没有成员变量,默认是常量,因为成员变量被final修饰,所以只有常量

接口中的变量是常量

//接口里面不能有构造方法,因为接口主要是对行为进行抽象

所有的类都直接或者间接继承Object类,如果说一个类没有父类,那么object类就是其父类

如果说一个类有父类,那么 这个类就间接的继承Object类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1K7C2hZP-1647592964132)(java.assets/image-20210727164430458.png)]

因为Object就只有这一个构造方法,所以说,所有的构造方法,默认访问父类的都是无参构造,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E7QKvzHJ-1647592964132)(java.assets/image-20210727164659177.png)]

案例:接口版猫和狗

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tql1djM4-1647592964132)(java.assets/image-20210727165120664.png)]

1.4 类和接口的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAufEwyG-1647592964133)(java.assets/image-20210728001429795.png)]

1.5 抽象类和接口的区别

黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

抽象类和接口的区别_dd_Mr的博客-CSDN博客

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KXMPAEhF-1647592964133)(java.assets/image-20210728221955650.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-azUpKBLL-1647592964133)(java.assets/image-20210728222058063.png)]

当添加报警器后,但不是所有门都有报警器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rc9NU9qK-1647592964133)(java.assets/image-20210728222151212.png)]

所以说,将接口和抽象类结合起来

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5SEasdif-1647592964134)(java.assets/image-20210728223539120.png)]

案例:运动员和教练

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RJbc22BU-1647592964134)(java.assets/image-20210728231211680.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RlyDYvwD-1647592964134)(java.assets/image-20210728231430878.png)]

这个案例用了9个文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VBf7C1qu-1647592964134)(java.assets/image-20210729004138643.png)]

1 形参和返回值【参数传递】

1.1 类名作为形参和返回值

基本数据类型作为形参和返回值就不讨论了,

主要讨论的是引用类型作为形参和返回值,类,抽象类,接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I3GQUhXj-1647592964135)(java.assets/image-20210729005910150.png)]

1、类名作为方法的形参

方法的形参是类名,其实需要的是该类的对象

实际传递的是该对象的【地址值】

2、类名作为方法的返回值

方法的返回值是类名,其实返回的是该类的对象

实际传递的,也是该对象的【地址值】

package itheima;

class Cat{
    public void eat(){
        System.out.println("猫吃鱼");
    }
}
class CatOperator{
    public void useCat(Cat c){   //Cat c = new Cat()?
        c.eat();
    }
    public Cat getCat(){
        Cat c=new Cat();
        return c;
    }
}

public class CatDemo {
    public static void main(String[] args) {
        //创建操作类对象,并调用方法
        CatOperator co=new CatOperator();
        Cat c=new Cat();
        co.useCat(c);
        Cat c2= co.getCat();    //new Cat()
        c2.eat();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fWy4TWd9-1647592964135)(java.assets/image-20210729145729480.png)]

1.2 抽象类名作为形参和返回值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4xWg1qvO-1647592964135)(java.assets/image-20210729010022093.png)]

package itheima2;
//抽象动物类,并创建吃的方法
abstract class Animal{
    public abstract void eat();
}

class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

class AnimalOperator{
    public void useAnimal(Animal a){
        //Animal a = new Cat()? 抽象类名作为参数时,需要的是子类作为实参数
        a.eat();
    }

    public Animal getAnimal(){
        Animal a=new Cat();
        return a;
    }
}

public class AnimalDemo {
    public static void main(String[] args) {
        AnimalOperator ao=new AnimalOperator();
        Animal a=new Cat();     //编译看左边,执行看右边
        ao.useAnimal(a);

        Animal a2 = ao.getAnimal(); //new Cat();    这个返回的是个猫对象,如果想要调用吃,那么就得调用猫
        a2.eat();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s1J7xbZY-1647592964136)(java.assets/image-20210729151711939.png)]

1.3 接口名作为形参和返回值(理解)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQZoNndT-1647592964136)(java.assets/image-20210729162313148.png)]

package itheima3;

//接口中的成员方法,只能是抽样方法
//public interface Jumpping{
interface Jumpping{
//    public abstract void jump();  //默认修饰符
    void jump();
}

class JumppingOperator{
    public void useJumpping(Jumpping j){
        //形参是个接口,然后这个接口的j可以调用方法jump(),说明这个j是个对象,而接口是不能直接实例化的
        //所以这是按照多态的形式创建的对象,要的是该接口的实现类对象 ,从而有了下面的cat类,用来实现这个接口
        j.jump();
    }
    public Jumpping getJumpping(){
        Jumpping j=new Cat();       //多态的形式创建对象
        return j;   //接口不能实例化,所以,返回的是实现类的 对象
    }
}

class Cat implements Jumpping{
    @Override
    public void jump() {
        System.out.println("猫可以跳高");
    }
}

//接口作为形参和返回值
public class JumppingDemo {
    public static void main(String[] args) {
        //创建操作类对象,并调用方法
        JumppingOperator jo=new JumppingOperator();
        Jumpping j=new Cat();       //多态的形式创建对象
        jo.useJumpping(j);
        Jumpping j2=jo.getJumpping();   //new Cat()
        j2.jump();
    }
}

2 内部类

2.1 内部类的基本使用(理解)

生活中案例:比如笔记本和cpu,笔记本看作是外部类,cpu看作是内部类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sniyx4Dp-1647592964136)(java.assets/image-20210730111627708.png)]

/*
    内部类访问特点: 内部类可以直接访问外部类的成员,包括私有
    外部类要访问内部类的成员,必须创建对象
*/
public class Outer {
    private int num=10;
    //内部类
    public class Inner{
        public void show(){
            System.out.println(num);    //内部类可以直接访问外部类的成员,包括私有
            System.out.println("内部类的函数");
        }
    }
    public void method(){
        Inner i=new Inner();
        i.show();           // 外部类要访问内部类的成员,必须创建对象
    }


package itheima4;
/*
    内部类访问特点: 内部类可以直接访问外部类的成员,包括私有
    外部类要访问内部类的成员,必须创建对象
*/
public class Outer {
    private int num=10;
    //内部类
    public class Inner{
        public void show(){
            System.out.println(num);    //内部类可以直接访问外部类的成员,包括私有
            System.out.println("内部类的函数");
        }
    }
    public void method(){
        Inner i=new Inner();
        i.show();           // 外部类要访问内部类的成员,必须创建对象
    }
    public static void main(String[] args) {
        Outer o =new Outer();
        o.method(); //通过外部类调用内部类的函数
                     //可不可以直接通过内部类调用内部类的函数呢,可以
        Outer myOuter = new Outer();
        Outer.Inner myInner = myOuter.new Inner();
        System.out.println("-------");
        myInner.show();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yqg6fFWm-1647592964136)(java.assets/image-20210730111513881.png)]

2.2 成员内部类(理解)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iZFx72oW-1647592964137)(java.assets/image-20210730221003757.png)]

成员内部类:是类的成员

局部内部类:就是指在类的方法里面的类

class Outer{
    private int num=10;
    public class Inner{            //成员内部类
        public void show(){
            System.out.println(num);
        }
    }
}

public class InnerDemo {
    public static void main(String[] args) {
        Outer.Inner inner=new Outer().new Inner();
        inner.show();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2rbEbnQd-1647592964137)(java.assets/image-20210730220013800.png)]

上面的例子,一般来说,是不常见的,因为定义内部类的目的就是为了不让外面轻而易举的看到,所以一般用private修饰内部类,而不用public

一般采用,创建一个外部类方法,然后该方法会创建一个内部类对象,然后用这个方法来调用内部类对象

package itheima6;

class Outer{
    int a=10;
    private class Inner{
        public void show(){
            System.out.println(a);
        }
    }
    public void method(){
        Inner inner=new Inner();
        inner.show();
    }
}
public class InnerDemo {
    public static void main(String[] args) {
        Outer outer=new Outer();
        outer.method();
    }
}

2.3 局部内部类(理解)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3saLiUCZ-1647592964137)(java.assets/image-20210730221259810.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gRWOveUA-1647592964138)(java.assets/image-20210730222115391.png)]

package itheima6;

class Outer{
    private int num = 20;
    public void method(){
        int num2=20;
        class Inner{
            public void show(){
                System.out.println(num);
                System.out.println(num2);
            }
        }
        Inner i=new Inner();
        i.show();
    }
}

public class OuterDemo {
    public static void main(String[] args) {
        Outer outer=new Outer();
        outer.method();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MrqkssJt-1647592964139)(java.assets/image-20210730222341956.png)]

2.4 匿名内部类(应用)

我们的类是class开头,但是匿名内部类是new开头的

这个匿名内部类可以是一个类或者是一个接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hi2m9ccm-1647592964139)(java.assets/image-20210731094434707.png)]

匿名内部类,本质是匿名的对象,这个类是抽象类居多

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OKdG4gwL-1647592964139)(java.assets/image-20210731090324824.png)]

示例1

package itheima9;

interface Inter{
    void show();
}

class Outer {
    public void method(){
        //这就是一个匿名内部类
        new Inter(){
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        };
    }
}
public class OuterDemo{
    public static void main(String[] args) {
        Outer o=new Outer();
        o.method();
    }
}

不会调用show方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XrDeomNU-1647592964139)(java.assets/image-20210731095734229.png)]

package itheima9;

interface Inter{
    void show();
}

class Outer {
    public void method(){
        //这就是一个匿名内部类
        //这样写仅仅是一个对象
//        new Inter(){
//            @Override
//            public void show() {
//                System.out.println("匿名内部类");
//            }
//        };
//  这样写就是对象调用了方法
      /*  new Inter(){
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        }.show();
        //调用两次,就再复制一份
		new Inter(){
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        }.show();
      */
    //多次调用的方式    
         Inter i= new Inter(){       //按照多态的形式,这个对象Inter一定是接口的实现类对象或者或者是类的子类对象
            @Override
           public void show() {
                System.out.println("匿名内部类");
            }
        };
        i.show();   //编译看左边,执行看右边
        i.show();   //多次调用
        
    }
}
public class OuterDemo{
    public static void main(String[] args) {
        Outer o=new Outer();
        o.method();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oZEJ2a6X-1647592964140)(java.assets/image-20210731100137352.png)]

2.5 匿名内部类在开发中的使用(应用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUWJKBgT-1647592964140)(java.assets/image-20210731101139957.png)]

如果一个方法的参数是接口名,那么他实际要的是接口的实现类对象,

可以省去一些不需要的对象

package itheima8;
/**
 * 跳高接口
 */
interface Jumpping{
    void jump();
}

/**
 * 实现接口
 */
class Cat implements Jumpping{
    @Override
    public void jump() {
        System.out.println("猫可以跳高");
    }
}

class Dog implements Jumpping{
    @Override
    public void jump() {
        System.out.println("狗可以跳高");
    }
}

/**
 * 接口操作类,里面有一个方法,方法的参数是接口名
 */
class JumppingOperator{
    public void method(Jumpping j){
        j.jump();
    }
}

public class JumppingDemo {
    public static void main(String[] args) {
        //需求:创建接口操作类对象,调用method方法
        JumppingOperator jo=new JumppingOperator();
        Jumpping j=new Cat();
        jo.method(j);

        Jumpping j2=new Dog();
        jo.method(j2);
        //。。。
        //如果有很多动物,那么就很冗余,匿名内部类可以很好的解决
        
        System.out.println("---------");

        //匿名内部类,可以简化操作
        jo.method(  //这个方法要的是一个接口,其实是接口的实现类对象,
                    //而匿名内部类的格式他的本质就是实现类对象,并且是实现了该接口的对象,

          new Jumpping() {      //这个就和猫完全没有关系,把猫删了也可,
              //所以,采用后面这两种形式,不需要多写两个类出来,

            @Override
            public void jump() {
                System.out.println("猫可以跳高");
            }
        }
        );
        jo.method(new Jumpping() {
            @Override
            public void jump() {
                System.out.println("狗可以跳高");
            }
        });
    }
}


package InnerClassDemo;

/**
 * 匿名内部类的本质,就是对接口或者类的实现或者继承
 * 1,定义一个接口,【对于接口来说,如果要实现接口,那么就要实现接口中的所有方法,这样对吗?】
 * 2,实现接口,创建小狗,小猫,实现接口中的方法
 * 3,接口操作类,创建,里面的参数是接口名
 */
interface Jumpping{
    public void jump();
}
class Dog implements Jumpping{
    @Override
    public void jump(){
        System.out.println("小狗跳");
    }
}
class Cat implements Jumpping{
    @Override
    public void jump() {
        System.out.println("小猫跳");
    }
}
class JumppingOperator{
    public void Operator(Jumpping j){
            j.jump();
    }
}
public class AnonymousInnerClass {
    public static void main(String[] args) {
        JumppingOperator jo = new JumppingOperator();
        //如果想要调用接口操作类的方法,就需要一个接口Jumpping的实现类,所以需要传递一个对象
        //但是这个对象可以用匿名内部类来实现,这样就不用频繁创建,狗,猫等对象
        Jumpping j=new Cat();
        Jumpping j1=new Dog();

        jo.Operator(j);
        jo.Operator(j1);

        /**
         * 匿名内部类本质上是对接口或者类的实现或者继承
         */

        jo.Operator(new Jumpping() {
            @Override
            public void jump() {
                System.out.println("匿名内部类之实现狗蹦");
            }
        });

        jo.Operator(new Jumpping() {
            @Override
            public void jump() {
                System.out.println("匿名内部类之实现猫跳");
            }
        });
    }
}

/**
 * 匿名内部类的好处:不用频繁创建类和对象,对于一些需要传值的东西,直接写即可。
 */

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QnsFJbZ-1647592964140)(java.assets/image-20210917180205982.png)]

String

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J8aSKNyM-1647592964141)(java.assets/image-20210626222755435.png)]

package com.itheima_02;
/*
    String构造方法:
        public String():创建一个空白字符串对象,不含有任何内容
        public String(char[] chs):根据字符数组的内容,来创建字符串对象
        public String(byte[] bys):根据字节数组的内容,来创建字符串对象
        String s = “abc”;	直接赋值的方式创建字符串对象,内容就是abc
        推荐使用直接赋值的方式得到字符串对象
 */

public class StringDemo01 {
    public static void main(String[] args) {
        //public String():创建一个空白字符串对象,不含有任何内容
        String s1 = new String();
        System.out.println("s1:" + s1);
//输出:null
        //public String(char[] chs):根据字符数组的内容,来创建字符串对象
        char[] chs = {'a', 'b', 'c'};
        String s2 = new String(chs);
        System.out.println("s2:" + s2);
//输出abc
        //public String(byte[] bys):根据字节数组的内容,来创建字符串对象
        byte[] bys = {97, 98, 99};
        String s3 = new String(bys);
        System.out.println("s3:" + s3);
//输出:979899,猜错了,,,
        //String s = “abc”;	直接赋值的方式创建字符串对象,内容就是abc
        String s4 = "abc";
        System.out.println("s4:" + s4);
//输出:abc
    }
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nx243f7n-1647592964141)(java.assets/image-20210617160433634.png)]

2.1 String概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BP6G4eou-1647592964141)(java.assets/image-20210830170252454.png)]

2.3 string对象的特点:

1, [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oz6i8oVg-1647592964141)(java.assets/image-20210617160654718.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nkJrSFqp-1647592964142)(java.assets/image-20210617160812795.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AAW4Vleh-1647592964142)(java.assets/image-20210617161129210.png)]

当执行结束,main方法就从栈内存消失

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-47plEI1T-1647592964142)(java.assets/image-20210617161211649.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9iHoMfYe-1647592964143)(java.assets/image-20210617161346126.png)]

package com.itheima_02;

/*
    使用 == 做比较:
        基本类型:比较的是数据值是否相同
        引用类型:比较的是地址值是否相同

     public boolean equals?(Object anObject):
        将此字符串与指定对象进行比较。由于我们比较的是字符串对象,所以参数直接传递一个字符串
 */
public class StringDemo02 {
    public static void main(String[] args) {
        //构造方法的方式得到对象
        char[] chs = {'a', 'b', 'c'};
        String s1 = new String(chs);
        String s2 = new String(chs);

        //直接赋值的方式得到对象
        String s3 = "abc";
        String s4 = "abc";

        //比较字符串对象地址是否相同
        System.out.println(s1 == s2);
        System.out.println(s1 == s3);
        System.out.println(s3 == s4);
        System.out.println("--------");

        //比较字符串内容是否相同
        System.out.println(s1.equals(s2));
        System.out.println(s1.equals(s3));
        System.out.println(s3.equals(s4));
    }
}

3 StringBuilder

3.1 StringBuilder概述

可变的字符串容器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-porUqn4d-1647592964143)(java.assets/image-20210617163810431.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fk46L0vF-1647592964143)(java.assets/image-20210617163835070.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uscckZ6l-1647592964143)(java.assets/image-20210617163906138.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sKwi8Uk8-1647592964144)(java.assets/image-20210617164023538.png)]

String和StringBuilder的区别:

  • String:内容是不可变的
  • StringBuilder:内容是可变的

3.2 StringBuilder构造方法:

/*
    StringBuilder构造方法:
        public StringBuilder():创建一个空白可变字符串对象,不含有任何内容
        public StringBuilder(String str):根据字符串的内容,来创建可变字符串对象
 */
public class StringBuilderDemo01 {
    public static void main(String[] args) {
        //public StringBuilder():创建一个空白可变字符串对象,不含有任何内容
        StringBuilder sb = new StringBuilder();
        System.out.println("sb:" + sb);		//空
        System.out.println("sb.length():" + sb.length());	//0

        //public StringBuilder(String str):根据字符串的内容,来创建可变字符串对象
        StringBuilder sb2 = new StringBuilder("hello");
        System.out.println("sb2:" + sb2);	//hello
        System.out.println("sb2.length():" + sb2.length());	//5
    }
}

3.3 StringBuilder 的添加和反转方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GHJupFtF-1647592964144)(java.assets/image-20210618221006345.png)]

/*
    StringBuilder 的添加和反转方法
        public StringBuilder append(任意类型):添加数据,并返回对象本身
        public StringBuilder reverse():返回相反的字符序列
 */
public class StringBuilderDemo02 {
    public static void main(String[] args) {
        StringBuilder sb=new StringBuilder();
        StringBuilder sb2 = sb.append("hello");
        
        System.out.println("sb:"+sb);
        System.out.println("sb2:"+sb2);
        System.out.println(sb==sb2);
        
        //【因为append是添加对象,并返回对象本身,所以就不需要用另一个StringBuilder来接收了,所以下面那个是进阶
        
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YCQC6g9k-1647592964144)(java.assets/image-20210618222017857.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rAUUcXS7-1647592964144)(java.assets/image-20210618222359338.png)]

package com.itheima;

/*
    StringBuilder 的添加和反转方法
        public StringBuilder append(任意类型):添加数据,并返回对象本身
        public StringBuilder reverse():返回相反的字符序列
 */
public class StringBuilderDemo02 {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
//        StringBuilder sb2 = sb.append("hello");
//        System.out.println("sb:"+sb);
//        System.out.println("sb2:"+sb2);
//        System.out.println(sb==sb2);
        sb.append("hello");
        sb.append("world");
        sb.append("100");
        System.out.println("sb:"+sb);   //sb:helloworld100

    }
}


public class StringBuilderDemo01 {
    public static void main(String[] args) {
        //创建对象
        StringBuilder sb = new StringBuilder();
//因为append方法返回的是对象本身,对象就可以调方法,所以,可以一直调用方法,即链式编程
        //链式编程
        sb.append("hello").append("world").append("java").append(100);
        System.out.println("sb:" + sb);

        //public StringBuilder reverse():返回相反的字符序列,直接把内容反转
        sb.reverse();
        System.out.println("sb:" + sb);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KY1dG8Ie-1647592964145)(java.assets/image-20210618223224200.png)]

3.4 StringBuilder和String相互转换

String不能直接使用append或者reserve,所以要把string转换成stringbuilder,然后再把stringbuilder转换成string

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HAo6TYUU-1647696053836)(java.assets/image-20210619175540339.png)]

package com.itheima;

public class StringBuilderDemo03 {
    public static void main(String[] args) {
        //string转换成stringbuilder,通过构造方法实现。
        String s="hello";
        System.out.println(s);
        StringBuilder sb=new StringBuilder(s);
        sb.append("可以添加内容");
        //stringbuilder转换成string,通过tostring方法实现
        sb.toString();
        System.out.println(sb);
    }
}

3.5 案例:拼接字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-txWh4J7w-1647592964145)(java.assets/image-20210619181320281.png)]

/*
    需求:
        定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。
        例如,数组为int[] arr = {1,2,3}; ,执行方法后的输出结果为:[1, 2, 3]
    思路:
        1:定义一个 int 类型的数组,用静态初始化完成数组元素的初始化
        2:定义一个方法,用于把 int 数组中的数据按照指定格式拼接成一个字符串返回。
          返回值类型 String,参数列表 int[] arr
        3:在方法中用 StringBuilder 按照要求进行拼接,并把结果转成 String 返回
        4:调用方法,用一个变量接收结果
        5:输出结果
 */
public class StringBuilderDemo04 {
    public static void main(String[] args) {
        int[] arr={1,2,3};
        String a=arrayToString(arr);
        System.out.println(a);          //[1,2,3]
    }

    //定义一个方法,实现字符串反转。返回值类型 String,参数 String s
    /*
        两个明确:
            返回值类型:String
            参数:String s
     */
    public static String arrayToString(int[] arr){
        //在方法中用 StringBuilder 按照要求进行拼接,并把结果转成 String 返回
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i=0;i

3.6 字符串反转

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-39dtTx5x-1647592964145)(java.assets/image-20210619184605620.png)]

package com.itheima_03;

import java.util.Scanner;

/*
    需求:
        定义一个方法,实现字符串反转。键盘录入一个字符串,调用该方法后,在控制台输出结果
        例如,键盘录入abc,输出结果 cba

    思路:
        1:键盘录入一个字符串,用 Scanner 实现
        2:定义一个方法,实现字符串反转。返回值类型 String,参数 String s
        3:在方法中用StringBuilder实现字符串的反转,并把结果转成String返回
        4:调用方法,用一个变量接收结果
        5:输出结果
 */
public class StringBuilderTest02 {
    public static void main(String[] args) {
        //键盘录入一个字符串,用 Scanner 实现
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入一个字符串:");
        String line = sc.nextLine();

        //调用方法,用一个变量接收结果
        String s = myReverse(line);

        //输出结果
        System.out.println("s:" + s);
    }

    //定义一个方法,实现字符串反转。返回值类型 String,参数 String s
    /*
        两个明确:
            返回值类型:String
            参数:String s
     */
    public static String myReverse(String s) {
        //在方法中用StringBuilder实现字符串的反转,并把结果转成String返回
        //String --- StringBuilder --- reverse() --- String
//        StringBuilder sb = new StringBuilder(s);
//        sb.reverse();
//        String ss = sb.toString();
//        return ss;

       return new StringBuilder(s).reverse().toString();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kvx0YOIG-1647592964146)(java.assets/image-20210619210803741.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTyNbhKU-1647592964146)(java.assets/image-20210619211109275.png)]

如果其他方法被使用到,要求会用帮助文档知道该方法如何使用

数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hdm1sqzQ-1647592964146)(java.assets/image-20210906004542350.png)]

1 数组定义格式

1.1 数组概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xjorreyg-1647592964146)(java.assets/image-20210906004742596.png)]

如果有很多个学员的成绩,那么就用多个变量存储成绩,如果更多的话,那么存储就更加麻烦,所以就引申出了数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQ60o039-1647592964147)(java.assets/image-20210906004923081.png)]

【精简:

一次性声明大量用于存储数据的变量

要存储的数据通常是同类型数据,例如考试成绩】

1.2 什么是数组

数组(array)是一种用于存储多个相同类型数据的存储模型

1.3 数组的定义格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MBaDl8lF-1647592964147)(java.assets/image-20210906005151015.png)]

2 数组初始化之动态初始化

2.1 数组初始化概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wZUaQe2D-1647592964147)(java.assets/image-20210906005347342.png)]

分配【内存空间】和【赋值】

2.2 数组初始化方式

  • 动态初始化
  • 静态初始化

2.3 动态初始化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T7cfycY6-1647592964147)(java.assets/image-20210906005511279.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5qnN28oZ-1647592964148)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105175308020.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMALR3F0-1647592964148)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105175350364.png)]

二维数组【动力节点】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XHmbAe24-1647592964148)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153735328.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZgHJRImc-1647592964148)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153746638.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zY9Ycjrq-1647592964149)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153753643.png)]

二维数组的读和写没有看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pdFHybhJ-1647592964149)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153816702.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwAm5cUd-1647592964149)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153830015.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RuhvdqUo-1647592964149)(java.assets/image-20220106012306863.png)]

array.length   	输出的结果是=3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qmiKIIVR-1647592964150)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153840640.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YVBsWGbT-1647592964150)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153855670.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O60VaiDY-1647592964150)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105153902910.png)]

用数组完成这道题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pL6HF3g0-1647592964151)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105154801943.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IE48UUDs-1647592964151)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105154814511.png)]

406,回顾数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vdkVRatf-1647592964151)(C:Users菠萝啤AppDataRoamingTypora ypora-user-imagesimage-20220105154912762.png)]

Java零基础教程视频(适合Java 0基础,Java初学入门)_哔哩哔哩_bilibili

p410 数组模拟栈数据结构

3 修饰符

3.4 final

状态修饰符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5uOYHQXc-1647592964151)(java.assets/image-20210617165210957.png)]

3.5 final修饰局部变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-San1eZ51-1647592964152)(java.assets/image-20210617165852204.png)]

static(静态)

static是一个修饰符,用于修饰类成员变量,方法,以及编写static代码块

static修饰成员方法,一般叫静态方法,不依赖于任何对象,可以直接访问,但是,对于静态方法,不能访问类的非静态成员变量和非静态成员方法,

因为非静态成员方法或者变量都必须依赖具体对象才能被调用。

但是要注意的是,虽然在

静态方法中不能访问非静态成员方法和非静态成员变量,

但是在非静态成员方法中是可以访问静态成员方法/变量的。

java 中 public,default,protected,private,final、static的区别_dd_Mr的博客-CSDN博客

正则表达式

1,判断功能

案例1

判断录入的手机号是否为13或者18开头

import java.util.Scanner;

public class RegexDm {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入手机好:");
        String s = sc.nextLine();
        String regex = "1[38]\d{9}";//定义手机好规则
        boolean flag = s.matches(regex);//判断功能
        System.out.println("flag:"+flag);
    }
}

手机号是11位的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w82lONXv-1647592964152)(java.assets/image-20220310210343285.png)]

表达式含义:

d表示[0—9]
中括号[]:只有方括号里面指定的字符才参与匹配,也只能匹配单个字符。
{n}表示恰好n次

2,分割功能

import java.util.Scanner;

/**
 * @Author: 从南到北
 * @Date: 2022/03/10/21:00
 */

public class RegexDm1 {
    public static void main(String[] args){
        String age = "18-24";//定义年龄范围
        String regex = "-";
        String[] strArr = age.split(regex);//分割成字符串数组

        int startAge = Integer.parseInt(strArr[0]);
        int endAge = Integer.parseInt(strArr[1]);

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的年龄:");
        int a = sc.nextInt();
        if (a >= startAge && a <= endAge){
            System.out.println("你就是我想找的");
        }else{
            System.out.println("滚");
        }
    }
}

3,替换功能

public class RegexDm {
    public static void main(String[] args){
        String s = "12342jasfkgnas234";
        //把字符串里面的数字替换成*
        String regex = "\d";
        String ss = "*";
        String result = s.replaceAll(regex,ss);
        System.out.println(result);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3SLFKoW-1647592964152)(java.assets/image-20220310211156882.png)]

校验qq号

import java.util.Scanner;

/**
 * @Author: 从南到北
 * @Date: 2022/03/10/21:15
 * 效验QQ号(要求:5-15位数字,0不能开头)
 */
public class RegexDm {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的QQ号码:");
        String qq = sc.nextLine();
        System.out.println("checkQQ:"+checkQQ(qq));
    }

    private static boolean checkQQ(String qq) {
        return qq.matches("[1-9]{1}\d{4,14}");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aiR9X6EK-1647592964152)(java.assets/image-20220310211820189.png)]

参考链接:

https://blog.csdn.net/weixin_43860260/article/details/91417485

MessageFormat类{占位符}

java中自定义使用{0}占位符功能之MessageFormat类

用于组装消息

java中自定义使用{0}占位符功能之MessageFormat类 - JavaShuo

java中{0}占位符的使用 - JavaShuo

MessageFormat类_sinat_41233888的博客-CSDN博客

MessageFormat类的用法 - 知乎 (zhihu.com)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d046Zwn3-1647592964153)(java.assets/image-20220310223557625.png)]

1 集合基础

主要集合概述:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f62C7VaU-1647592964153)(java.assets/image-20220112200914191.png)]

集合继承结构图_Collection 部分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7fNK5gQN-1647592964153)(java.assets/image-20220111233422458.png)]

1.1 集合概述

因为数组的长度是固定的,不能随便改变,所以就出现了集合的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyJ4qgpl-1647592964154)(java.assets/image-20210619211352889.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nl9jLfke-1647592964154)(java.assets/image-20210619211453470.png)]

package com.itheima;

import java.util.ArrayList;

public class ArrayListDemo01 {
    public static void main(String[] args) {
        ArrayList array = new ArrayList<>();
        //public boolean add(E e):将指定的元素追加到此集合的末尾
        System.out.println(array.add("hello")); 
        //因为array.add()一定是成功的,所以就没有必要打印输出这句话
        System.out.println(array);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tcFmUDVr-1647592964154)(java.assets/image-20210619212400788.png)]

package com.itheima;
import java.util.ArrayList;

/*
    ArrayList构造方法:
        public ArrayList():创建一个空的集合对象

    ArrayList添加方法:
        public boolean add(E e):将指定的元素追加到此集合的末尾
        public void add(int index,E element):在此集合中的指定位置插入指定的元素
 */
public class ArrayListDemo01 {
    public static void main(String[] args) {
        //public ArrayList():创建一个空的集合对象
//        ArrayList array = new ArrayList<>();

        ArrayList array = new ArrayList();

        //public boolean add(E e):将指定的元素追加到此集合的末尾
//        System.out.println(array.add("hello"));

        array.add("hello");
        array.add("world");
        array.add("java");

        //public void add(int index,E element):在此集合中的指定位置插入指定的元素
        array.add(1,"javase");  //原来的元素会往后以
//        array.add(3,"javaee");    //直接在后面添加

        //IndexOutOfBoundsException 集合索引越界
//        array.add(4,"javaee");    //报错

        //输出集合
        System.out.println("array:" + array);

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LOX0E4tp-1647592964154)(java.assets/image-20210619213122114.png)]

package com.itheima_01;

import java.util.ArrayList;

/*
    ArrayList常用方法:
        public boolean remove(Object o):删除指定的元素,返回删除是否成功
        public E remove(int index):删除指定索引处的元素,返回被删除的元素
        public E set(int index,E element):修改指定索引处的元素,返回被修改的元素
        public E get(int index):返回指定索引处的元素
        public int size():返回集合中的元素的个数
 */
public class ArrayListDemo02 {
    public static void main(String[] args) {
        //创建集合
        ArrayList array = new ArrayList();

        //添加元素
        array.add("hello");
        array.add("world");
        array.add("java");

        //public boolean remove(Object o):删除指定的元素,返回删除是否成功
//        System.out.println(array.remove("world"));
//        System.out.println(array.remove("javaee"));

        //public E remove(int index):删除指定索引处的元素,返回被删除的元素
//        System.out.println(array.remove(1));

        //IndexOutOfBoundsException
//        System.out.println(array.remove(3));

        //public E set(int index,E element):修改指定索引处的元素,返回被修改的元素
//        System.out.println(array.set(1,"javaee"));

        //IndexOutOfBoundsException
//        System.out.println(array.set(3,"javaee"));

        //public E get(int index):返回指定索引处的元素
//        System.out.println(array.get(0));
//        System.out.println(array.get(1));
//        System.out.println(array.get(2));
        //System.out.println(array.get(3)); //?????? 自己测试

        //public int size():返回集合中的元素的个数
        System.out.println(array.size());

        //输出集合
        System.out.println("array:" + array);
    }
}

集合进阶

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-grSYJsiy-1647592964155)(java.assets/image-20210708162932314.png)]

2.1 List集合概述和特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iRpTweZ1-1647592964155)(java.assets/image-20210708163132461.png)]

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Author: 从南到北
 * @Date: 2022/01/11/15:40
 *  List集合特点
 *    有序:存储和取出的元素顺序一致
 *    可重复:存储的元素可以重复
 */
public class ListDemo01 {
    public static void main(String[] args) {
        //创建集合对象,List是一个接口,而ArrayList是List接口的一个实现类。 
        List list = new ArrayList();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("world");
        System.out.println("输出集合对象:");
        System.out.println(list);
        System.out.println("迭代器的方式遍历:");
        Iterator it = list.iterator();
        while (it.hasNext()) {
            String s = it.next();
            System.out.print(s+",");

        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mo9hb98S-1647592964155)(java.assets/image-20220111154448700.png)]

list是一个接口继承自Collection接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbmQ6dUL-1647592964155)(java.assets/image-20210708164509151.png)]

List是一个接口,而ArrayList是List接口的一个实现类。

Java中List和ArrayList的区别 - 小赵小楠 - 博客园 (cnblogs.com)

2.2 List集合特有方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OYM6Qvy9-1647592964156)(java.assets/image-20210708165010780.png)]

注意:带索引操作的时候,常见的一个错误,索引越界!这个比较常见

2.5 增强for循环和Iterator迭代器

格式:for(ElementType element: arrayName){};

案例:

List intList = new ArrayList();
for (Integer i: intList) {
    System.out.print(i);
}

总结:

相对于for(;;)而言 增强for循环有两个好处:

1.写起来简单

2.遍历集合、容器简单

Java Iterator(迭代器)_dd_Mr的博客-CSDN博客

Java增强for循环_dd_Mr的博客-CSDN博客

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZQjTCx0N-1647592964156)(java.assets/image-20210815153052721.png)]

3 Set

3.1 Set集合概述和特点

黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K1TPHWnr-1647592964156)(java.assets/image-20210823153517500.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9y1iQysM-1647592964157)(java.assets/image-20210823150502207.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WJQwnMaY-1647592964157)(java.assets/image-20210823150423951.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1CrQJkrZ-1647592964157)(java.assets/image-20210823153422553.png)]

3.2 哈希值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AU7dSCYa-1647592964157)(java.assets/image-20210823160139917.png)]

字符串string重写了hashcode()方法

package com.itheima_02;

/*
    哈希值:
        是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

    Object类中有一个方法可以获取对象的哈希值
        public int hashCode():返回对象的哈希码值
 */
public class HashDemo {
    public static void main(String[] args) {
        //创建学生对象
        Student s1 = new Student("林青霞",30);

        //同一个对象多次调用hashCode()方法返回的哈希值是相同的
        System.out.println(s1.hashCode()); //1060830840
        System.out.println(s1.hashCode()); //1060830840
        System.out.println("--------");

        Student s2 = new Student("林青霞",30);

        //默认情况下,不同对象的哈希值是不相同的
        //通过方法重写,可以实现不同对象的哈希值是相同的
        System.out.println(s2.hashCode()); //2137211482
        System.out.println("--------");

        System.out.println("hello".hashCode()); //99162322
        System.out.println("world".hashCode()); //113318802
        System.out.println("java".hashCode()); //3254818

        System.out.println("world".hashCode()); //113318802
        System.out.println("--------");

        System.out.println("重地".hashCode()); //1179395
        System.out.println("通话".hashCode()); //1179395


    }
}



package itheima11;


public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    // 通过方法重写,可以实现不同对象的哈希值相同。没有下面这个方法的重写,那么就不相同
    /*
    @Override
    public int hashCode() {
        return 0;
    }
     */
    
}

3.3 HashSet集合概述和特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A1WBv88l-1647592964158)(java.assets/image-20210823183158498.png)]

package com.itheima_03;

import java.util.HashSet;

/*
    HashSet集合特点
        1:底层数据结构是哈希表
        2:对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
        3:没有带索引的方法,所以不能使用普通for循环遍历
        4:由于是Set集合,所以是不包含重复元素的集合
 */
public class HashSetDemo01 {
    public static void main(String[] args) {
        //创建集合对象
        HashSet hs = new HashSet();

        //添加元素
        hs.add("hello");
        hs.add("world");
        hs.add("java");

        hs.add("world");

        //遍历
        for(String s : hs) {
            System.out.println(s);
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6sJb3R8n-1647592964158)(java.assets/image-20210823183247299.png)]

3.4 HashSet集合保证元素唯一性源码分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sv5WGJtx-1647592964158)(java.assets/image-20210823184220498.png)]

3.5 常见数据结构之哈希表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KI5ElF1h-1647592964159)(java.assets/image-20210823184823486.png)]

动力字节:

哈希表、哈希函数,了解即可

哈希表:数组和单向链表的结合体

06 案例:HashSet集合存储学生对象并遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uLtqFKTt-1647592964159)(java.assets/image-20210823190233431.png)]

package itheima11;
import java.util.Objects;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}


package itheima11;

import java.util.HashSet;

public class HashSetDemo02 {
    public static void main(String[] args) {
        //创建HashSet集合对象
        HashSet hs = new HashSet();
        //创建学生对象
        Student s1 = new Student("林青霞", 30);
        Student s2 = new Student("张曼玉", 35);
        Student s3 = new Student("王祖贤", 33);
        Student s4 = new Student("王祖贤", 33);

        //把学生添加到集合
        hs.add(s1);
        hs.add(s2);
        hs.add(s3);
        hs.add(s4);

        //遍历集合(增强for)
        for (Student s : hs) {
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FFKtY98t-1647592964159)(java.assets/image-20210823190113166.png)]

alt+insert一直点即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X5xz4jRW-1647592964160)(java.assets/image-20210823190325466.png)]

07 LinkedHashSet集合概述和特点

08 TreeSet集合概述和特点

09 自然排序Comparable的使用

10 比较器排序Comparator的使用

11 成绩排序

12 不重复的随机数

4 泛型

4.1 泛型概述【类型参数化】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zTSs7O6j-1647592964160)(java.assets/image-20210815154147905.png)]

类比先前学过的。

定义方法时候,有形参,然后调用此方法时传递实参

泛型:参数化类型

就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型

集合被规定泛型后,就只能使用所规定的类型了

例子:使用泛型List之后,表示List集合中只允许存储Animal类型的数据。如果存储String类型,那么就报错了

List myList = new ArrayList();

使用泛型后,集合中元素的数据类型更加统一了。

【泛型就是将变量类型参数化,你i想是什么类型,就<在这里面传什么类型>】

其好处,两个:

package itheima1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class GenericDemo {
    public static void main(String[] args) {

        //创建集合对象
//        Collection c=new ArrayList();
        Collection c=new ArrayList();

        //添加元素,当我们没有指定添加类型的时候,添加的是默认object类型,因为泛型默认是引用类型,object可以代表所有的引用类型

        c.add("hello");
        c.add("world");
        c.add("java");      //我们把字符串赋值给object是向上转型
       // c.add(100);       这里会报错,因为前面已经用了String泛型,所以,100是一个int类型,会报错,就将运行期间的错误提前到编译阶段

        //使用迭代器来进行遍历

        Iterator it = c.iterator();
        while(it.hasNext()){
            /**
             *    Object obj=it.next();   //添加的时候,指针是object类型,所以获取的时候,也是object类型
             *             System.out.println(obj);
             */
            //因为存储的是object类型, 所以我们向下转型,想将其变成string类型,
//            String s=(String) it.next();
            String s=it.next();     //有了泛型,就不用加强制类型转换了

            System.out.println(s);

        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GJjsNCmx-1647592964160)(java.assets/image-20210815160406095.png)]

4.2 泛型类 < T >

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyotVxtI-1647592964160)(java.assets/image-20210815164444034.png)]

泛型方法

泛型接口

泛型类

package itheima;

public class Teacher {
    private Integer age;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}



package itheima;

public class Student {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}



package itheima;

public class Generic {		//T可以是String、Integer、Boolean
    private T t;
    public T getT(){
        return t;
    }
    public void setT(T t){
        this.t = t;
    }
}


package itheima;
//测试类
public class GenericDemo {
    public static void main(String[] args) {
     Student s=new Student();
     s.setName("林青霞");
        System.out.println(s.getName());

        Teacher t=new Teacher();
        t.setAge(30);
        System.out.println(t.getAge());
        
  		System.out.println("______________________");
        
        Generic g1=new Generic();
        g1.setT("林青霞");
        System.out.println(g1.getT());

        Generic g2= new Generic();
        g2.setT(30);
        System.out.println(g2.getT());

        Generic g3 = new Generic();
        g3.setT(true);
        System.out.println(g3.getT());
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2HTy1Flq-1647592964161)(java.assets/image-20220107134900876.png)]

CSDN总结:

java泛型T_dd_Mr的博客-CSDN博客

动力节点泛型

动力节点,泛型讲解,很好

4.3

4.5 类型通配符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OiHMhBeK-1647592964161)(java.assets/image-20210817141707054.png)]

4.6 可变参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6LIAu1be-1647592964161)(java.assets/image-20210817150718928.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TI5xKaTa-1647592964162)(java.assets/image-20210817143455241.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-flQmp4sq-1647592964162)(java.assets/image-20210817144342841.png)]

package itheima01;

public class ArhsDemo01 {
    public static void main(String[] args) {
        System.out.println(sum(10,20));
        System.out.println(sum(10,20,30));
        System.out.println(sum(10,20,30,40));
        System.out.println(sum(10,20,30,40,50));
    }

    public static int sum(int... a){
//        System.out.println(a);
        int sum=0;
        for(int i:a){
            sum+=i;
        }
        return sum;
    }


}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fx2QM7LG-1647592964162)(java.assets/image-20210817150401974.png)]

package itheima01;

public class ArhsDemo01 {
    public static void main(String[] args) {
        System.out.println(sum(10,20));
        System.out.println(sum(10,20,30));
        System.out.println(sum(10,20,30,40));
        System.out.println(sum(10,20,30,40,50));
    }
    /*
    public static int sum(int... a){
//        System.out.println(a);
        int sum=0;
        for(int i:a){
            sum+=i;
        }
        return sum;
    }
*/
    public static int sum(int b,int... a) {
        return 0;//这样会首先给b,然后剩余的给a
    }
}

4.7 可变参数的使用

5 Map【字典】

集合继承结构图_Map 部分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rbSa13eM-1647592964162)(java.assets/image-20220111233351234.png)]

java中一般用map与hashmap来创建一个key-value对象
使用前提是要导入方法包:
  import java.util.HashMap;
  import java.util.Map;
格式:
  Map 数据名称 =  new HashMap();

key(键)-value(值)类似python里面的字典
key-value是【一对一】对应关系(简单的打比方例如生活中的丈夫与妻子的关系)
就例如看到key就会想到说这是value的老公,你看到value就会说这是key的老婆
一般格式是{ key : value }

5.1 Map集合概述和使用

黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-liXkLKC6-1647592964163)(java.assets/image-20210823190716387.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NsN71rAu-1647592964163)(java.assets/image-20210823191336362.png)]

package itheima11;

import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 从南到北
 * @Date: 11/08/2021/14:40
 * @Description:
 *
 */
public class MapDemo01 {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("资源1","无人机");
        map.put("资源2","火炮");
        map.put("资源3","飞机");	// 被替代
        map.put("资源3","电脑");    // 每个键只能映射一个值 

        //输出集合对象
        System.out.println(map);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pcjwum40-1647592964163)(java.assets/image-20211108144800602.png)]

5.2 Map集合的基本功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QCeHWeQc-1647592964163)(java.assets/image-20210823192305735.png)]

package com.itheima_01;

import java.util.HashMap;
import java.util.Map;

/*
    Map集合的基本功能:
        V put(K key,V value):添加元素
        V remove(Object key):根据键删除键值对元素
        void clear():移除所有的键值对元素
        boolean containsKey(Object key):判断集合是否包含指定的键
        boolean containsValue(Object value):判断集合是否包含指定的值(自学)
        boolean isEmpty():判断集合是否为空
        int size():集合的长度,也就是集合中键值对的个数
 */
public class MapDemo02 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();

        //V put(K key,V value):添加元素
        map.put("张无忌","赵敏");
        map.put("郭靖","黄蓉");
        map.put("杨过","小龙女");

        //V remove(Object key):根据键删除键值对元素
//        System.out.println(map.remove("郭靖"));
//        System.out.println(map.remove("郭襄"));

        //void clear():移除所有的键值对元素
//        map.clear();

        //boolean containsKey(Object key):判断集合是否包含指定的键
//        System.out.println(map.containsKey("郭靖"));
//        System.out.println(map.containsKey("郭襄"));

        //boolean isEmpty():判断集合是否为空
//        System.out.println(map.isEmpty());

        //int size():集合的长度,也就是集合中键值对的个数
        System.out.println(map.size());
        //输出集合对象
        System.out.println(map);
    }
}



package itheima11;

import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 从南到北
 * @Date: 11/08/2021/14:51
 * @Description:
 */
public class MapDemo02 {
    public static void main(String[] args) {

        //创建集合对象
        Map map = new HashMap();

        //V put(K key,V value):添加元素
        map.put("张无忌","赵敏");
        map.put("郭靖","黄蓉");
        map.put("杨过","小龙女");

        System.out.println(map.remove("郭靖"));
        System.out.println(map);    //删除郭靖后,只剩“两个键值对”还有一个“黄蓉”

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jw19Z7SL-1647592964164)(java.assets/image-20211108145444287.png)]

5.3 Map集合的获取功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywcJ63gF-1647592964164)(java.assets/image-20211108151526784.png)]

package itheima11;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 从南到北
 * @Date: 11/08/2021/15:02
 * @Description:
 */
public class MapDemo03 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();
        //添加元素
        map.put("张无忌","赵敏");
        map.put("郭靖","黄蓉");
        map.put("杨过","小龙女");

        //V get(Object Key):根据键获取值
        System.out.println(map.get("张无忌")); //输出赵敏

        //获取所有键的集合
        Set keySet = map.keySet();
        for(String key:keySet){
            System.out.println(key);
        }

        // Collection values() 获取所有值的集合
        Collection values = map.values();
        for (String value : values) {
            System.out.println(value);
        }


    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zwf6HQcP-1647592964164)(java.assets/image-20211108151624239.png)]

5.4 Map集合的遍历(方式1)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DzilhimS-1647592964165)(java.assets/image-20211108152712212.png)]

package itheima11;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 从南到北
 * @Date: 11/08/2021/15:20
 * @Description:
 *
 * map集合遍历的方式1
 */
public class MapDemo04 {
    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();
        //添加元素
        map.put("张无忌","赵敏");
        map.put("郭靖","黄蓉");
        map.put("杨过","小龙女");

        //获取所有键的集合,用keySet()方法实现
        Set keySet = map.keySet();
        for (String key : keySet) {
            //根据键去找值,用get(Object key) 方法实现
            String value = map.get(key);
            System.out.println(key+","+value);
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-epJWBfkB-1647592964165)(java.assets/image-20211108152749266.png)]

5.5 Map集合的遍历(方式2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYi4QFNs-1647592964165)(java.assets/image-20211108153341167.png)]

package itheima11;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 从南到北
 * @Date: 11/08/2021/15:34
 * @Description:
 *      5.5 Map集合的遍历(方式2)
 */
public class MapDemo05 {

    public static void main(String[] args) {
        //创建集合对象
        Map map = new HashMap();
        //添加元素
        map.put("张无忌","赵敏");
        map.put("郭靖","黄蓉");
        map.put("杨过","小龙女");

        //获得所有键值对,对象的集合
        Set> entrySet = map.entrySet();
        //遍历键值对,对象集合,得到每一个键值对对象
        for (Map.Entry me : entrySet) {
            //根据键值对 对象获取键和值
            String key = me.getKey();
            String value = me.getValue();
            System.out.println(key+","+value);
        }


    }
}

案例:HashMap集合存储学生对象并遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kjydXf3p-1647592964165)(java.assets/image-20211108154040038.png)]

案例:HashMap集合存储ArrayList元素并遍历

案例:统计字符串中每个字符出现的次数

黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bSF3AdTS-1647592964166)(java.assets/image-20211109104718168.png)]

File文件操作

1 File

1.1 File类概述和构造方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kpPI5zBm-1647592964166)(java.assets/image-20210619214223001.png)]

package com.itheima;

import java.io.File;

/*
    File:文件和目录路径名的抽象表示
          1:文件和目录是可以通过File封装成对象的
          2:对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。
            将来是要通过具体的操作把这个路径的内容转换为具体存在的

    构造方法:
        File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
        File(String parent, String child):从父路径名字符串和子路径名字符串创建新的 File实例。
        File(File parent, String child):从父抽象路径名和子路径名字符串创建新的 File实例。
 */
public class FileDemo01 {
    public static void main(String[] args) {
        //File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
        File f1 = new File("D:\itcast\java.txt");
        System.out.println(f1);

        //File(String parent, String child):从父路径名字符串和子路径名字符串创建新的 File实例。
        File f2 = new File("D:\itcast","java.txt");
        System.out.println(f2);

        //File(File parent, String child):从父抽象路径名和子路径名字符串创建新的 File实例。
        File f3 = new File("D:\itcast");
        File f4 = new File(f3,"java.txt");
        System.out.println(f4);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZnV2baL-1647592964166)(java.assets/image-20210619220503030.png)]

并且不会创建该文件!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Axo1dwwO-1647592964167)(java.assets/image-20210624091541639.png)]

  • 这个parent我知道啥意思了,就是他的上一级目录,然后child就是这个文件本身

  • 这个是将文件路径封装成一个可以操作的对象

     File f1 = new File("D:\itcast\java.txt");
    

1.2 File类创建功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tEavLOag-1647592964167)(java.assets/image-20210619220619360.png)]

package com.itheima;

import java.io.File;
import java.io.IOException;

/*
    File类创建功能:
        public boolean createNewFile():当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
            如果文件不存在,就创建文件,并返回true
            如果文件存在,就不创建文件,并返回false

        public boolean mkdir():创建由此抽象路径名命名的目录
            如果目录不存在,就创建目录,并返回true
            如果目录存在,就不创建目录,并返回false

        public boolean mkdirs():创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
            自己补齐
 */
public class FileDemo02 {
    public static void main(String[] args) throws IOException {
        //需求1:我要在E:\itcast目录下创建一个文件java.txt
        File f1 = new File("E:\itcast\java.txt");
        System.out.println(f1.createNewFile());
        System.out.println("--------");

        //需求2:我要在E:\itcast目录下创建一个目录JavaSE
        File f2 = new File("E:\itcast\JavaSE");
        System.out.println(f2.mkdir());
        System.out.println("--------");

        //需求3:我要在E:\itcast目录下创建一个多级目录JavaWEB\HTML
        File f3 = new File("E:\itcast\JavaWEB\HTML");
//        System.out.println(f3.mkdir());
        System.out.println(f3.mkdirs());
        System.out.println("--------");

        //需求4:我要在E:\itcast目录下创建一个文件javase.txt
        File f4 = new File("E:\itcast\javase.txt");
//      System.out.println(f4.mkdir());   //创建文件就用创建文件的函数,不然这个会生成一个javase.txt的文件夹的
        System.out.println(f4.createNewFile());
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vlOin85o-1647592964167)(java.assets/image-20210619221744319.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LYFZKt7t-1647592964167)(java.assets/image-20210619221802361.png)]

1.3 File类删除功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l4yG53vB-1647592964168)(java.assets/image-20210625103825493.png)]

1.4 File类判断和获取功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HoI1LeX-1647592964168)(java.assets/image-20210619221910427.png)]

黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

package com.itheima;

import java.io.File;

/*
    File类的判断和获取功能:
        public boolean isDirectory():测试此抽象路径名表示的File是否为目录
        public boolean isFile():测试此抽象路径名表示的File是否为文件
        public boolean exists():测试此抽象路径名表示的File是否存在

        public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串
        public String getPath():将此抽象路径名转换为路径名字符串
        public String getName():返回由此抽象路径名表示的文件或目录的名称

        public String[] list():返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
        public File[] listFiles():返回此抽象路径名表示的目录中的文件和目录的File对象数组
 */
public class FileDemo04 {
    public static void main(String[] args) {
        //创建一个File对象
        File f = new File("myFile\java.txt");

//        public boolean isDirectory():测试此抽象路径名表示的File是否为目录
//        public boolean isFile():测试此抽象路径名表示的File是否为文件
//        public boolean exists():测试此抽象路径名表示的File是否存在
        System.out.println(f.isDirectory());
        System.out.println(f.isFile());
        System.out.println(f.exists());

//        public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串
//        public String getPath():将此抽象路径名转换为路径名字符串
//        public String getName():返回由此抽象路径名表示的文件或目录的名称
        System.out.println(f.getAbsolutePath());
        System.out.println(f.getPath());    //这个是我们封装好的路径
        System.out.println(f.getName());    //文件的名称
        System.out.println("--------");

//        public String[] list():返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
//        public File[] listFiles():返回此抽象路径名表示的目录中的文件和目录的File对象数组
        File f2 = new File("E:\itcast");

        String[] strArray = f2.list();
        for(String str : strArray) {
            System.out.println(str);
        }
        System.out.println("--------");

        File[] fileArray = f2.listFiles();
        for(File file : fileArray) {
//            System.out.println(file);
//            System.out.println(file.getName());
            if(file.isFile()) {
                System.out.println(file.getName());
            }
        }
    }
}

2 字节流

2.1 IO流概述和分类(inputstream,outputstream)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tx99gTKy-1647592964168)(java.assets/image-20210620205244239.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ku0LuBCu-1647592964169)(java.assets/image-20210620205404707.png)]

输入:就是从硬盘读数据到程序

输出:就是从程序把内容写到硬盘

出入以内存为参考

IO流分类:

  • 按照数据的流向
    输入流:读数据

    输出流:写数据

  • 按照数据类型来分

    字节流

    字节输入流;字节输出流

    字符流

    字符输入流;字符输出流

一般来说,我们说的IO流是按照数据类型来分的

输入流inputstream,读数据

输出流outputstream,写数据

这是两个抽象基类

2.2 字节流写数据(FileOutputStream,write)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OO5XeL8U-1647592964169)(java.assets/image-20210620212119447.png)]

package com.itheima_01;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
    FileOutputStream:文件输出流用于将数据写入File
        FileOutputStream(String name):创建文件输出流以指定的名称写入文件
 */
public class FileOutputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //创建字节输出流对象
        //FileOutputStream (String name):创建文件输出流以指定的名称写入文件
        FileOutputStream fos = new FileOutputStream("myByteStream\fos.txt");
        /*
            做了三件事情:
                A:调用系统功能创建了文件
                B:创建了字节输出流对象
                C:让字节输出流对象指向创建好的文件
         */

        //void write (int b):将指定的字节写入此文件输出流
        fos.write(97);	//b
//        fos.write(57);	//9
//        fos.write(55);	//7

        //最后都要释放资源
        //void close ():关闭此文件输出流并释放与此流相关联的任何系统资源。
        fos.close();
    }
}

2.3 字节流写数据的3种方式(一次-1个字节,1个字节数组,1个字节的部分字节数组)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WUGBd9gW-1647592964169)(java.assets/image-20210620212321692.png)]

package com.itheima_01;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
    构造方法:
        FileOutputStream(String name):创建文件输出流以指定的名称写入文件
        FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件

    写数据的三种方式:
        void write(int b):将指定的字节写入此文件输出流
        一次写一个字节数据

        void write(byte[] b):将 b.length字节从指定的字节数组写入此文件输出流
        一次写一个字节数组数据

        void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流
        一次写一个字节数组的部分数据
*/
public class FileOutputStreamDemo02 {
    public static void main(String[] args) throws IOException {
        //FileOutputStream(String name):创建文件输出流以指定的名称写入文件
        FileOutputStream fos = new FileOutputStream("myByteStream\fos.txt");
       //代码一执行,整个文件都是重新建立的
        //new File(name)
//        FileOutputStream fos = new FileOutputStream(new File("myByteStream\fos.txt"));

        //FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件
//        File file = new File("myByteStream\fos.txt");
//        FileOutputStream fos2 = new FileOutputStream(file);
//        FileOutputStream fos2 = new FileOutputStream(new File("myByteStream\fos.txt"));

        //void write(int b):将指定的字节写入此文件输出流
//        fos.write(97);
//        fos.write(98);
//        fos.write(99);
//        fos.write(100);
//        fos.write(101);

//        void write(byte[] b):将 b.length字节从指定的字节数组写入此文件输出流
//        byte[] bys = {97, 98, 99, 100, 101};
        //byte[] getBytes():返回字符串对应的字节数组
        byte[] bys = "abcde".getBytes();
//        fos.write(bys);

        //void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流	
//        fos.write(bys,0,bys.length);
        fos.write(bys,1,3); //bcd//这个意思是,从索引为1开始,写3个

        //释放资源
        fos.close();
    }
}

2.4 字节流写数据的两个小问题?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ybE5I5h0-1647592964169)(java.assets/image-20210621144536397.png)]

package com.itheima_01;

import java.io.FileOutputStream;
import java.io.IOException;

/*
    字节流写数据的两个小问题:
        1:字节流写数据如何实现换行呢?

        (不同的系统识别换行是不一样的)
            window:

            linux:

            mac:

        2:字节流写数据如何实现追加写入呢?
            public FileOutputStream?(String name,boolean append)
                创建文件输出流以指定的名称写入文件。
                如果第二个参数为true ,则字节将写入文件的末尾而不是开头
 */
public class FileOutputStreamDemo03 {
    public static void main(String[] args) throws IOException {
        //创建字节输出流对象
//        FileOutputStream fos = new FileOutputStream("myByteStream\fos.txt");
        FileOutputStream fos = new FileOutputStream("myByteStream\fos.txt",true);

        //写数据
        for (int i = 0; i < 10; i++) {
            fos.write("hello".getBytes());
            fos.write("
".getBytes());
        }

        //释放资源
        fos.close();
    }
}

2.5 字节流写数据加异常处理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-84Lgq0pK-1647592964170)(java.assets/image-20210621144806656.png)]

因为throw抛出异常后,后面的close()就不会执行了,所以就用finally函数

try。。。catch。。。finally处理异常可以在编译时找到 发生问题的原因,并明确原因

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9eAgw7tj-1647592964170)(java.assets/image-20210621145435409.png)]

package com.itheima;

import java.io.FileOutputStream;
import java.io.IOException;

/*
    字节流写数据加入异常处理
 */
public class FileOutputStreamDemo04 {
    public static void main(String[] args) {
//        try {
//            FileOutputStream fos = new FileOutputStream("myByteStream\fos.txt");
//            fos.write("hello".getBytes());
//            fos.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        //加入finally来实现释放资源
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("myByteStream\fos.txt");
//            fos = new FileOutputStream("Z:\myByteStream\fos.txt");
            fos.write("hello".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

2.6 字节流读数据(FileInputStream,read)

2.6.1 一次读一个字节数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a24MWIjZ-1647592964170)(java.assets/image-20210621145900172.png)]

 FileInputStream fis = new FileInputStream("idea_test\fos.txt");

【fos、fis,老师的这个命名也是非常讲究的】

package com.itheima;

import java.io.FileInputStream;
import java.io.IOException;

/*
    需求:
        把文件fos.txt中的内容读取出来在控制台输出

        FileInputStream:从文件系统中的文件获取输入字节
        FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名

    使用字节输入流读数据的步骤:
        1:创建字节输入流对象
        2:调用字节输入流对象的读数据方法
        3:释放资源
 */

public class FileInputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        //FileInputStream(String name)
        FileInputStream fis = new FileInputStream("myByteStream\fos.txt");

        //调用字节输入流对象的读数据方法
        //int read():从该输入流读取一个字节的数据

        /*
        //第一次读取数据
        int by = fis.read();
        System.out.println(by);
        System.out.println((char)by);

        //第二次读取数据
        by = fis.read();
        System.out.println(by);
        System.out.println((char)by);

        //再多读取两次
        by = fis.read();
        System.out.println(by);
        by = fis.read();
        System.out.println(by);

        //如果达到文件的末尾, -1
        */

        /*
        int by = fis.read();
        while (by != -1) {
            System.out.print((char)by);
            by = fis.read();
        }
        */

        //优化上面的程序
        int by;
        /*
            fis.read():读数据
            by=fis.read():把读取到的数据赋值给by
            by != -1:判断读取到的数据是否是-1
         */
        while ((by=fis.read())!=-1) {
            System.out.print((char)by);
        }

        //释放资源
        fis.close();
    }
}

每次读取一个字节也有3种方式,当读到文件末尾时,返回结果-1

fis.read(),读数据是fis流

案例:复制文本文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cizqaFtn-1647592964171)(java.assets/image-20210621154904558.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EiJOzvij-1647592964171)(java.assets/image-20210621154926595.png)]

OutputStream和InputStream是抽象类

package com.itheima_02;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
    需求:
        把“E:\itcast\窗里窗外.txt”复制到模块目录下的“窗里窗外.txt”

        数据源:
            E:\itcast\窗里窗外.txt --- 读数据 --- InputStream --- FileInputStream
        目的地:
            myByteStream\窗里窗外.txt --- 写数据 --- OutputStream --- FileOutputStream

    思路:
        1:根据数据源创建字节输入流对象
        2:根据目的地创建字节输出流对象
        3:读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)
        4:释放资源
 */
public class CopyTxtDemo {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字节输入流对象
        FileInputStream fis = new FileInputStream("E:\itcast\窗里窗外.txt");
        //根据目的地创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("myByteStream\窗里窗外.txt");

        //读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)
        int by;
        while ((by=fis.read())!=-1) {
            fos.write(by);
        }

        //释放资源
        fos.close();
        fis.close();
    }
}

2.6.2 一次读一个字节数组数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KUiXhDjP-1647592964171)(java.assets/image-20210621161445821.png)]

package com.itheima;

import java.io.FileInputStream;
import java.io.IOException;

/*
    需求:把文件fos.txt中的内容读取出来在控制台输出

    使用字节输入流读数据的步骤:
        1:创建字节输入流对象
        2:调用字节输入流对象的读数据方法
        3:释放资源
 */
public class FileInputStreamDemo02 {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fis = new FileInputStream("myByteStream\fos.txt");

        //调用字节输入流对象的读数据方法
        //int read(byte[] b):从该输入流读取最多 b.length个字节的数据到一个字节数组
        /*
        byte[] bys = new byte[5];

        //第一次读取数据
        int len = fis.read(bys);        //这个length不是字节数组的长度,而是实际读取的数据的个数
        System.out.println(len);
        //String(byte[] bytes)      将字节数组的数据转到字符串里面,然后输出
//          string的一个构造方法,直接把字节数组变成字符串

//      System.out.println(new String(bys));
        System.out.println(new String(bys,0,len));

        //第二次读取数据
        len = fis.read(bys);
        System.out.println(len);
//        System.out.println(new String(bys));
        System.out.println(new String(bys,0,len));

        //第三次读取数据
        len = fis.read(bys);
        System.out.println(len);
        //   System.out.println(new String(bys));     //这次只读了四个,所以还有一个上次读的没有替换掉
        //String(byte[] bytes, int offset, int length) 这个方法是只显示数组长度的内容
        System.out.println(new String(bys,0,len));

        //再多读取两次
        len = fis.read(bys);
        System.out.println(len);
        len = fis.read(bys);
        System.out.println(len);
        */

        /*
            hello

            world


            第一次:hello
            第二次:
wor
            第三次:ld
r

         */

        byte[] bys = new byte[1024]; //1024及其整数倍
        int len;	 //这个len是实际每次读取的数据的个数
        
        while ((len=fis.read(bys))!=-1) {
            System.out.print(new String(bys,0,len));
        }
		  System.out.println(len);    //此时输出的是-1
        //释放资源
        fis.close();
    }
}

注意:

  • String(byte[] bytes, int offset, int length, Charset charset)

    构建了一种新的 String通过解码指定的字节数组使用指定的 charset。

  • byte[] bys = new byte[1024]; //1024及其整数倍,这个[]里面通常是1024的整倍数

  • int len; //这个len是实际每次读取的数据的个数

2.7 字节缓冲流( BufferOutputStream,BufferedInputStream)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e2zcpaBq-1647592964171)(java.assets/image-20210621170757957.png)]

package com.itheima_03;
import java.io.*;

/*
    字节缓冲流:
        BufferOutputStream
        BufferedInputStream
    构造方法:
        字节缓冲输出流:BufferedOutputStream(OutputStream out)
        字节缓冲输入流:BufferedInputStream(InputStream in)
 */

public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
        //字节缓冲输出流:BufferedOutputStream(OutputStream out)
//        FileOutputStream fos = new FileOutputStream("myByteStream\bos.txt");
//        BufferedOutputStream bos = new BufferedOutputStream(fos);
        
        /*
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\bos.txt"));
        //写数据
        bos.write("hello
".getBytes());
        bos.write("world
".getBytes());
        //释放资源
        bos.close();
        */
        
        //字节缓冲输入流:BufferedInputStream?(InputStream in)
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream\bos.txt"));

        //一次读取一个字节数据
//        int by;
//        while ((by=bis.read())!=-1) {
//            System.out.print((char)by);
//        }
        
        //一次读取一个字节数组数据
        byte[] bys = new byte[1024];
        int len;
        while ((len=bis.read(bys))!=-1) {
            System.out.print(new String(bys,0,len));
        }
        
        //释放资源
        bis.close();
    }
}

注意:字节缓冲流里面存放字节流

package com.itheima_03;
import java.io.*;
public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream\bos.txt"));
        byte[] bys = new byte[1024];
        int len;
        while ((len=bis.read(bys))!=-1) {
            System.out.print(new String(bys,0,len));
        }
        bis.close();
    }
}

案例:复制视频

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0XQWMwDM-1647592964172)(java.assets/image-20210623140201975.png)]

package com.itheima_03;

import java.io.*;

/*
    需求:
        把E:\itcast\字节流复制图片.avi 复制到模块目录下的 字节流复制图片.avi

    思路:
        1:根据数据源创建字节输入流对象
        2:根据目的地创建字节输出流对象
        3:读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
        4:释放资源

    四种方式实现复制视频,并记录每种方式复制视频的时间
        1:基本字节流一次读写一个字节             共耗时:64565毫秒
        2:基本字节流一次读写一个字节数组          共耗时:107毫秒
        3:字节缓冲流一次读写一个字节             共耗时:405毫秒
        4:字节缓冲流一次读写一个字节数组          共耗时:60毫秒
 */
public class CopyAviDemo {
    public static void main(String[] args) throws IOException {
        //记录开始时间
        long startTime = System.currentTimeMillis();

        //复制视频
//        method1();
//        method2();
//        method3();
        method4();

        //记录结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("共耗时:" + (endTime - startTime) + "毫秒");
    }

    //字节缓冲流一次读写一个字节数组
    public static void method4() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\itcast\字节流复制图片.avi"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\字节流复制图片.avi"));

        byte[] bys = new byte[1024];
        int len;
        while ((len=bis.read(bys))!=-1) {
            bos.write(bys,0,len);
        }
        bos.close();
        bis.close();
    }

    //字节缓冲流一次读写一个字节
    public static void method3() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\itcast\字节流复制图片.avi"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\字节流复制图片.avi"));

        int by;
        while ((by=bis.read())!=-1) {
            bos.write(by);
        }

        bos.close();
        bis.close();
    }


    //基本字节流一次读写一个字节数组
    public static void method2() throws IOException {
        //E:\itcast\字节流复制图片.avi
        //模块目录下的 字节流复制图片.avi
        FileInputStream fis = new FileInputStream("E:\itcast\字节流复制图片.avi");
        FileOutputStream fos = new FileOutputStream("myByteStream\字节流复制图片.avi");

        byte[] bys = new byte[1024];
        int len;
        while ((len=fis.read(bys))!=-1) {
            fos.write(bys,0,len);
        }

        fos.close();
        fis.close();
    }

    //基本字节流一次读写一个字节
    public static void method1() throws IOException {
        //E:\itcast\字节流复制图片.avi
        //模块目录下的 字节流复制图片.avi
        FileInputStream fis = new FileInputStream("E:\itcast\字节流复制图片.avi");
        FileOutputStream fos = new FileOutputStream("myByteStream\字节流复制图片.avi");

        int by;
        while ((by=fis.read())!=-1) {
            fos.write(by);
        }

        fos.close();
        fis.close();
    }
}

3 字符流

3.1 为什么会出现字符流

注意:字符>字节

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VWhlorVn-1647592964172)(java.assets/image-20210623151238462.png)]

package com.itheima_01;

/*
    需求:字节流读文本文件数据

    一个汉字存储:
        如果是GBK编码,占用2个字节
        如果是UTF-8编码,占用3个字节
 */

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("idea_test\a.txt");
        int by;
        while((by=fis.read())!=-1){
            System.out.print((char)by);
        }
        fis.close();
    }
}

文本文件:abc

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yiO5Qfse-1647592964172)(java.assets/image-20210623145741162.png)]

文本文件:abc汉字

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7hc9gvOh-1647592964173)(java.assets/image-20210623145813322.png)]

原因:

一个汉字存储:
    如果是GBK编码,占用2个字节
    如果是UTF-8编码,占用3个字节
   因为你是一个字节一个的读的

故,提供了字符流

还有一点疑惑:

用字节流读写文件的时候,为什么没有问题:因为此时,汉字的字节为负数

实例如下:

import java.io.IOException;
import java.util.Arrays;

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
            String s="abc"; //[97, 98, 99]
            String s1="中国";
            byte[] bys=s.getBytes();
            byte[] bys1=s1.getBytes("UTF-8");   //[-28, -72, -83, -27, -101, -67]       此时编译器会将3个字符组成一个汉字
            byte[] bys2=s1.getBytes("GBK");     //[-42, -48, -71, -6]               此时编译器会将2个字符组成一个汉字
            System.out.println(Arrays.toString(bys2));
    }
}

3.2

3.5 字符流写数据的5种方式(OutputStreamWriter,write,flush刷新流)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nVHzpQXi-1647592964173)(java.assets/image-20210623151801863.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yp6WgldB-1647592964173)(java.assets/image-20210623155706645.png)]

构造方法:

OutputStreamWriter(OutputStream out):创建一个使用默认字符编码的OutputStreamWriter

void write(int c):写一个字符

package com.itheima_02;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/*
    构造方法:
        OutputStreamWriter(OutputStream out):创建一个使用默认字符编码的OutputStreamWriter

    写数据的5种方式:
        void write(int c):写一个字符
        void write(char[] cbuf):写入一个字符数组
        void write(char[] cbuf, int off, int len):写入字符数组的一部分
        void write(String str):写一个字符串
        void write(String str, int off, int len):写一个字符串的一部分
 */

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //字符流写数据不能直接写进文件中,会先放到缓存区中,最终需要通过字节流写,需要用flush()刷新流
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("idea_test\osw.txt"));
        osw.write(97);  //写一个字符
        osw.flush();    //刷新流
        osw.write(98);
        osw.flush();
        osw.write(99);
        //close()这个方法,关闭流,先刷新
        osw.close();
        //Exception in thread "main" java.io.IOException: Stream closed
      //  osw.write(100);
    }
}

void write(char[] cbuf):写入一个字符数组

字符流write写数据()

OutputStreamWriter:

package com.itheima_02;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //字符流写数据不能直接写进文件中,会先放到缓存区中,最终需要通过字节流写,需要用flush()刷新流
        //OutputStreamWriter(OutputStream out):创建一个使用默认字符编码的OutputStreamWriter
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\osw.txt"));

        //方法二:void write(char[] cbuf):写入一个字符数组
        char[] chs = {'a', 'b', 'c', 'd', 'e'};
//        osw.write(chs);

        //方法三:void write(char[] cbuf, int off, int len):写入字符数组的一部分
//        osw.write(chs, 0, chs.length);
//        osw.write(chs, 1, 3);

        //方法四:void write(String str):写一个字符串
//        osw.write("abcde");

        //方法五:void write(String str, int off, int len):写一个字符串的一部分
//        osw.write("abcde", 0, "abcde".length());
        osw.write("abcde", 1, 3);

        //释放资源
        osw.close();
        //Exception in thread "main" java.io.IOException: Stream closed
//        osw.write(100);
    }
}

注意:字符流写数据不能直接到文件,需要刷新flush()一下.

实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNUZS03n-1647592964174)(java.assets/162655699.jpg)]

/**
? ? ? ? * flush() 方法是清空,即清空缓冲区数据,就是说
? ? ? ? * 你用读写流的时候,其实数据是先被读到了内存中,
? ? ? ? * 然后用数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,
? ? ? ? * 因为还有一部分有可能留在内存这个缓冲区中.这时候如果你调用了
? ? ? ? * close方法关闭了读写流,那么这部分数据就会丢失,【注意:现在close()在关闭的时候,会先刷新一次】
? ? ? ? * 所以应该再关闭读写流之前先flush(),显得清空数据.
? ? ? ? */
? ? ? ?//刷新就是将内存(缓冲区)中的数据(是一个字节数组)强制写到磁盘/浏览器/控制台/文件

参考链接: 使用字符流 必须刷新缓冲区 flush_Hurricane_m的博客-CSDN博客

3.6 字符流读数据的两种方式(InputStreamReader,read)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GNbJT7WF-1647592964174)(java.assets/image-20210623155752234.png)]

字节流和字符流读数据读的内容是一样的,只是方式不一样

package com.itheima_02;
/*	
    构造方法:
        InputStreamReader(InputStream in):创建一个使用默认字符集的InputStreamReader

    读数据的2种方式:
        int read():一次读一个字符数据
        int read(char[] cbuf):一次读一个字符数组数据
 */

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("idea_test\osw.txt"));
//      第一种方式:
//      int read():一次读一个字符数据
//        int ch;
//        while((ch=isr.read())!=-1){
//            System.out.print((char)ch);
//        }
//        isr.close();
        //第二种方式:
        // int read(char[] cbuf):一次读一个字符数组数据
        char[] chs=new char[1024];
        int len;
        while((len =isr.read(chs))!=-1){
            System.out.println(new String(chs,0,len));
        }
        isr.close();
    }
}

案例:复制java文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pIwU2TGz-1647592964174)(java.assets/image-20210623183524821.png)]

package com.itheima_03;

import java.io.*;

/*
    需求:
        把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java

    思路:
        1:根据数据源创建字符输入流对象
        2:根据目的地创建字符输出流对象
        3:读写数据,复制文件
        4:释放资源
 */
public class CopyJavaDemo01 {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字符输入流对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\ConversionStreamDemo.java"));
        //根据目的地创建字符输出流对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\Copy.java"));

        //读写数据,复制文件
        //一次读写一个字符数据
//        int ch;
//        while ((ch=isr.read())!=-1) {
//            osw.write(ch);
//        }
//一次读写一个字符数组数据
        char[] chs = new char[1024];
        int len;
        while ((len=isr.read(chs))!=-1) {
            osw.write(chs,0,len);
        }
        //释放资源
        osw.close();
        isr.close();
    }
}

案例:复制java文件(改进版使用FileReader,FileWriter)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jMRlWHbP-1647592964174)(java.assets/image-20210623185251736.png)]

注意:如果在字符流中涉及到编码和解码问题,还得使用转换流inputstreamreader和outputstreamreader

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pu0FyKO3-1647592964175)(java.assets/image-20210623205724958.png)]

package com.itheima_03;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
    需求:
        把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java

    数据源和目的地的分析
        数据源:myCharStream\ConversionStreamDemo.java --- 读数据 --- Reader --- InputStreamReader --- FileReader
        目的地: myCharStream\ Copy.java --- 写数据 --- Writer --- OutputStreamWriter --- FileWriter

    思路:
        1:根据数据源创建字符输入流对象
        2:根据目的地创建字符输出流对象
        3:读写数据,复制文件
        4:释放资源
 */
public class CopyJavaDemo02 {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字符输入流对象
        FileReader fr = new FileReader("myCharStream\ConversionStreamDemo.java");
        //根据目的地创建字符输出流对象
        FileWriter fw = new FileWriter("myCharStream\Copy.java");

//读写数据,复制文件
//        int ch;
//        while ((ch=fr.read())!=-1) {
//            fw.write(ch);
//        }        
        char[] chs = new char[1024];
        int len;
        while ((len=fr.read(chs))!=-1) {
            fw.write(chs,0,len);
        }
        //释放资源
        fw.close();
        fr.close();
    }
}

3.7 字符缓存流(BufferedWriter,BufferedReader)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tYDKgqZq-1647592964175)(java.assets/image-20210622112448656.png)]

BufferedWriter

BufferedReader

缓冲流:用来提高读写效率

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NIbK2XJS-1647592964175)(java.assets/image-20210624103607089.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BkxkS8L8-1647592964176)(java.assets/image-20210624103650824.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YePbgMvm-1647592964176)(java.assets/image-20210624103703345.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mOQ7Uc5S-1647592964176)(java.assets/image-20210623210827841.png)]

通过源码知道:这两个缓冲流封装的是长度为8192个字符的字符数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I15CsZuV-1647592964176)(java.assets/image-20210624104855129.png)]

package com.itheima_04;

import java.io.*;

/*
    字符缓冲流:
        BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
        BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途

    构造方法:
        BufferedWriter(Writer out)
        BufferedReader(Reader in)
 */
public class BufferedStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //BufferedWriter(Writer out)
//        FileWriter fw = new FileWriter("idea_test\bw.txt");
//        BufferedWriter bw = new BufferedWriter(fw);
        BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\bw.txt"));

        bw.write("hello
");
        bw.write("world
");

        bw.close();

        //BufferedReader(Reader in)
       // BufferedReader br = new BufferedReader(new FileReader("myCharStream\bw.txt"));

        //一次读取一个字符数据
//        int ch;
//        while ((ch=br.read())!=-1) {
//            System.out.print((char)ch);
//        }

//        //一次读取一个字符数组数据
//        char[] chs = new char[1024];
//        int len;
//        while ((len=br.read(chs))!=-1) {
//            System.out.print(new String(chs,0,len));
//        }
//
//        br.close();

    }
}



package com.itheima_04;
import java.io.*;
public class BufferedStreamDemo01 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\bw.txt"));
        bw.write("hello
");
        bw.write("world
");
        bw.close();
    }
}

案例:复制java文件(字符缓冲流改进版)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jywPqiBb-1647592964177)(java.assets/image-20210623234211872.png)]

package com.itheima_03;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
    需求:
        把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java

    数据源和目的地的分析
        数据源:myCharStream\ConversionStreamDemo.java --- 读数据 --- Reader --- InputStreamReader --- FileReader
        目的地: myCharStream\ Copy.java --- 写数据 --- Writer --- OutputStreamWriter --- FileWriter

    思路:
        1:根据数据源创建字符输入流对象
        2:根据目的地创建字符输出流对象
        3:读写数据,复制文件
        4:释放资源
 */

     
        
public class CopyJavaDemo02 {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字符输入流对象
        FileReader fr = new FileReader("myCharStream\ConversionStreamDemo.java");
        //根据目的地创建字符输出流对象
        FileWriter fw = new FileWriter("myCharStream\Copy.java");

        //读写数据,复制文件
//        int ch;
//        while ((ch=fr.read())!=-1) {
//            fw.write(ch);
//        }

        char[] chs = new char[1024];
        int len;
        while ((len=fr.read(chs))!=-1) {
            fw.write(chs,0,len);
        }

        //释放资源
        fw.close();
        fr.close();
    }
}

3.8 字符缓冲流特有功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D8Mf6YWx-1647592964177)(java.assets/image-20210624103121041.png)]

package com.itheima_04;
import java.io.*;
/*
    字符缓冲流的特有功能
        BufferedWriter:
            void newLine():写一行行分隔符,行分隔符字符串由系统属性定义

        BufferedReader:
            public String readLine():读一行文字。
                结果包含行的内容的字符串,不包括任何行终止字符,如果流的结尾已经到达,则为null
 */

public class BufferedStreamDemo02 {
    public static void main(String[] args) throws IOException {
     /*
        //创建字符缓冲输出流
        BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\bw.txt"));
        //写数据
        for (int i=0;i<10;i++){
            bw.write("hello"+i);
//            bw.write("
");
            bw.newLine();
            bw.flush();
        }
        //释放资源
        bw.close();
        */

        //创建字符缓冲输入流读数据
        BufferedReader br = new BufferedReader(new FileReader("idea_test\bw.txt"));
//        public String readLine():读一行文字。不包括换行,所以要自己添加换行
//        //第一次读取数据
//        String line=br.readLine();
//        System.out.println(line);
//          //第二次读取数据
//       line=br.readLine();
//        System.out.println(line);
//          //在多读两次
//       line=br.readLine();
//        System.out.println(line);
//        line=br.readLine();
        System.out.println(line);
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }
}

案例:复制java文件(字符缓冲流特有功能改进版)字符流复制文件最常用方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HWvc8jSY-1647592964177)(java.assets/image-20210624111026373.png)]

package com.itheima_04;

import java.io.*;

/*
    需求:
        把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java

    思路:
        1:根据数据源创建字符缓冲输入流对象
        2:根据目的地创建字符缓冲输出流对象
        3:读写数据,复制文件
            使用字符缓冲流特有功能实现
        4:释放资源
 */
public class CopyJavaDemo02 {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("myCharStream\ConversionStreamDemo.java"));
        //根据目的地创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\Copy.java"));

        //读写数据,复制文件
        //使用字符缓冲流特有功能实现
        String line;
        while ((line=br.readLine())!=null) {
            bw.write(line);//该方法不会换行,所以需要换行的方法
            bw.newLine();//行分隔符
            bw.flush();	//刷新一下,事实证明,没有这句,仍然可以
        }

        //释放资源
        bw.close();
        br.close();
    }
}

3.9 IO流小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oOqHPwrm-1647592964177)(java.assets/image-20210624170059328.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-btvSHeii-1647592964178)(java.assets/image-20210624170207878.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LOZlxzoe-1647592964178)(java.assets/image-20210624170335872.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nkm7uyhn-1647592964178)(java.assets/image-20210624195527382.png)]

案例:集合到文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ziltzfcy-1647592964178)(java.assets/image-20210624195652190.png)]

package com.itheima_05;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/*
    需求:
        把ArrayList集合中的字符串数据写入到文本文件。要求:每一个字符串元素作为文件中的一行数据

    思路:
        1:创建ArrayList集合
        2:往集合中存储字符串元素
        3:创建字符缓冲输出流对象
        4:遍历集合,得到每一个字符串数据
        5:调用字符缓冲输出流对象的方法写数据
        6:释放资源
 */
 
public class ArrayListToTxtDemo {
    public static void main(String[] args) throws IOException {
        //创建ArrayList集合
        ArrayList array = new ArrayList();

        //往集合中存储字符串元素
        array.add("hello");
        array.add("world");
        array.add("java");

        //创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\array.txt"));

        //遍历集合,得到每一个字符串数据
        for(String s : array) {
            //调用字符缓冲输出流对象的方法写数据
            bw.write(s);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
    }
}

注意:说明文件的内容可能来自于集合

案例:文件到集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0HfqaJb1-1647592964179)(java.assets/image-20210624204611610.png)]

package com.itheima_05;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/*
    需求:
        把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个集合元素

    思路:
        1:创建字符缓冲输入流对象
        2:创建ArrayList集合对象
        3:调用字符缓冲输入流对象的方法读数据
        4:把读取到的字符串数据存储到集合中
        5:释放资源
        6:遍历集合
 */
public class TxtToArrayListDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("myCharStream\array.txt"));

        //创建ArrayList集合对象
        ArrayList array = new ArrayList();

        //调用字符缓冲输入流对象的方法读数据
        String line;
        while ((line=br.readLine())!=null) {
            //把读取到的字符串数据存储到集合中
            array.add(line);
        }

        //释放资源
        br.close();

        //遍历集合
        for(String s : array) {
            System.out.println(s);
        }
    }
}

案例:点名器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFh1ripx-1647592964179)(java.assets/image-20210624210526135.png)]

package com.itheima_05;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

/*
    需求:
        我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随点名器

    思路:
        1:创建字符缓冲输入流对象
        2:创建ArrayList集合对象
        3:调用字符缓冲输入流对象的方法读数据
        4:把读取到的字符串数据存储到集合中
        5:释放资源
        6:使用Random产生一个随机数,随机数的范围在:[0,集合的长度)
        7:把第6步产生的随机数作为索引到ArrayList集合中获取值
        8:把第7步得到的数据输出在控制台
 */
public class CallNameDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("idea_test\array.txt"));

        //创建ArrayList集合对象
        ArrayList array = new ArrayList();

        //调用字符缓冲输入流对象的方法读数据
        String line;
        while ((line=br.readLine())!=null) {
            //把读取到的字符串数据存储到集合中
            array.add(line);
        }
        //释放资源
        br.close();

        //使用Random产生一个随机数,随机数的范围在:[0,集合的长度)
        Random r = new Random();
        int index = r.nextInt(array.size());    
        //size()数组的长度
        //nextInt下一个伪随机、均匀分布的 int价值从这个随机数生成器的序列


        //把第6步产生的随机数作为索引到ArrayList集合中获取值
        String name = array.get(index);

        //把第7步得到的数据输出在控制台
        System.out.println("幸运者是:" + name);
    }
}

4 特殊操作流

4.1 标准输入输出流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VxN1iWWK-1647592964179)(java.assets/image-20210624215117675.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f5iICxF9-1647592964180)(java.assets/image-20210624211801925.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m49NqzRG-1647592964180)(java.assets/image-20210624211841446.png)]

标准输入流

package com.itheima_05;


import java.io.IOException;
import java.io.InputStream;

/*
    public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
 */
public class SystemInDemo {
    public static void main(String[] args) throws IOException {
        InputStream is=System.in;
        int by;
        while ((by= is.read())!=-1){
            System.out.print((char)by); //因为汉字是三个字节,这个是按照一个一个读的
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WrPlADkw-1647592964180)(java.assets/image-20210624213048269.png)]

package com.itheima_05;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/*
    public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
 */
public class SystemInDemo {
    public static void main(String[] args) throws IOException {
        // InputStream is=System.in;    //1
//        int by;
//        while ((by= is.read())!=-1){
//            System.out.print((char)by);
//        }

        //如何把字节流转换成字符流?用转换流
        //InputStreamReader isr=new InputStreamReader(is); //2
        //字符流能不能实现一次读取一行数据呢?可以
        //一次读取一行数据是字符缓冲流特有的方法
       // BufferedReader br=new BufferedReader(isr);//3
        //不过上面的三句话可以用一句来实现
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        //我们把System.in这个字节流通过转换流转换成字符流,再通过bufferreader包装成字符缓冲输入流,
        // 真正底层读数据的还是用到的是底层的字节流
        System.out.println("请输入一个字符串:");
        String line= br.readLine(); //用一个字符串来接收
        System.out.println("你输入的字符串是:"+line);
        System.out.println("请输入一个整数:");
        int i = Integer.parseInt(br.readLine());        //因为我们得到的是字符串,如果我们想要得到int类型的,就要用这个来转换
        System.out.println("你输入的整数是:" + i);

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bodg7Mis-1647592964180)(java.assets/image-20210624214909963.png)]

package com.itheima_05;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;

/*
    public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
 */
public class SystemInDemo {
    public static void main(String[] args) throws IOException {
        //自己实现键盘录入数据太麻烦了,所以Java就提供了一个类供我们使用
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String name=sc.nextLine();
        System.out.println("你输入的字符串是:"+name);
        System.out.println("请输入一个整数:");
        int i = sc.nextInt();
        System.out.println("你输入的整数是:" + i);   
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P86tNknz-1647592964181)(java.assets/image-20210624215646620.png)]

标准输出流

还有没看的:黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

讲的是标准输出流

package com.itheima_01;

import java.io.PrintStream;

/*
    public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
 */
public class SystemOutDemo {
    public static void main(String[] args) {
        //public static final PrintStream out:标准输出流
        PrintStream ps = System.out;

        //能够方便地打印各种数据值
//        ps.print("hello");
//        ps.print(100);

//        ps.println("hello");
//        ps.println(100);

        //System.out的本质是一个字节输出流
        System.out.println("hello");
        System.out.println(100);

        System.out.println();
//        System.out.print();
    }
}

4.2 打印流

字节打印流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9QNkc8Pv-1647592964181)(java.assets/image-20210628153202005.png)]

字节输出流,说明是用来写数据的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WdaxgJO6-1647592964181)(java.assets/image-20210628155049006.png)]

package com.itheima_02;

import java.io.IOException;
import java.io.PrintStream;

/*
    打印流的特点:
        只负责输出数据,不负责读取数据
        有自己的特有方法

    字节打印流
        PrintStream(String fileName):使用指定的文件名创建新的打印流
 */
public class PrintStreamDemo {
    public static void main(String[] args) throws IOException {
        //PrintStream(String fileName):使用指定的文件名创建新的打印流
        PrintStream ps = new PrintStream("myOtherStream\ps.txt");

        //写数据
        //字节输出流有的方法
//        ps.write(97);

        //使用特有方法写数据
//        ps.print(97);
//        ps.println();
//        ps.print(98);
        ps.println(97);
        ps.println(98);


        //释放资源
        ps.close();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ivl50TMx-1647592964181)(java.assets/image-20210628155329296.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7ag5Hij-1647592964182)(java.assets/image-20210628155524023.png)]

看其继承体系,继承writer,所以是字符输出流,所以我们应该看其写数据的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gOShorLN-1647592964182)(java.assets/image-20210628155545175.png)]

字符打印流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rfd07Jxb-1647592964182)(java.assets/image-20210628155736086.png)]

package com.itheima_02;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/*
    字符打印流的构造方法:
        PrintWriter(String fileName) :使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新

        PrintWriter(Writer out, boolean autoFlush):创建一个新的PrintWriter
            out:字符输出流
            autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区
 */
public class PrintWriterDemo {
    public static void main(String[] args) throws IOException {
        //PrintWriter(String fileName) :使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新
//        PrintWriter pw = new PrintWriter("myOtherStream\pw.txt");

//        pw.write("hello");
//        pw.write("
");
//        pw.flush();
//        pw.write("world");
//        pw.write("
");
//        pw.flush();

//        pw.println("hello");
        /*
            pw.write("hello");
            pw.write("
");
         */
//        pw.flush();
//        pw.println("world");
//        pw.flush();

        //PrintWriter(Writer out, boolean autoFlush):创建一个新的PrintWriter
        PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\pw.txt"),true);
//        PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\pw.txt"),false);

        pw.println("hello");
        /*
            pw.write("hello");
            pw.write("
");
            pw.flush();
         */
        pw.println("world");

        pw.close();
    }
}

案例:复制java文件(打印流改进版)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wGSzWyS8-1647592964183)(java.assets/image-20210628161338704.png)]

package com.itheima_02;

import java.io.*;

    /*
        需求:
            把模块目录下的PrintStreamDemo.java 复制到模块目录下的 Copy.java

        思路:
            1:根据数据源创建字符输入流对象
            2:根据目的地创建字符输出流对象
            3:读写数据,复制文件
            4:释放资源
    */
public class CopyJavaDemo {
    public static void main(String[] args) throws IOException {
        /*
        //根据数据源创建字符输入流对象
        BufferedReader br = new BufferedReader(new FileReader("myOtherStream\PrintStreamDemo.java"));
        //根据目的地创建字符输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("myOtherStream\Copy.java"));

        //读写数据,复制文件
        String line;
        while ((line=br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
        br.close();
        */

        //根据数据源创建字符输入流对象
        BufferedReader br = new BufferedReader(new FileReader("myOtherStream\PrintStreamDemo.java"));
        //根据目的地创建字符输出流对象
        PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\Copy.java"),true);

        //读写数据,复制文件
        String line;
        while ((line=br.readLine())!=null) {
            pw.println(line);
        }

        //释放资源//这个关闭资源好像也有顺序,就是先开的后关,后开的先关
        pw.close();
        br.close();
    }
}

4.3 对象序列化流

对象序列化流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OQZ9FBmJ-1647592964183)(java.assets/image-20210628165306177.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x48pfRfk-1647592964183)(java.assets/image-20210629102042626.png)]

package com.itheima_03;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/*
    对象序列化流
        构造方法:
            ObjectOutputStream?(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream

        序列化对象的方法:
            void writeObject?(Object obj):将指定的对象写入ObjectOutputStream

    NotSerializableException:抛出一个实例需要一个Serializable接口。 序列化运行时或实例的类可能会抛出此异常

    类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化
 */
public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //ObjectOutputStream?(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\oos.txt"));

        //创建对象
        Student s = new Student("林青霞",30);

        //void writeObject?(Object obj):将指定的对象写入ObjectOutputStream
        oos.writeObject(s);

        //释放资源
        oos.close();
    }
}



package com.itheima_03;

import java.io.Serializable;
//类要想实现序列化,必须要实现这个接口,这只是一个标识,里面没有方法要重写
public class Student implements Serializable {
    private static final long serialVersionUID = 42L;
    private String name;
//    private int age;
    private transient int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

//    @Override
//    public String toString() {
//        return "Student{" +
//                "name='" + name + ''' +
//                ", age=" + age +
//                '}';
//    }
}

对象反序列化流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7BFd041t-1647592964183)(java.assets/image-20210629103722095.png)]

package com.itheima_03;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/*
    构造方法:
        ObjectInputStream?(InputStream in):创建从指定的InputStream读取的ObjectInputStream

    反序列化对象的方法:
        Object readObject?():从ObjectInputStream读取一个对象
 */
public class ObjectInputStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //ObjectInputStream?(InputStream in):创建从指定的InputStream读取的ObjectInputStream
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\oos.txt"));

        //Object readObject?():从ObjectInputStream读取一个对象
        Object obj = ois.readObject();

        Student s = (Student) obj;
        System.out.println(s.getName() + "," + s.getAge());

        ois.close();
    }
}

还有一集

黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXIDbBxQ-1647592964184)(java.assets/image-20210626191118764.png)]

多线程

1 多线程

1.1 进程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LIKCzNLO-1647592964184)(java.assets/image-20210626160630047.png)]

1.2 线程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qVAoIUZd-1647592964184)(java.assets/image-20210626161252498.png)]

单线程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-orrQFrSD-1647592964185)(java.assets/image-20210626161458160.png)]

多线程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8X8CmI3v-1647592964185)(java.assets/image-20210626161716883.png)]

1.3 多线程的实现方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xmgosydV-1647592964185)(java.assets/image-20210626161935005.png)]

这个thread类继承object类,已经实现了runnable接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbPmbNtL-1647592964185)(java.assets/image-20211127180131709.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4mlWxAu-1647592964186)(java.assets/image-20211127180237973.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zz1nNkz1-1647592964186)(java.assets/image-20210626163339724.png)]

jvm:java虚拟机

为什么要重写run方法

因为在mythread里面有很多要执行的程序,重写run,里面只放你要运行的内容

代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aXditHyk-1647592964186)(java.assets/image-20210626163404347.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u9Fk4YaJ-1647592964186)(java.assets/image-20210626163424788.png)]

直接调用run方法,并不会启动线程,而是单纯的输出run方法中的内容罢了,要通过start方法才行

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NVzQMCss-1647592964187)(java.assets/image-20210626163247402.png)]

1.4 设置和获取线程名称*(讲源码)

黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pA4BFlu1-1647592964187)(java.assets/image-20210626172816242.png)]

package com.itheima_02;

public class MyThread extends Thread {

    public MyThread() {}

    public MyThread(String name) {
        super(name);    //调用的父类的带参构造方法
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+":"+i);
        }
    }
}

/*
private String name;

public Thread() {
    this(null, null, "Thread-" + nextThreadNum(), 0);
}

public Thread(String name) {
    this(null, null, name, 0);
}

public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
    this(group, target, name, stackSize, null, true);
}

private Thread(ThreadGroup g, Runnable target, String name,
                   long stackSize, AccessControlContext acc,
                   boolean inheritThreadLocals) {
    this.name = name;
}

public final synchronized void setName(String name) {
    this.name = name;
}

public final String getName() {
    return name;
}

private static int threadInitNumber; //0,1,2
private static synchronized int nextThreadNum() {
    return threadInitNumber++;//0,1,...
}

 */


package com.itheima_02;

/*
    Thread类中获取和设置线程名称的方法
        void setName(String name):将此线程的名称更改为等于参数 name
        String getName():返回此线程的名称
 */
public class MyThreadDemo {
    public static void main(String[] args) {
//        MyThread my1 = new MyThread();
//        MyThread my2 = new MyThread();
//
//        //void setName(String name):将此线程的名称更改为等于参数 name
//        my1.setName("高铁");
//        my2.setName("飞机");

        //Thread(String name)
//        MyThread my1 = new MyThread("高铁");
//        MyThread my2 = new MyThread("飞机");
//
//        my1.start();
//        my2.start();

        //static Thread currentThread() 返回对当前正在执行的线程对象的引用
        System.out.println(Thread.currentThread().getName());
    }
}

1.5线程调度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R8M5t1LA-1647592964187)(java.assets/image-20210626181341491.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2O1Fd1AA-1647592964187)(java.assets/image-20211129113217834.png)]

package com.itheima_03;

/*
    Thread类中设置和获取线程优先级的方法
        public final void setPriority(int newPriority):更改此线程的优先级
        public final int getPriority():返回此线程的优先级
 */
public class ThreadPriorityDemo {
    public static void main(String[] args) {
        ThreadPriority tp1 = new ThreadPriority();
        ThreadPriority tp2 = new ThreadPriority();
        ThreadPriority tp3 = new ThreadPriority();

        tp1.setName("高铁");
        tp2.setName("飞机");
        tp3.setName("汽车");

        //public final int getPriority():返回此线程的优先级
//        System.out.println(tp1.getPriority()); //5
//        System.out.println(tp2.getPriority()); //5
//        System.out.println(tp3.getPriority()); //5

        //public final void setPriority(int newPriority):更改此线程的优先级
//        tp1.setPriority(10000); //IllegalArgumentException
//        System.out.println(Thread.MAX_PRIORITY); //10
//        System.out.println(Thread.MIN_PRIORITY); //1
//        System.out.println(Thread.NORM_PRIORITY); //5

        //设置正确的优先级,线程优先级高,只能表示获取cpu时间片的几率的高,并不是每一次都会跑在最前面
        tp1.setPriority(5);
        tp2.setPriority(10);
        tp3.setPriority(1);


        tp1.start();
        tp2.start();
        tp3.start();
    }
}

1.6 线程控制

线程守护

线程休眠

线程死亡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRkGYMwP-1647592964188)(java.assets/image-20210626181551313.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NKiEXWyC-1647592964188)(java.assets/image-20210626182600690.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WFI1LGgh-1647592964188)(java.assets/image-20210626182708942.png)]

每输出一次,就要线程休眠1秒

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bbQbYPIL-1647592964188)(java.assets/image-20210626182718282.png)]


void join():等待这个线程死亡

package com.itheima_04;

public class ThreadJoin extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + ":" + i);
        }
    }
}


package com.itheima_04;
/*
    void join():等待这个线程死亡
 */
public class ThreadJoinDemo {
    public static void main(String[] args) {
        ThreadJoin tj1 = new ThreadJoin();
        ThreadJoin tj2 = new ThreadJoin();
        ThreadJoin tj3 = new ThreadJoin();

        tj1.setName("康熙");
        tj2.setName("四阿哥");
        tj3.setName("八阿哥");

        tj1.start();
        try {
            tj1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        tj2.start();
        tj3.start();
    }
}

守护线程

package dch.thread04;

public class ThreadDaemon extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + ":" + i);
        }
    }
}



package dch.thread04;

public class ThreadDaemonDemo {
    public static void main(String[] args) {
        ThreadDaemon td1=new ThreadDaemon();
        ThreadDaemon td2=new ThreadDaemon();

        td1.setName("关羽");
        td2.setName("张飞");

        //设置主线程(main)为刘备,刘备挂了,张飞关羽也能长在
        Thread.currentThread().setName("刘备");
        //设置守护线程
        td1.setDaemon(true);
        td2.setDaemon(true);

        td1.start();
        td2.start();

        for(int i=0; i<10; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ph8hrQEH-1647592964189)(java.assets/image-20210626184507885.png)]

runnable,是实现的接口,所以不能用thread类中的getname方法

首先拿到当前线程,然后再使用getname方法

不能直接使用getname方法,因为这个类没有继承thread,只是实现了runnable方法

1.7 线程的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ETYguIa-1647592964189)(java.assets/image-20210626184947619.png)]

1.8 多线程的实现方式

看jdk文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RXu8LItE-1647592964189)(java.assets/image-20210626191027283.png)]

package dch.thread05;
//通过实现接口的方式来实现多线程,不影响他再继承其他的类
public class MyRunnable implements Runnable {
//实现runnable接口,并没有继承thread类,好处:将来可以有自己的父类,
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            //这个方法会报错,因为这个类只是实现了Runnable接口,和Thread类没有关系,
            //不能直接调用Thread类中的方法
//            System.out.println(getName()+":"+i);
            //我们先拿到当前线程,然后再去拿这个名字,就可以了
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}


package dch.thread05;
/*
    方式2:实现Runnable接口
        1:定义一个类MyRunnable实现Runnable接口
        2:在MyRunnable类中重写run()方法
        3:创建MyRunnable类的对象
        4:创建Thread类的对象,把MyRunnable对象作为构造方法的参数
        5:启动线程
 */

public class MyRunnableDemo {
    public static void main(String[] args) {
        //创建myrunable类对象
        MyRunnable my=new MyRunnable();
        //创建thread类对象,把myrunnable对象作为构造方法的参数
        //Thread(Runnable target)
//        Thread t1=new Thread(my);
//        Thread t2=new Thread(my);
        //   Thread(Runnable target, String name)
        //将myRunnable实现类的对象作为参数传递,可以将myRunnable看作同一个资源,由多个线程去使用
        Thread t1=new Thread(my,"高铁"); 
        Thread t2=new Thread(my,"飞机");
    }
}

2 线程同步

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9mc22sMJ-1647592964190)(java.assets/image-20210626191336746.png)]

2.1 卖票案例的思考

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KA5Fm9oJ-1647592964190)(java.assets/image-20211129172519450.png)]

2.2 卖票案例数据安全问题的解决

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6kHLz6Nt-1647592964190)(java.assets/image-20211129173649918.png)]

2.3 同步代码块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EJVXqgaG-1647592964190)(java.assets/image-20211129174623201.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nn8HhCm4-1647592964191)(java.assets/image-20211129173938034.png)]

正确上锁方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-houzl70J-1647592964191)(java.assets/image-20211129174539755.png)]

2.4 同步方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rvWeszi8-1647592964191)(java.assets/image-20211129180337238.png)]

2.5 线程安全的类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZlicwckM-1647592964191)(java.assets/image-20211129200930557.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ez3z5HJh-1647592964192)(java.assets/image-20211129200943626.png)]

hashtable的源码中有同步代码块,所以是线程安全的类

hashmap里面的方法,没有加同步代码块,所以是线程不安全类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1IInnBYS-1647592964192)(java.assets/image-20211129201604085.png)]

这三个类都是加了

synchronized关键字的,所以是线程安全类

2.6 Lock锁

3 生产者消费者

3.1 生产者消费者模式概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1mFsppv9-1647592964193)(java.assets/image-20210627093316330.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ad03pmWS-1647592964193)(java.assets/image-20210627093416861.png)]

3.2 生产者消费者案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EiOJkyqc-1647592964193)(java.assets/image-20210627093646976.png)]

黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

4 动力节点多线程

视频链接:

Java多线程实战精讲-带你一次搞明白Java多线程高并发_哔哩哔哩_bilibili

getid获取线程编号

package com.wkcto.threadmethod.p5yield;

/**
 * @Author: 从南到北
 * @Date: 2022/01/06/12:38
 *
 *  输出线程id和名字
 */
public class SubThread5 extends Thread{

    @Override
    public void run() {
        System.out.println("currentName:"+Thread.currentThread().getName()+","+"cuttentgetID:"+this.getId());
    }

}



package com.wkcto.threadmethod.p5yield;

/**
 * @Author: 从南到北
 * @Date: 2022/01/06/13:11
 */
public class Test {
    public static void main(String[] args) {

        System.out.println(Thread.currentThread().getName()+",id="+Thread.currentThread().getId());
        //子线程

        for (int i =1;i<100;i++){
            new SubThread5().start();

            try {
                Thread.sleep(100);  //就是说可能会取相同的id
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
}

yield()使当前线程抛弃获取的CPU资源,并重新cpu分配执行权

package Donglizijie.com.wkcto.threadmehtod.p5yield;

/**
 * @Author: 从南到北
 * @Date: 2022/01/05/18:43
 */
public class SubThread6 extends Thread{

    @Override
    public void run() {

        long begin = System.currentTimeMillis();
        long sum = 0;
        for (int i=1;i<=10000000;i++){
            sum+=i;
            Thread.yield(); //线程让步,放弃cpu执行权,然后线程调度器再给他分配资源
        }

        long end = System.currentTimeMillis();
        System.out.println(Thread.currentThread().getName()+"用时:"+(end-begin));

    }
}



package Donglizijie.com.wkcto.threadmehtod.p5yield;

/**
 * @Author: 从南到北
 * @Date: 2022/01/05/18:46
 */
public class Test {
    public static void main(String[] args) {
        //开启子线程,计算累加和
        SubThread6 t6 = new SubThread6();

        t6.start();
        //在main函数中计算累加和
        long begin = System.currentTimeMillis();
        long sum=0;
        for (int i=1;i<=100000000;i++){
            sum+=i;
        }
        long end = System.currentTimeMillis();
        System.out.println("main方法,用时:"+(end-begin));
    }
}

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I6bIqxGF-1647592964194)(java.assets/image-20220106140529244.png)]

setPriority()

重点:线程间的通信

4.1 等待通知机制

在单线程编程中,要执行的操作需要满足一定的条件才能执行,可 以把这个操作放在 if 语句块中. 蛙课网【动力节点旗下品牌】 http://www.wkcto.com 在多线程编程中,可能 A 线程的条件没有满足只是暂时的, 稍后其 他的线程 B 可能会更新条件使得 A 线程的条件得到满足. 可以将 A 线 程暂停,直到它的条件得到满足后再将 A 线程唤醒.

它的伪代码:

atomics{
 //原子操作
 while(条件不成立){
	 等待 
  }
 	当前线程被唤醒条件满足后,继续执行下面的操作
 }

4.2 join()

3 TCP通信程序

3.1 TCP通信原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jZcXZdPF-1647592964194)(java.assets/image-20210625145210983.png)]

3.2 TCP发送数据(getOutputStream)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FgOgJaSj-1647592964194)(java.assets/image-20210625150606451.png)]

3.3 TCP接收数据(getInputStream)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TI09evl1-1647592964195)(java.assets/image-20210625155105747.png)]

接收数据的步骤

  1. 创建服务器端套接字对象(ServerSocket)

    ServerSocket(int port)

  2. 监听客户端连接,返回一个Socket对象

    Socket accept()

  3. 获取输入流,读数据,并把数据显示在控制台

    InputStream getInputStream()

  4. 释放资源

    void close()

只要有getinputstream和getoutputstream,就可以通过这两个来进行

Class Socket

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mtugNQUV-1647592964195)(java.assets/image-20210626135128812.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dlRdpNpx-1647592964196)(java.assets/image-20210626135232507.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eWdFkG4x-1647592964196)(java.assets/image-20210625151959332.png)]

3.4 TCP通信程序练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovikkp5b-1647592964196)(java.assets/image-20210626143219687.png)]

练习1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7jch81ui-1647592964197)(java.assets/image-20210707142924879.png)]

客户端:

package com.itheima_05;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/*
    客户端:发送数据,接收服务器反馈
 */

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的Socket对象(Socket)
        Socket s = new Socket("192.168.1.66", 10000);

        //获取输出流,写数据
        OutputStream os = s.getOutputStream();
        os.write("hello,tcp,我来了".getBytes());

        //接收服务器反馈
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String data = new String(bys, 0, len);
        System.out.println("客户端:" + data);

        //释放资源
//        is.close();
//        os.close();
        s.close();
    }
}

服务器端:

package com.itheima_05;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
    服务器:接收数据,给出反馈
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器端的Socket对象(ServerSocket)
        ServerSocket ss = new ServerSocket(10000);

        //监听客户端连接,返回一个Socket对象
        Socket s = ss.accept();

        //获取输入流,读数据,并把数据显示在控制台
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String data = new String(bys, 0, len);
        System.out.println("服务器:" + data);

        //给出反馈
        OutputStream os = s.getOutputStream();
        os.write("数据已经收到".getBytes());

        //释放资源

        ss.close();
    }
}

练习2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oAqeH7oz-1647592964197)(java.assets/image-20210707133917720.png)]

黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili****

客户端:

package com.itheima_06;

import java.io.*;
import java.net.Socket;

/*
    客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
 */

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket s = new Socket("192.168.1.66",10000);

        //数据来自于键盘录入,直到输入的数据是886,发送数据结束 ,不用scanner,用自己包装的键盘录入
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //封装输出流对象
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while ((line=br.readLine())!=null) {
            if("886".equals(line)) {
                break;
            }

            //获取输出流对象,
//            OutputStream os = s.getOutputStream();    //这是一个字节流,要转换成字符流
//            os.write(line.getBytes());
//一次写一个字符串,而不是写一个字节
            bw.write(line); //写一行
            bw.newLine();   //换行
            bw.flush(); //刷新
        }

        //释放资源
        s.close();
    }
}

服务器端:

package com.itheima_06;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/*
    服务器:接收到的数据在控制台输出
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器Socket对象
        ServerSocket ss = new ServerSocket(10000);

        //监听客户端的连接,返回一个对应的Socket对象
        Socket s = ss.accept();

        //获取输入流
//        InputStream is = s.getInputStream();
//        InputStreamReader isr = new InputStreamReader(is);
//        BufferedReader br = new BufferedReader(isr);
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

        //释放资源
        ss.close();
    }
}

练习3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OCo2plNN-1647592964197)(java.assets/image-20211220173941847.png)]

客户端和2一样不变

package com.itheima_07;

import java.io.*;
import java.net.Socket;

/*
    客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket s = new Socket("192.168.1.66",10000);

        //数据来自于键盘录入,直到输入的数据是886,发送数据结束
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //封装输出流对象
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while ((line=br.readLine())!=null) {
            if("886".equals(line)) {
                break;
            }
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        s.close();
    }
}

服务器端:

package com.itheima_07;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
    服务器:接收到的数据写入文本文件
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器Socket对象
        ServerSocket ss = new ServerSocket(10000);

        //监听客户端连接,返回一个对应的Socket对象
        Socket s = ss.accept();

        //接收数据
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        //把数据写入文本文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\s.txt"));

        String line;
        while ((line=br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
        ss.close();
    }
}

练习4

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9wmV3QFV-1647592964198)(java.assets/image-20210626160041275.png)]

就是上传文件到服务器

客户端:

package com.itheima_08;

import java.io.*;
import java.net.Socket;

/*
    客户端:数据来自于文本文件
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket s = new Socket("192.168.1.66",10000);

        //封装文本文件的数据
        BufferedReader br = new BufferedReader(new FileReader("myNet\InetAddressDemo.java"));
        //封装输出流写数据
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        String line;
        while ((line=br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        br.close();
        s.close();
    }
}

服务器不变3

package com.itheima_08;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
    服务器:接收到的数据写入文本文件
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器Socket对象
        ServerSocket ss = new ServerSocket(10000);

        //监听客户端连接,返回一个对应的Socket对象
        Socket s = ss.accept();

        //接收数据
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        //把数据写入文本文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\Copy.java"));

        String line;
        while ((line=br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
        ss.close();
    }
}

练习5(*)

黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2FSJ7ssy-1647592964198)(java.assets/image-20210626155841154.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IdAqIPCv-1647592964198)(java.assets/image-20210626155929955.png)]

服务器端:

package com.itheima_09;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
    服务器:接收到的数据写入文本文件,给出反馈
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器Socket对象
        ServerSocket ss = new ServerSocket(10000);

        //监听客户端连接,返回一个对应的Socket对象
        Socket s = ss.accept();

        //接收数据
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        //把数据写入文本文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\Copy.java"));

        String line;
        while ((line=br.readLine())!=null) { //等待读取数据
//            if("886".equals(line)) {
//                break;
//            }
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

//        System.out.println(11111);

        //给出反馈
        BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        bwServer.write("文件上传成功");
        bwServer.newLine();
        bwServer.flush();

        //释放资源
        bw.close();
        ss.close();
    }
}

客户端:

package com.itheima_09;

import java.io.*;
import java.net.Socket;

/*
    客户端:数据来自于文本文件,接收服务器反馈
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket s = new Socket("192.168.1.66",10000);

        //封装文本文件的数据
        BufferedReader br = new BufferedReader(new FileReader("myNet\InetAddressDemo.java"));
        //封装输出流写数据
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        String line;
        while ((line=br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

//        System.out.println(22222);

        //自定义结束标记
//        bw.write("886");
//        bw.newLine();
//        bw.flush();

        //public void shutdownOutput?()
        s.shutdownOutput(); //输出结束的标记

        //接收反馈
        BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String data = brClient.readLine(); //等待读取数据
        System.out.println("服务器的反馈:" + data);

        //释放资源
        br.close();
        s.close();
    }
}

练习6

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0cDznHSs-1647592964199)(java.assets/image-20211220215613005.png)]

客户端:

package com.itheima_10;

import java.io.*;
import java.net.Socket;

/*
    客户端:数据来自于文本文件,接收服务器反馈
 */

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket s = new Socket("192.168.1.66",10000);

        //封装文本文件的数据
        BufferedReader br = new BufferedReader(new FileReader("myNet\InetAddressDemo.java"));
        //封装输出流写数据
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        String line;
        while ((line=br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        s.shutdownOutput();		//如果没有这一句,那么,就代表

        //接收反馈
        BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String data = brClient.readLine(); //等待读取数据
        System.out.println("服务器的反馈:" + data);

        //释放资源
        br.close();
        s.close();
    }
}

服务器端:

package com.itheima_10;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/*
    服务器:接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //创建服务器Socket对象
        ServerSocket ss = new ServerSocket(10000);	//服务器套接字

        while (true) {
            //监听客户端连接,返回一个对应的Socket对象
            Socket s = ss.accept();	//监听客户端,
            //为每一个客户端开启一个线程
            new Thread(new ServerThread(s)).start();		//把客户端放到套接字中
        }

//        ss.close();	//一般,服务器是不会关的
    }
}

多线程

package com.itheima_10;

import java.io.*;
import java.net.Socket;

public class ServerThread implements Runnable {
    private Socket s;	//服务器套接字
    
    public ServerThread(Socket s) {		
        this.s = s;
    }
    
    @Override
    public void run() {
        try {
            //接收数据写到文本文件
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//            BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\Copy.java"));
            //解决名称冲突问题
            int count = 0;
            File file = new File("myNet\Copy["+count+"].java");
            while (file.exists()) {	//如果文件不存在,就不会触发这个循环
                count++;
                file = new File("myNet\Copy["+count+"].java");
            }
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));

            String line;
            while ((line=br.readLine())!=null) {
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
            //给出反馈
            BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            bwServer.write("文件上传成功");
            bwServer.newLine();
            bwServer.flush();
            //释放资源
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1 类加载器

1.1 类加载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0PaSUJ3-1647592964199)(java.assets/image-20210815143429416.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fXGWq2PY-1647592964199)(java.assets/image-20210815143752376.png)]

1.2 类加载器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hlaSa8NE-1647592964199)(java.assets/image-20210815143925316.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YSV8K9ER-1647592964200)(java.assets/image-20210815144224616.png)]

package com.itheima_01;

/*
    ClassLoader 中的两个方法
        static ClassLoader getSystemClassLoader?():返回用于委派的系统类加载器
        ClassLoader getParent?():返回父类加载器进行委派
 */
public class ClassLoaderDemo {
    public static void main(String[] args) {
        //static ClassLoader getSystemClassLoader?():返回用于委派的系统类加载器
        ClassLoader c = ClassLoader.getSystemClassLoader();
        System.out.println(c); //AppClassLoader

        //ClassLoader getParent?():返回父类加载器进行委派
        ClassLoader c2 = c.getParent();
        System.out.println(c2); //PlatformClassLoader

        ClassLoader c3 = c2.getParent();
        System.out.println(c3); //null
    }
}

2 反射

2.1 反射概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NOZNXaGR-1647592964200)(java.assets/image-20210815141718689.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z13OG3yj-1647592964200)(java.assets/image-20210815141818178.png)]

2.2 获取Class类的对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aL0EwLCG-1647592964200)(java.assets/image-20210815141932109.png)]

2.3 反射获取构造方法并使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SIkHBGVy-1647592964201)(java.assets/image-20210823115021793.png)]

package com.itheima_03;

import com.itheima_02.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/*
    反射获取构造方法并使用
 */
public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class c = Class.forName("com.itheima_02.Student");

        //Constructor[] getConstructors?() 返回一个包含 Constructor对象的数组, Constructor对象反映了由该 Class对象表示的类的所有公共构造函数
//        Constructor[] cons = c.getConstructors();
        //Constructor[] getDeclaredConstructors?() 返回反映由该 Class对象表示的类声明的所有构造函数的 Constructor对象的数组
        Constructor[] cons = c.getDeclaredConstructors();
        for(Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("--------");

        //Constructor getConstructor?(Class... parameterTypes) 返回一个 Constructor对象,该对象反映由该 Class对象表示的类的指定公共构造函数
        //Constructor getDeclaredConstructor?(Class... parameterTypes) 返回一个 Constructor对象,该对象反映由此 Class对象表示的类或接口的指定构造函数
        //参数:你要获取的构造方法的参数的个数和数据类型对应的字节码文件对象

        Constructor con = c.getConstructor();

        //Constructor提供了一个类的单个构造函数的信息和访问权限
        //T newInstance?(Object... initargs) 使用由此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例
        Object obj = con.newInstance();
        System.out.println(obj);

//        Student s = new Student();
//        System.out.println(s);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KNM23pe3-1647592964201)(java.assets/image-20210823133915928.png)]

2.4 反射获取构造方法并使用练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Jw8tsLe-1647592964201)(java.assets/image-20210818163838756.png)]

正常来说,不能通过私有方法创建对象,但是在反射里面可以,通过暴力反射

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-18zMWDTS-1647592964201)(java.assets/image-20210818163821196.png)]

成员变量也叫字段,file,下面这个方法,很明显是拿的所有的成员变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7C8rBPP-1647592964202)(java.assets/image-20210818164115874.png)]

练习1代码

package itheima3;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/*
    通过反射实现如下的操作:
        Student s = new Student("林青霞",30,"西安");
        System.out.println(s);
 */
public class ReflectDemo02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取Class对象
        Class c = Class.forName("itheima2.Student");
        Constructor con = c.getConstructor(String.class, int.class, String.class);
        Object obj = con.newInstance("林青霞", 30, "西安");
        System.out.println(obj);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ybELnVes-1647592964202)(java.assets/image-20210823134322584.png)]

练习2代码

package com.itheima_03;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/*
    通过反射实现如下的操作:
        Student s = new Student("林青霞");
        System.out.println(s);
 */

public class ReflectDemo03 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class c = Class.forName("com.itheima_02.Student");

        //private Student(String name)
        //Constructor getDeclaredConstructor?(Class... parameterTypes)
        Constructor con = c.getDeclaredConstructor(String.class);

        //暴力反射
        //public void setAccessible?(boolean flag):值为true,取消访问检查
        con.setAccessible(true);

        Object obj = con.newInstance("林青霞");
        System.out.println(obj);

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f0uJvRZc-1647592964202)(java.assets/image-20210823134937287.png)]

2.5 反射获取成员变量并使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IjBT21tU-1647592964203)(java.assets/image-20210819140701413.png)]

package com.itheima_04;

import com.itheima_02.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/*
    反射获取成员变量并使用
 */
public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class c = Class.forName("com.itheima_02.Student");

        //Field[] getFields?() 返回一个包含 Field对象的数组, Field对象反映由该 Class对象表示的类或接口的所有可访问的公共字段
        //Field[] getDeclaredFields?() 返回一个 Field对象的数组,反映了由该 Class对象表示的类或接口声明的所有字段
//        Field[] fields = c.getFields();
        Field[] fields = c.getDeclaredFields();
        for(Field field : fields) {
            System.out.println(field);
        }
        System.out.println("--------");

        //Field getField?(String name) 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定公共成员字段
        //Field getDeclaredField?(String name) 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定声明字段
        Field addressField = c.getField("address");

        //获取无参构造方法创建对象
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();

//        obj.addressField = "西安";

        //Field提供有关类或接口的单个字段的信息和动态访问
        //void set?(Object obj, Object value) 将指定的对象参数中由此 Field对象表示的字段设置为指定的新值
        addressField.set(obj,"西安"); //给obj的成员变量addressField赋值为西安

        System.out.println(obj);



//        Student s = new Student();
//        s.address = "西安";
//        System.out.println(s);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kpvyTQYr-1647592964203)(java.assets/image-20210819204259878.png)]

2.6 反射获取成员变量并使用练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JvymgASe-1647592964203)(java.assets/image-20210819205413809.png)]

package com.itheima_04;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/*
    练习:通过反射实现如下操作
        Student s = new Student();
        s.name = "林青霞";
        s.age = 30;
        s.address = "西安";
        System.out.println(s);
 */
public class ReflectDemo02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        //获取Class对象
        Class c = Class.forName("com.itheima_02.Student");

        //Student s = new Student();
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);

        //s.name = "林青霞";
//        Field nameField = c.getField("name"); //NoSuchFieldException: name
        Field nameField = c.getDeclaredField("name");
        //以后,当你不知道该用上面的两个哪一个时,就用下面那个,因为下面那个,无论公共私有,都可以拿到
        //而且在调方法之前,都先取消公共访问检查,就下面那个语句,这样就可以使用了    
        nameField.setAccessible(true);
        nameField.set(obj, "林青霞");
        System.out.println(obj);

        //s.age = 30;
        Field ageField = c.getDeclaredField("age");
        ageField.setAccessible(true);
        ageField.set(obj,30);
        System.out.println(obj);

        //s.address = "西安";
        Field addressField = c.getDeclaredField("address");
        addressField.setAccessible(true);
        addressField.set(obj,"西安");
        System.out.println(obj);
    }
}

2.7 反射获取成员方法并使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2kiRIUwN-1647592964203)(java.assets/image-20210819220731409.png)]

package com.itheima_05;

import com.itheima_02.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
    反射获取成员方法并使用
 */
public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class c = Class.forName("com.itheima_02.Student");

        //Method[] getMethods?() 返回一个包含 方法对象的数组, 方法对象反映由该 Class对象表示的类或接口的所有公共方法,包括由类或接口声明的对象以及从超类和超级接口继承的类
        //Method[] getDeclaredMethods?() 返回一个包含 方法对象的数组, 方法对象反映由 Class对象表示的类或接口的所有声明方法,
        //包括public,protected,default(package)访问和私有方法,但不包括继承方法
//        Method[] methods = c.getMethods();
        Method[] methods = c.getDeclaredMethods();
        for(Method method : methods) {
            System.out.println(method);
        }
        System.out.println("--------");

        //Method getMethod?(String name, Class... parameterTypes) 返回一个 方法对象,该对象反映由该 Class对象表示的类或接口的指定公共成员方法
        //Method getDeclaredMethod?(String name, Class... parameterTypes) 返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 Class对象
  
        //public void method1()
        Method m = c.getMethod("method1");

        //获取无参构造方法创建对象
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();

//        obj.m();

        //在类或接口上提供有关单一方法的信息和访问权限
        //Object invoke?(Object obj, Object... args) 在具有指定参数的指定对象上调用此 方法对象表示的基础方法
        //Object:返回值类型
        //obj:调用方法的对象
        //args:方法需要的参数
        m.invoke(obj);

//        Student s = new Student();
//        s.method1();
    }
}

2.8 反射获取成员方法并使用练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZvCuYThe-1647592964204)(java.assets/image-20210820015713345.png)]

package com.itheima_05;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
     练习:通过反射实现如下操作
        Student s = new Student();
        s.method1();
        s.method2("林青霞");
        String ss = s.method3("林青霞",30);
        System.out.println(ss);
        s.function();
 */
public class ReflectDemo02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class c = Class.forName("com.itheima_02.Student");

        //Student s = new Student();    通过无参构造方法,构造一个对象
        Constructor con = c.getConstructor();        
        Object obj = con.newInstance();     

        //s.method1();     通过对象调用方法
        Method m1 = c.getMethod("method1");
        m1.invoke(obj);     //invoke这个对象    这个是调用无参方法  

        //s.method2("林青霞");
        Method m2 = c.getMethod("method2", String.class);
        m2.invoke(obj,"林青霞");        //调用有参方法  

//        String ss = s.method3("林青霞",30);
//        System.out.println(ss);
        Method m3 = c.getMethod("method3", String.class, int.class);
        Object o = m3.invoke(obj, "林青霞", 30);    //调用有参且带有返回值的方法
        System.out.println(o);

        //s.function();
//        Method m4 = c.getMethod("function"); //报错(因为getMethod拿的是公共的方法)NoSuchMethodException: com.itheima_02.Student.function()
        Method m4 = c.getDeclaredMethod("function");    //这个是调用私有方法
        m4.setAccessible(true); //取消访问检查
        m4.invoke(obj);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OcAj3sY4-1647592964204)(java.assets/image-20210820015758316.png)]

2.9 反射练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9f6M0xpV-1647592964204)(java.assets/image-20210820194904780.png)]

练习1

package com.itheima_06;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/*
    练习1:我有一个ArrayList集合,现在我想在这个集合中添加一个字符串数据,如何实现?
 */
public class ReflectTest01 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //创建集合
        ArrayList array = new ArrayList();

//        array.add(10);
//        array.add(20);
//        array.add("hello");

        Class c = array.getClass();
        Method m = c.getMethod("add", Object.class);//因为这个方法的参数是object类型的

        m.invoke(array,"hello");
        m.invoke(array,"world");
        m.invoke(array,"java");

        System.out.println(array);
    }
}



//反射可以越过泛型检查的,获取到原始的方法所需要的参数类型,最后我们调用原始的方法的参数类型,就可以传字符串了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CVBs9oj4-1647592964205)(java.assets/image-20210820021854949.png)]

练习2

这样的就可以只通过修改配置文件即可修改调用的函数,而不用修改源程序

注解【补充】

注解入门

什么是注解

注解,有检测和约束的功能

内置注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTF8yDNi-1647592964205)(java.assets/image-20210902204647544.png)]

suppressWarning,镇压警告,

当你声明一个变量后,然后如果不适用他,他的颜色就是那种淡淡的深灰色,然后你用了之后,就变成彩色了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GAa3tPgR-1647592964205)(java.assets/image-20210902204757596.png)]

自定义注解,元注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n0658Oem-1647592964205)(java.assets/image-20210902204805439.png)]

java一些常用函数

split分割函数,用来分割字符串

tab是制表符,是

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W7w1H4po-1647592964206)(java.assets/image-20211007140335848.png)]

java中<<,>>和>>>的含义 - jason小蜗牛 - 博客园 (cnblogs.com)

double和int类型加减乘除的结果是double还是int

1 Java实现栈

栈(后进先出),

(8条消息) Java 实现栈的三种方式_大魔王的博客-CSDN博客_java 栈

Java基础关于Map(字典)的方法使用 - Cookie-Fei - 博客园 (cnblogs.com)

数据结构

时间复杂度

算法的时间与空间复杂度(一看就懂) - 知乎 (zhihu.com)

常见的时间复杂度量级有:

  • 常数阶O(1)
  • 对数阶O(logN)
  • 线性阶O(n)
  • 线性对数阶O(nlogN)
  • 平方阶O(n2)
  • 立方阶O(n3)
  • K次方阶O(n^k)
  • 指数阶(2^n)

上面从上至下依次的时间复杂度越来越大,执行的效率越来越低。

常数阶O(1)

无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1),如:

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

上述代码在执行的时候,它消耗的时候并不随着某个变量的增长而增长,那么无论这类代码有多长,即使有几万几十万行,都可以用O(1)来表示它的时间复杂度。

线性阶O(n)

这个在最开始的代码示例中就讲解过了,如:

for(i=1; i<=n; ++i)
{
   j = i;
   j++;
}

这段代码,for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的,因此这类代码都可以用O(n)来表示它的时间复杂度。

对数阶O(logN)

还是先来看代码:

int i = 1;
while(i

从上面代码可以看到,在while循环里面,每次都将 i 乘以 2,乘完之后,i 距离 n 就越来越近了。我们试着求解一下,假设循环x次之后,i 就大于 2 了,此时这个循环就退出了,也就是说 2 的 x 次方等于 n,那么 x = log2^n
也就是说当循环 log2^n 次以后,这个代码就结束了。因此这个代码的时间复杂度为:O(logn)

线性对数阶O(nlogN)

线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。

就拿上面的代码加一点修改来举例:

for(m=1; m

平方阶O(n2)

平方阶O(n2) 就更容易理解了,如果把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n2) 了。
举例:

for(x=1; i<=n; x++)
{
   for(i=1; i<=n; i++)
    {
       j = i;
       j++;
    }
}

这段代码其实就是嵌套了2层n循环,它的时间复杂度就是 O(n*n),即 O(n2)
如果将其中一层循环的n改成m,即:

for(x=1; i<=m; x++)
{
   for(i=1; i<=n; i++)
    {
       j = i;
       j++;
    }
}

那它的时间复杂度就变成了 O(m*n)

立方阶O(n3)、K次方阶O(n^k)

参考上面的O(n2) 去理解就好了,O(n3)相当于三层n循环,其它的类似。

除此之外,其实还有 平均时间复杂度、均摊时间复杂度、最坏时间复杂度、最好时间复杂度 的分析方法,有点复杂,这里就不展开了。

空间复杂度

既然时间复杂度不是用来计算程序具体耗时的,那么我也应该明白,空间复杂度也不是用来计算程序实际占用的空间的。

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,我们用 S(n) 来定义。

空间复杂度比较常用的有:O(1)、O(n)、O(n2),我们下面来看看:

  1. 空间复杂度 O(1)

如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)
举例:

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)

  1. 空间复杂度 O(n)

我们先看一个代码:

int[] m = new int[n]
for(i=1; i<=n; ++i)
{
   j = i;
   j++;
}

这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,这段代码的2-6行,虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)

链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-biFcyJhz-1647592964206)(java.assets/image-20220108212225831.png)]

data是数据域

next是指针域

头节点:不存储数据,是链表的入口

链表是一种存储数据的格式,每个节点的值才是最重要的

ASCII码

1-10

48-57

A-Z

65-90

a-z

97-122

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HbTrKO5j-1647592964206)(java.assets/image-20220108164416738.png)]

队列

java 队列_dd_Mr的博客-CSDN博客

用链表实现队列,先进先出,画个图就明白了

实现思路

链表的尾部插入元素,头部删除元素,故需要尾节点,不需要每次都找尾部

//队列代码
import java.util.Iterator;
 
public class Queue implements Iterable{
    //记录首结点
    private Node head;	//头节点不允许类外部访问,只能由类内部函数来操作
    //记录最后一个结点
    private Node last;	
    //记录队列中元素的个数
    private int N;
 
    public Queue() {
        head = new Node(null,null);
        last=null;
        N=0;
    }
 
    //判断队列是否为空
    public boolean isEmpty(){
        return N==0;
    }
 
    //返回队列中元素的个数
    public int size(){
        return N;
    }
 
    //向队列中插入元素t
    public void enqueue(T t){
         //分两种情况,第一次插入
        //即当前尾节点为null
        if (last==null){
            last = new Node(t,null);
            head.next=last;
        }else{
              //当前尾节点不为null
            Node oldLast = last;
            last = new Node(t,null);
            oldLast.next=last;
        }		
        //个数+1
        N++;
    }
 
    //从队列中拿出一个元素
    public T dequeue(){
        if (isEmpty()){
            return null;
        }
 
        Node oldFirst = head.next;
        head.next = oldFirst.next;
        N--;
        if (isEmpty()){
            last=null;
        }
        return oldFirst.item;
    }
 	
    @Override
    public Iterator iterator() {
        return new QIterator();
    }
 
    private class QIterator implements Iterator{
        private Node n = head;
 
        @Override
        public boolean hasNext() {
            return n.next!=null;
        }
 
        @Override
        public T next() {
            Node node = n.next;
            n = n.next;
            return node.item;
        }
    }
 
    private class Node{
        public T item;
        public Node next;
 
        public Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
    }
}

}

你可能感兴趣的:(java,后端,java,后端)