由浅到深认识Java语言(36):I/O流

news2024/9/28 17:35:09

该文章Github地址:https://github.com/AntonyCheng/java-notes

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识Java语言(35):File类

44.I/O流(操作文件中的数据)

相关概念

I/O流:Input/Output;

I/O作用是将数据从一个设备中流入另一个设备中,比如从磁盘流向内存,从磁盘流向移动存储设备,从一台计算机流向另一台计算机;

I/O流中的数据都是字节,任何数据文件都由字节组成,字节是计算机中最小的存储单元;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

I/O流对象的分类

按照操作的文件类型分类

  • 文件类型文件 – 选择流对象字符流
    • 什么是文本文件:使用文本工具(记事本,notepad++,editplus等)打开这个文件能够直接“阅读”的文件;
  • 非文件类型文件 – 选择流对象字节流

按照数据流向分类

  • 输入流:Java 程序从其他地方读取数据;
  • 输出流:Java 程序中的数据写入到其他地方;

I/O流对象的分类归纳

  • 字节输出流:OutputStream 抽象超类
  • 字节输入流:InputStream 抽象超类
  • 字符输出流:Writer 抽象超类
  • 字符输出流:Reader 抽象超类

字节流

字节输出流

OutputStream 是所有字节输出流的超类,是一种全能的输出流,可以写入任何类型的文件;

写入字节的方法 write()

  • void write(int b) 写入单个字节,参数给到的是 int ,但是会被转型为 byte ,所以数据范围应该在 -128~127;
  • void write(byte[] b) 写入字节数组;
  • void write(byte[] b,int startIndex,int len) 写入数组的一部分,开始索引,写入的个数;常常用于文件的复制操作;
FileOutputStream 实现类

构造方法:

  • FileOutputStream(File file)
  • FileOutputStream(String file)
    • 创建字节输出流对象,绑定参数就是要写入的数据目的地;
    • 如果数据目的地不存在,那么就会创建这样一个数据目的地并且写入数据,如果数据目的地存在,那么就会覆盖原有的数据目的地中的数据;

JVM 很聪明,任何一个操作系统都具有 IO 设备,但是 JVM 没有,因为它是依靠操作系统来实现 IO 功能的,所以当 IO 对象使用完毕后要记得释放资源(对象名.close());

字节输出流写入文件的步骤:

  • 创建字节输出流对象,构造方法中需要绑定文件的路径;

  • 调用流对象的方法 write() 写入数据;

  • 释放资源;

    示例如下:

    package top.sharehome.Demo;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo {
        public static void main(String[] args) throws IOException {
            File f = new File("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            FileOutputStream fos = new FileOutputStream(f);
            byte[] arr = new byte[]{97,98,99,100,101,102};
            boolean exists = f.exists();
            if (exists){
                fos.write(49);
                fos.write(50);
                fos.write(51);
                fos.write(arr);
                fos.write(arr,0,3);
            }
            fos.close();
        }
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    还可以利用字符串中的 getBytes() 方法将字符串转换成 byte[];

    package top.sharehome.Demo;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo {
        public static void main(String[] args) throws IOException {
            File f = new File("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            FileOutputStream fos = new FileOutputStream(f);
            boolean exists = f.exists();
            if (exists){
                fos.write("你好 Java".getBytes());
            }
            fos.close();
        }
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

追加写入和换行:

  • 追加写入,即 FileOutputStream 构造方法的第二个参数写 true;

    package top.sharehome.Demo;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo {
        public static void main(String[] args) throws IOException {
            FileOutputStream fosWrite = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            FileOutputStream fosCover = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt",true);
            fosWrite.write(97);
            fosWrite.write(98);
            fosWrite.write(99);
            fosCover.write(100);
            fosCover.write(101);
            fosCover.write(102);
            fosCover.close();
            fosWrite.close();
        }
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 换行写入,使用 Windows 系统的换行符号 \r(换行符) \n(回车符)

    示例如下:

    package top.sharehome.Demo;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Demo {
        public static void main(String[] args) throws IOException {
            FileOutputStream fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            byte[] bytes = new byte[]{97,98,99,'\n','\r',100,101,102};
            fos.write(bytes);
            fos.close();
        }
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

字节输出流异常处理

其实以上的示例都存在不恰当异常处理的情况,由于 JVM 借用了 OS 的 IO 功能,所以 JVM 向上抛的异常处理方式并不是一个明智的选择,所以应该选择 try……catch……finally…… 的异常处理方式将其就地处理掉;

异常主要有两个:

  1. FileOutputStream 对象创建失败后的空指针异常;
  2. 以及 FileOutputStream 创建时的 IO 流异常;

示例如下:

package top.sharehome.Demo;

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

public class Demo {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        //这个 try 是为了处理IO流异常
        try {
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            fos.write("字节输出流异常处理".getBytes());
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //这个 try 也是为了处理IO流异常
            try {
                //这个 if 是为了防止空指针异常输出
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

字节输入流

InputStream 是所有字节输入流的超类,是一种全能的输入流,可以读取任何类型的文件;

读取字节的方法 read()

  • int read() 读取单个字节,同一个对象的连续 read() 方法会接连读取内容,每次读取返回一个 int 类型值,如果读取到流的末尾就返回 -1,该方法不能正常读取中文,因为一个中文字符所占大小不止一个字节
  • int read(byte[] b) 读取字节数组,同一个对象的连续 read(byte[] b) 方法会接连读取内容并返回读取到的字节个数,同时 byte[] 数组中的会被新读取到的内容所覆盖,如果读取到流的末尾就返回 -1,通常我们要将 byte[] 数组设置成 1024 的整数倍
FileInputStream 实现类

构造方法:

  • FileInputStream(File file)
  • FileInputStream(String file)
    • 创建字节输入流对象,绑定参数就是要读取的数据源文件;
    • 字节流输入流和输出流的方法使用几乎一样;

方法示例如下:

  • int read() 读取单个字节,返回一个 int 类型值;

    (文件中内容是 abc)

    package top.sharehome.Demo;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class Demo {
        public static void main(String[] args) {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
                int r = 0;
                while ((r = fis.read()) != -1) {
                    System.out.println("r= "+r);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • int read(byte[] b) 读取字节数组;

    (文件中内容是 abcdefghi)

    package top.sharehome.Demo;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class Demo {
        public static void main(String[] args) {
            FileInputStream fis = null;
            byte[] arr = new byte[1024];
            try {
                fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
                int i;
                while ((i = fis.read(arr)) != -1) {
                    System.out.println("i = " + i);
                    System.out.println("new String(arr) = " + new String(arr));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    由于原理是 byte[] 数组覆盖后输出,最后一次只读取到了一个 i 字母,所以仅仅只覆盖上一次所读取到的 g 的位置,而 h 的位置保持不变;

    为了不出现以上的情况,我们又要运用 String 类当中的重载方法 String(转换的数组,开始索引,转换的个数)

    package top.sharehome.Demo;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class Demo {
        public static void main(String[] args) {
            FileInputStream fis = null;
            byte[] arr = new byte[1024];
            try {
                fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
                int i;
                while ((i = fis.read(arr)) != -1) {
                    System.out.println("i = " + i);
                    System.out.println("new String(arr) = " + new String(arr, 0, i));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

文件复制

实现文件的复制功能,和操作系统中的 Ctrl+c,Ctrl+v 一样,原理上就是字节的流动;

我们可以用单个字节输入输出流完成它,假设从 test1.txt 提取内容 123test2.txt 中:

package top.sharehome.Demo;

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

public class Demo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test1.txt");
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test2.txt");
            int flag = 0;
            while ((flag = fis.read()) != -1) {
                fos.write(flag);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

但是这种单个字节复制文件方法是不明智的,较小的文件可以这样,但是一旦文件内存较大,该方法的效率就显得极其低下;

举例如下:

以下是 test3.txt 文件内容,有20000+行内容,我们写程序来验证一下所花费时间;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

package top.sharehome.Demo;

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

public class Demo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test3.txt");
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test2.txt");
            int flag = 0;
            while ((flag = fis.read()) != -1) {
                fos.write(flag);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("end-start = " + (end - start));
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

足足用了 13 秒,效率极低!所以我们要考虑运用到字节数组去完成这一复制动作!

package top.sharehome.Demo;

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

public class Demo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        byte[] arr = new byte[1024];
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test3.txt");
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test2.txt");
            int flag = 0;
            while ((flag = fis.read(arr)) != -1) {
                fos.write(arr,0,flag);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("end-start = " + (end - start));
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显然,速度要快很多,这样的数组也就是字节流缓冲流的原理;

字节流的缓冲流

使用字节流的缓冲流,提高原有流对象的读写性能;

字节流缓冲区流,流的本质上也是字节流;

  • BufferedOutputStream 继承自 OutputStream;
    • 方法 write() 写入单个的字节,或者是字节数组;
  • BufferedInputStream 继承自 InputStream;
    • 方法 read() 读取单个的字节,或者是字节数组;

Buffered 开头的流被称为缓冲流,FileOutputStream 基础流;这些类的构造器需要传入基础流,传入什么基础流,那就对什么基础流进行高效处理,如果没有基础流,那么这个类就无意义,这样的类设计也有一个特殊的设计模式名称——装饰者,关闭流时仅关闭装饰者即可;

BufferedOutputStream 构造方法

new BufferedOutputStream(OutputStream out) 传递字节输出流;

BufferedInputStream 构造方法

new BufferedInputStream(InputStream in) 传递字节输入流;

字节缓冲流实现文件复制
package top.sharehome.Demo;

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test3.txt");
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test2.txt");
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            byte[] arr = new byte[1024];
            int flag = 0;
            while ((flag = bis.read(arr)) != -1) {
                bos.write(arr, 0, flag);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("(end-start) = " + (end - start));
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

再次相比普通数组的文件复制,这又是一次巨大的优化;

下一章:由浅到深认识Java语言(37):I/O流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1550867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++中 eigen(一)建造向量

快速上手: https://eigen.tuxfamily.org/dox/group__QuickRefPage.html 文档: https://eigen.tuxfamily.org/dox/index.html Constructors 建造 向量 Vectors 向量 例如,方便的 typedef Vector3f 是一个包含 3 个浮点数的(列&a…

Spring用到了哪些设计模式?

目录 Spring 框架中⽤到了哪些设计模式?工厂模式单例模式1.饿汉式,线程安全2.懒汉式,线程不安全3.懒汉式,线程安全4.双重检查锁(DCL, 即 double-checked locking)5.静态内部类6.枚举单例 代理模…

15K star!一款功能强悍的手机电脑同屏工具,开源无需root!

在日常工作、生活场景中,经常会遇到需将手机与电脑屏幕进行共享。 今天就给大家推荐一款Android实时投屏神器:QtScrcpy。 它可以通过 USB / 网络连接Android设备,并进行显示和控制,且无需root权限。 1、简介 QtScrcpy是一款功…

nginx代理解决跨域问题

文章目录 一、什么是跨域、跨域问题产生的原因二、注意事项三、nginx代理解决总结 一、什么是跨域、跨域问题产生的原因 跨域(Cross-Origin)是指在 Web 开发中,一个网页的运行脚本试图访问另一个网页的资源时,这两个网页的域名、…

微信开发者工具接入短剧播放器插件

接入短剧播放插线 申请添加插件基础接入app.jsonapp.jsplayerManager.js数据加密跳转到播放器页面运行出错示例小程序页面页面使用的方法小程序输入框绑定申请添加插件 添加插件:登录微信开发者平台 ——> 设置 ——> 第三方设置 ——> 插件管理 ——> 搜索“短剧…

springboot多模块

这里springboot使用idea中的 Spring Initializr 来快速创建。 一、demo 1、创建父项目 首先使用 Spring Initializr 来快速创建好一个父Maven工程。然后删除无关的文件,只需保留pom.xml 文件。 (1)new Project -> spring initializr快…

FPGA时钟资源详解(1)——时钟Buffer的选择

FPGA时钟系列文章总览:FPGA原理与结构(14)——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 目录 一、概述 二、时钟Buffer的选择 2.1 BUFG 2.2 BUFR 和 BUFIO 2.2.1 源同步接口的支持 2.2.2 扩展时钟域…

StringRedisTemplate与RedisTemplate详解【序列化的方式不同】

spring 封装了 RedisTemplate 对象来进行对redis的各种操作&#xff0c;它支持所有的 redis 原生的 api。在RedisTemplate中提供了几个常用的接口方法的使用&#xff0c;分别是: private ValueOperations<K, V> valueOps; private HashOperations<K, V> hashOps; …

Python-open3d点云配准

文章目录 ICP算法鲁棒核ICP测试 ICP算法 ICP, 即Iterative Closest Point, 迭代点算法。 ICP算法有多种形式&#xff0c;其中最简单的思路就是比较点与点之间的距离&#xff0c;对于点云 P { p i } , Q { q i } P\{p_i\}, Q\{q_i\} P{pi​},Q{qi​}而言&#xff0c;如果二者…

《Mahjong Bump》

Mahjong Bump 类型&#xff1a;Tile 三消 视角&#xff1a;2d 乐趣点&#xff1a;清空杂乱快感&#xff0c;轻松的三合一休闲 平台&#xff1a;GP 时间&#xff1a;2021 个人职责&#xff1a; 所有程序部分开发 上架 GooglePlay 相关工做 针对游戏数据做出分析&#xff0c;讨论…

Keil5快速使用

注册机链接如下 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;xim0 --来自百度网盘超级会员V4的分享 ① 打开Keil5软件 ② 在打开的对话框中复制自己软件的ID&#xff0c;然后粘贴到注册机对应的位置。 ③ 复制到注册机中后点击Generate&#xff08;注意&…

keil:syntax error near?这个报错怎么改?

我第一次学的编程语言是java&#xff0c;当时用eclipse开发环境&#xff0c;后面没学成&#xff0c;转成单片机。 刚开始学51单片机的时候&#xff0c;从强大的开发工具eclipse转变到像远古石器一样的Keil&#xff0c;还是挺不习惯的。 除了不会自动补全之类的基础功能以外&…

PostgreSQL FDW(外部表) 简介

1、FDW: 外部表 背景 提供外部数据源的透明访问机制。PostgreSQL fdw(Foreign Data Wrapper)是一种外部访问接口,可以在PG数据库中创建外部表,用户访问的时候与访问本地表的方法一样,支持增删改查。 而数据则是存储在外部,外部可以是一个远程的pg数据库或者其他数据库(…

Linux基础IO(操作系统层面理解文件)

目录 一、认识 open 函数 1.1 理解文件 1.2 open 函数 1.3 函数选项和宏 二、 open 函数的返回值 三、 fd 的本质 3.1 各部分内容及关系 3.2 如何确定进程对应文件 四、Linux 一切皆文件&#xff1f; 一、认识 open 函数 在C语言中学习文件操作时&#xff0c;我们学…

基于java+springboot+vue实现的超市在线销售系统(文末源码+Lw+ppt)23-356

摘 要 当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统超市在线销售采取了人工的管理方法&a…

MYSQL8.0安装、配置、启动、登入与卸载详细步骤总结

文章目录 一.下载安装包1.方式一.官网下载方式二.网盘下载 二.解压安装三.配置1.添加环境变量 三.验证安装与配置成功四.初始化MYSQL五.注册MySQL服务六.启动与停止MYSQL服务七.修改账户默认密码八.登入MySQL九.卸载MySQL补充&#xff1a;彻底粉碎删除Mysql 一.下载安装包 1.方…

ZC706+AD9361 运行 open WiFi

先到github上下载img&#xff0c;网页链接如下&#xff1a; https://github.com/open-sdr/openwifi?tabreadme-ov-file 用win32 Disk lmager 把文件写入到SD卡中&#xff0c;这一步操作会把SD卡重新清空&#xff0c;注意保存数据。这个软件我会放在最后的网盘链接中 打开linu…

宁波IATF16949质量管理认证体系如何认证?

&#x1f436;在当今竞争激烈的&#x1f338;汽车市场中&#xff0c;质量已成为企业&#x1f469;‍❤️‍&#x1f48b;‍&#x1f468;生存和发展的关键。IATF16949质量管理认证体系&#x1f34e;作为国际汽车行业认可的&#x1f33a;质量管理标准&#xff0c;已成为企业&…

IDEA设置代码自动提示不区分大小写

1. 打开设置 在 IntelliJ IDEA 中&#xff0c;点击顶部菜单栏的 File–>Settings&#xff08;或者使用快捷键 Ctrl Alt S&#xff09;。 2. 进入设置&#xff1a; 在弹出窗口左侧导航栏中选择 Editor --> General --> Code Completion&#xff0c;取消勾选 “Mat…

机器学习中的 K-Means算法及其优缺点(包含Python代码样例)

目录 一、简介 二、优缺点介绍 三、Python代码示例 四、总结 一、简介 K-Means算法是一种经典的无监督学习算法&#xff0c;用于将数据集中的样本分为 K 个不同的类别。K-均值聚类算法的工作原理如下&#xff1a; 随机选择 K 个中心点作为初始聚类中心。将每个样本点分配…