用静态工厂方法代替构造器
用静态工厂方法来代替构造方法。
public class Student {private String name;private int age;private String studentId;private Student(String name, int age, String studentId) {this.name = name;this.age = age;this.studentId = studentId;}public static Student createStudent(String name, int age, String studentId) {// 在静态工厂方法中执行一些额外的逻辑// 例如参数验证、生成默认的学生ID等// 调用私有构造器创建学生对象return new Student(name, age, studentId);}// Getter 和 Setter 方法...}
静态工厂方法相较于构造方法的五个优点:
- 有自己的名称,而构造方法必须与类名一致。
- 不用每次被调用时都会创建一个新的对象,它可以返回预先构造好的对象。
- 可以返回所声明的返回类型的任何子类型的对象。
- 所返回对象的类可以输入的参数不同而改变。
- 在编写包含该方法的类时,所返回对象的类并不一定存在。
缺点:
- 如果没有共有的或者受保护的构造方法,就无法为这些类创建子类。(因祸得福)
- 在API文档中可能会很难发现这个方法。(无伤大雅)
下面来详细谈一谈每一个优缺点:
优点一:
静态工厂方法有自己的名称,而构造方法必须与类名一致:
import java.time.LocalDate;public class DateUtils {private DateUtils() {// 私有构造方法,防止实例化}public static LocalDate createToday() {// 创建表示当前日期的对象return LocalDate.now();}public static LocalDate createDate(int year, int month, int day) {// 创建指定年月日的日期对象return LocalDate.of(year, month, day);}
}
优点二:
静态工厂方法不用每次被调用时都会创建一个新的对象,它可以返回预先构造好的对象:
单例模式(Singleton Pattern)是一种创建型设计模式,旨在确保类只有一个实例,并提供全局访问点以访问该实例。
单例模式的主要特点是:
- 保证类只有一个实例:通过限制类的实例化过程,确保在程序运行期间只存在一个实例对象。
- 全局访问点:提供一个全局的访问方法,使其他对象可以方便地获取该单例实例。
使用单例模式的主要优点包括:
- 对资源的集中管理:单例模式可以集中管理某些共享的资源,确保资源的一致性和可靠性。
- 节约系统资源:由于只有一个实例存在,可以减少系统开销,节约内存和处理器等资源。
- 简化对象之间的通信:通过单例对象,可以简化对象之间的通信,避免了传递多个对象引用的复杂性。
常见的单例模式实现方式有两种:它们的区别在于对象的创建时间点不同。
饿汉模式(Eager Initialization):
- 在类加载时就创建并初始化单例对象。
- 对象在整个生命周期中都存在,无论是否被使用。
- 线程安全,不需要考虑多线程环境。
- 简单直接,但可能导致资源浪费。
懒汉模式(Lazy Initialization):
- 在需要时才创建并初始化单例对象。
- 对象在首次使用时创建,延迟了对象的实例化时间。
- 需要考虑多线程环境下的线程安全性。
- 在多线程环境下可能需要额外的同步机制,可能会影响性能。
// 饿汉模式
public class Singleton {private static Singleton instance = new Singleton();private Singleton() {// 私有构造函数}public static Singleton getInstance() {return instance;}// 其他方法...
}
// 懒汉模式
public class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}// 其他方法...
}
优点三:
静态工厂方法可以返回所声明的返回类型的任何子类型的对象:
举个例子:createShape静态工厂方法声明的返回值类型是Shape,但它却可以返回Shape的子类型Circle和Square。
public class Shape {private String name;private Shape(String name) {this.name = name;}public String getName() {return name;}public static Shape createShape(String name) {if (name.equalsIgnoreCase("circle")) {return new Circle();} else if (name.equalsIgnoreCase("square")) {return new Square();} else {return new Shape(name);}}
}public class Circle extends Shape {public Circle() {super("Circle");}
}public class Square extends Shape {public Square() {super("Square");}
}
java.util.Collections
是 Java 标准库中提供的一个实用类,它包含了一系列静态方法,用于操作和处理集合类(如 List、Set、Map 等)的工具方法。这些方法包括创建不可修改的集合、集合的排序、查找元素、线程安全包装等,其中的很多方法也是返回了所声明的类型的子类型。以下是一些
java.util.Collections
类中常用的静态工厂方法:
创建不可修改的集合(Immutable Collections):
emptyList()
:返回一个空的不可修改的List
。emptySet()
:返回一个空的不可修改的Set
。emptyMap()
:返回一个空的不可修改的Map
。unmodifiableList(List<? extends T> list)
:返回一个不可修改的List
,基于指定的列表。unmodifiableSet(Set<? extends T> set)
:返回一个不可修改的Set
,基于指定的集合。unmodifiableMap(Map<? extends K, ? extends V> map)
:返回一个不可修改的Map
,基于指定的映射。集合的排序和查找:
sort(List<T> list)
:对指定的列表进行原地排序(升序)。reverse(List<T> list)
:反转指定列表中元素的顺序。shuffle(List<T> list)
:随机打乱指定列表中元素的顺序。binarySearch(List<? extends Comparable<? super T>> list, T key)
:二分查找指定列表中的元素。binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
:使用自定义比较器进行二分查找。线程安全的集合包装:
synchronizedList(List<T> list)
:返回一个线程安全的List
,基于指定的列表。synchronizedSet(Set<T> set)
:返回一个线程安全的Set
,基于指定的集合。synchronizedMap(Map<K,V> map)
:返回一个线程安全的Map
,基于指定的映射。这些静态工厂方法提供了方便的方式来创建和操作集合对象,简化了集合操作的代码实现。它们充分利用了 Java 泛型和静态方法的特性,提供了类型安全和易用性。
优点四:
静态工厂方法所返回对象的类可以输入的参数不同而改变:
在Java中,RegularEnumSet和JumboEnumSet是EnumSet的两个内部实现类。它们都是用于存储枚举类型元素的集合。
RegularEnumSet:
- RegularEnumSet是EnumSet的默认实现类。
- 它使用一个位向量(bit vector)来表示集合中的元素。
- 当枚举类型的元素数量较少时(通常在64个或更少),RegularEnumSet会被使用。
- RegularEnumSet的内部使用了long类型的数组,每个位表示一个枚举元素的存在与否。这种紧凑的表示形式使得RegularEnumSet在性能和内存消耗方面表现优异。
JumboEnumSet:
- 当枚举类型的元素数量超过64个时,EnumSet会使用JumboEnumSet作为其内部实现。
- JumboEnumSet使用一个BitSet来表示集合中的元素。
- BitSet是一个更大的位向量,它可以支持更多的枚举元素。
- JumboEnumSet以较高的内存消耗为代价,提供了对大型枚举集合的支持。
在大多数情况下,你不需要直接使用RegularEnumSet或JumboEnumSet,而是通过EnumSet的静态工厂方法来创建EnumSet对象。EnumSet会根据枚举类型的元素数量自动选择使用适当的内部实现类。
优点五:
静态工厂方法在编写包含该方法的类时,所返回对象的类并不一定存在:
在JDBC(Java数据库连接)中的服务提供者框架是一个典型的例子,其中静态工厂方法可以返回对象的类在编写包含该方法的类时并不一定存在。
在JDBC中,服务提供者框架用于加载和管理数据库驱动程序。驱动程序供应商可以通过实现特定接口并提供驱动程序的实现来注册其驱动程序。服务提供者框架允许应用程序通过静态工厂方法获取适当的驱动程序实例,而无需显式引用特定的驱动程序类。
下面是一个简化的示例,展示了JDBC服务提供者框架的代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;public class JDBCProviderFramework {// 私有构造函数,防止实例化private JDBCProviderFramework() {}// 静态工厂方法,返回数据库连接对象public static Connection getConnection(String url, String username, String password) throws SQLException {// 加载并注册合适的数据库驱动程序try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {throw new SQLException("Failed to load database driver");}// 获取数据库连接return DriverManager.getConnection(url, username, password);}
}public class Main {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydb";String username = "root";String password = "password";try {Connection connection = JDBCProviderFramework.getConnection(url, username, password);// 使用数据库连接执行操作// ...} catch (SQLException e) {e.printStackTrace();}}
}
在上述示例中,JDBCProviderFramework
类是服务提供者框架的一部分。它包含一个私有构造函数和一个静态工厂方法 getConnection()
,用于获取数据库连接对象。
在 getConnection()
方法中,首先使用 Class.forName()
方法加载并注册合适的数据库驱动程序,这里以MySQL驱动程序为例。然后,通过 DriverManager.getConnection()
方法获取数据库连接对象,并将其返回。
在 Main
类的 main()
方法中,我们使用 JDBCProviderFramework.getConnection()
方法获取数据库连接对象,并在实际应用程序中使用该连接对象执行数据库操作。
这里的关键是,在编写 JDBCProviderFramework
类时,并没有显式引用或依赖于特定的数据库驱动程序类。相反,通过使用服务提供者框架和静态工厂方法,可以在未来动态加载和使用不同的数据库驱动程序,而无需修改 JDBCProviderFramework
类的代码。
这种设计允许在未来定义或扩展返回的对象类(即不同的数据库驱动程序),以适应新的数据库技术或供应商。通过配置和动态加载,应用程序可以灵活地选择和切换不同的数据库驱动程序,而不需要修改主要的代码逻辑。
这个例子展示了静态工厂方法在JDBC服务提供者框架中的应用,其中返回的对象的类在编写包含该方法的类时并不一定存在,而是根据具体的实现在运行时动态加载和使用。
这个太难理解了,感兴趣的读者可以去了解一下服务提供者框架!!
缺点一:
静态工厂方法因为没有共有的或者受保护的构造方法,就无法为这些类创建子类。(因祸得福)
静态工厂方法的一个特点是通过私有构造函数来限制实例化,因此没有公有或受保护的构造方法。这导致无法直接创建该类的子类,从而在一定程度上确保了类的封装性和不可继承性。
这种限制有时也可以被视为一种优势,因为它可以防止不必要或不合适的继承。静态工厂方法可以在类的实现中隐藏构造函数,将对象的创建控制权交给工厂方法,从而提供更精确的控制和灵活性。
尽管无法直接创建子类,但可以通过其他方式实现类似的扩展和定制。以下是一些常见的方法:
组合和委派:使用静态工厂方法返回的对象作为另一个类的成员,并将其方法暴露给外部使用。这样可以通过组合和委托的方式实现类似于继承的行为。
接口实现:通过实现接口,可以创建新的类并使用静态工厂方法返回的对象作为实现接口的一部分。这样可以扩展原始类的功能并定制行为。
静态工厂方法的参数化:静态工厂方法可以接受参数,并根据参数的不同返回不同的对象实例。通过合理设计参数,可以实现类似于子类化的效果。
虽然静态工厂方法限制了直接子类的创建,但可以通过以上方法实现类似的效果,并同时提供更好的灵活性和控制性。这种设计可以避免一些继承带来的问题,使代码更加清晰、可维护和可扩展。
缺点二:
在API文档中可能会很难发现这个方法。(无伤大雅)
静态工厂方法的命名方法没有固定的规范,但通常遵循一些常见的命名约定和惯例。以下是一些常见的命名方法:
of
或valueOf
:这是一种常见的命名模式,用于表示通过给定的参数创建对象实例。例如:of()
,valueOf()
,getInstance()
,create()
等。
from
:这种命名模式用于表示从给定的参数或源对象中创建对象实例。例如:from()
,fromX()
,fromXyz()
等。
newInstance
或newX
:这种命名模式用于表示创建新的对象实例。例如:newInstance()
,newX()
,newXyz()
等。
getX
:这种命名模式用于表示获取对象的实例,通常与工厂方法所创建的对象具有某种关联关系。例如:getX()
,getXyz()
,getXByY()
等。
createX
或buildX
:这种命名模式用于表示创建对象实例,通常与构建复杂对象或对象图相关。例如:createX()
,buildX()
,createXyz()
,buildXyz()
等。这些只是一些常见的命名方法示例,具体的命名方式可以根据项目的需求和团队的约定进行选择。重要的是选择一个能清晰表达方法意图和用途的命名,使代码易于阅读和理解。
此外,为了提高代码的可读性和一致性,建议在命名静态工厂方法时遵循一些通用的命名约定,例如使用驼峰命名法、使用具体和清晰的命名等。
相关文章:
用静态工厂方法代替构造器
用静态工厂方法来代替构造方法。 public class Student {private String name;private int age;private String studentId;private Student(String name, int age, String studentId) {this.name name;this.age age;this.studentId studentId;}public static Student creat…...
Discourse 最多允许有几个分类级别
和 DISCUZ 不同,DISCUZ 可以允许分类下面还有分类,再继续分类这种嵌套式分类。 Discourse 最多只允许有 2 个分类。 如果你在已有的分类下再继续分类的话,系统会提示错误: 意思就是子分类不能再分子分类。 Discourse 尽量采取了…...
MySQL数据库主从复制和读写分离
MySQL数据库主从复制和读写分离 。## MySQL主从复制 MySQL主从复制的概念 MySQL主从复制是一个异步的数据复制过程,允许将一个MySQL服务器(主服务器)上的数据复制到一个或多个MySQL服务器(从服务器)。主从复制提供了…...
rust - 使用log4rs打印日志
本文提供了一种通过log4rs库记录日志的方法。这里没有采用读取yaml文件的方式,而是通过对象构造的方式来初始化日志,用于发包时不带配置文件的场景。 初始化日志 在release环境,仅需要将日志打印到文件中,而日常开发时ÿ…...
数据结构:单调栈和单调队列
文章目录 一、单调栈1.1、栈的思想1.2、单调栈1.2.1、单调栈的基本应用:找出数组中每个元素右侧第一个更大的元素1.2.2、单调栈的基本应用:找出数组中每个元素左侧第一个更大的元素1.2.3、单调栈拓展1.2.4、单调栈LeetCode题单 二、单调队列2.1、队列的思…...
大模型RAG性能提升路径
大模型相关目录 大模型,包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步,扬帆起航。 大模型应用向开发路径:AI代理工作流大模型应用开发实用开源项目汇总大模…...
机器视觉学习(九)—— 边缘检测
目录 一、边缘检测 1.1 Canny边缘检测 1.1.1 cv2.Canny函数 1.1.2 Canny边缘检测示例 1.2 角点检测 1.2.1 cv2.goodFeaturesToTrack()函数 1.2.2 OpenCV角点检测示例代码 1.3 直线检测 1.3.1 cv2.HoughLinesP()函数 1.3.2 OpenCV直线检测示例代码 1.4 圆形检测 1.4…...
基于单片机声音分贝采集和显示控制系统设计
**单片机设计介绍,基于单片机声音分贝采集和显示控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机声音分贝采集和显示控制系统设计,主要目标是实现声音分贝的实时采集、处理以及显示…...
CentOS使用Docker部署Halo并结合内网穿透实现公网访问本地博客
文章目录 1. Docker部署Halo1.1 检查Docker版本如果未安装Docker可参考已安装Docker步骤:1.2 在Docker中部署Halo 2. Linux安装Cpolar2.1 打开服务器防火墙2.2 安装cpolar内网穿透 3. 配置Halo个人博客公网地址4. 固定Halo公网地址 本文主要介绍如何在CentOS 7系统使…...
打造高效自动化渗透测试系统:关键步骤与实践
随着当前网络安全威胁的不断扩展与升级,开展渗透测试工作已经成为广大企业组织主动识别安全漏洞与潜在风险的关键过程。然而,传统的人工渗透测试模式对测试人员的专业能力和经验水平有很高的要求,企业需要投入较大的时间和资源才能完成。在此…...
绿联 部署vocechat,搭建私人聊天服务器,用于小型团队和家庭环境
1、镜像 privoce/vocechat-server:latest 2、安装 2.1、基础设置 重启策略:容器退出时总是重启容器。 2.2、网络 桥接即可。 2.3、存储空间 装载路径:/home/vocechat-server/data不可变更,权限读写。 2.4、端口设置 容器端口3000不可变…...
考研数学|高效刷透汤家凤《1800》经验分享
当然不需要换老师,如果你在基础阶段连汤老师的课都听不进去,那么换其他老师的话,很大可能也是白搭。 如果你现在对于1800还是一筹莫展的话,那么很明显,这反映出前期基础不扎实,没有真正理解和掌握这部分内…...
LLM推理入门指南②:深入解析KV缓存
在本系列文章《LLM推理入门指南①:文本生成的初始化与解码阶段》中,作者对Transformer解码器的文本生成算法进行了高层次概述,着重介绍了两个阶段:单步初始化阶段,即提示的处理阶段,和逐个生成补全词元的多…...
上采样技术在语义分割中的应用
目录 概要 一、概述 二、实现方法 1.转置卷积 2.反池化 3.双线性插值法 三、在经典网络中的的应用 1.U-Net 2.FCN 总结 概要 上采样是用于深度学习中提高语义分割精度的技术,可以实现图像放大和像素级别标注 一、概述 神经网络的基本结构为:…...
linux 组建raid5详细操作
raid5最多运行损坏一个盘,最少3个盘,容量为少一块硬盘的容量之和。 如果硬盘数量较多,比如8块以上,建议用raid6,raid6最多允许两块硬盘损坏。 如果需要 一、安装raid软件 deb包 apt-get install mdadm或dnf包 dnf …...
机器学习概念、步骤、分类和实践
在当今数字化时代,机器学习已经渗透到我们生活的方方面面,从智能手机应用、搜索引擎优化,到自动驾驶汽车、医疗诊断等,其应用无处不在。本文将带您走进机器学习的世界,了解它的基本概念、步骤、分类以及实践应用。 一…...
钉钉服务端API报错 错误描述: robot 不存在;解决方案:请确认 robotCode 是否正确
problem 调用钉钉服务端API,机器人发送群聊消息,后台返回报错信息: 钉钉服务端API报错 错误描述: robot 不存在;解决方案:请确认 robotCode 是否正确; reason 定位: 登录后台,查看机器人是存在查看机器人调用权限接…...
Linux 开发环境以及编译链接
再谈编译链接 C函数重载与编译链接-CSDN博客 之前我已经写过文章简单介绍了编译链接要做的一些操作。现在为了能更好的理解我们平时的开发环境,我会在Linux系统上完整地走一遍流程。 环境描述 我们使用普通用户在Linux上进行操作,先写一段测试代码。 …...
SmartChart的部署以及可能遇见的报错解决方案
简介 数据可视化是一种将数据转化为图形的技术,可以帮助人们更好地理解和分析数据。但是,传统的数据可视化开发往往需要编写大量的代码,或者使用复杂的拖拽工具,不仅耗时耗力,而且难以实现个性化的需求。有没有一种更…...
【Node.js从基础到高级运用】十九、Node.js 捕获错误之“未捕获的异常”
引言 在 Node.js 应用程序中,错误处理是保证应用稳定性和可靠性的关键部分。特别是“未捕获的异常”(uncaught exceptions),如果不妥善处理,很可能会导致整个进程崩溃。在本文中,我们将探讨如何在 Node.js …...
vue 计算属性
基础示例 模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。比如说,我们有这样一个包含嵌套数组的对象: const author reactive({name: John Doe,books: [V…...
RedissonLock-tryLock-续期
redisson版本3.16.6 1.什么是看门狗 Redisson提供的分布式锁是支持锁自动续期的,也就是说,如果线程仍旧没有执行完,那么redisson会自动给redis中的目标key延长超时时间,这在Redisson中称之为 Watch Dog 机制。默认情况下&#x…...
MSTP环路避免实验(华为)
思科设备参考:MSTP环路避免实验(思科) 一,技术简介 MSTP(多生成树协议),MSTP解决了STP和RSTP没有考虑vlan的问题,STP和RSTP将所有的vlan共享为一个生成树实例,无法实现…...
IoT网关在智能制造工厂生产线监控与管理中的应用-天拓四方
随着工业4.0时代的到来,智能制造已成为工业发展的重要方向。IoT网关在智能制造工厂中扮演着关键角色,它能够实现设备间的互联互通、数据的实时采集与处理,以及生产线的智能监控与管理。本案例将详细介绍IoT网关在智能制造工厂生产线监控与管理…...
niushop单商户V5多店版源码分享三端uniapp打包方法包括PC端_小程序或h5端打包_收银端打包_APP端打包_商户端
目前多店版有四端uniapp,包括PC端uniapp,商家端uniapp,收银端uniapp,门店手机端uniapp,下面我总结下这些端的打包流程希望能帮助到大家,需要交流的可以看我昵称或者点我头像关注我分享代码和教程 一.niush…...
npm包发布
一、npm npm(Node Package Manager)是 Node.js 的包管理工具,用于安装、分享和管理 JavaScript 包和项目依赖。npm 是 Node.js 的默认包管理器,随同 Node.js 一起安装。 二、npm主要功能特点 包管理:npm 允许开发者…...
C#使用SQLite(含加密)保姆级教程
C#使用SQLite 文章目录 C#使用SQLite涉及框架及库复制runtimes创建加密SQLite文件生成连接字串执行SQL生成表SQLiteConnectionFactory.cs 代码结构最后 涉及框架及库 自己在NuGet管理器里面安装即可 Chloe.SQLite:ORM框架Microsoft.Data.Sqlite.Core:驱…...
C# 异步与 Unity 协程(实例讲解)
C#异步编程实例: 假设我们有一个需要从Web获取数据的简单应用。我们可以使用C#的异步编程模型来避免UI线程被HTTP请求阻塞 1using System.Net.Http; 2using System.Threading.Tasks; 3 4public class AsyncExample 5{ 6 public async Task<string> Fetch…...
iOS - Runloop介绍
文章目录 iOS - Runloop介绍1. 简介1.1 顾名思义1.2. 应用范畴1.3. 如果没有runloop1.4. 如果有了runloop 2. Runloop对象3. Runloop与线程4. 获取Runloop对象4.1 Foundation4.2 Core Foundation4.3 示例 5. Runloop相关的类5.1 Core Foundation中关于RunLoop的5个类5.2 CFRunL…...
探究分布式事务:深入ACID特性在分布式系统中的挑战与解决方案
✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 ✨✨ 帅哥美女们,我们共同加油!一起进步&am…...
wordpress导航栏制作/济南优化网页
在《敏捷个人价值观,欢迎提出你的意见和你的价值观》中我介绍了一下我对敏捷个人价值观的一点初步理解,在这里也很感谢大家对blog的积极回复以及直接给我发邮件进行交流,你们的反馈是我们完善敏捷个人的最好参与方式。 大家对价值观的态度 上…...
用nas 做网站/360营销平台
整理了一份全国省市区SQL插入脚本,并配上抓取数据读取插入数据库源码,附件下载地址:https://files.cnblogs.com/files/101Love/Region.rar 转载于:https://www.cnblogs.com/101Love/p/7493868.html...
做六级真题的网站/婚恋网站排名前10
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/zjx18915341085/article/details/79715075一、准备工作1、修改环境变量,能够找到qmake&am…...
曲靖手机网站建设/网络营销专业如何
Java RMI基础Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能…...
网络营销方式举个例子/温州seo公司
下面介绍无监督机器学习算法,与前面分类回归不一样的是,这个不知道目标变量是什么,这个问题解决的是我们从这些样本中,我们能发现什么。 这下面主要讲述了聚类算法,跟数据挖掘中的关联挖掘中的两个主要算法。 K均值算法…...
做电影网站技术/百度快速seo软件
第1关:使用K近邻算法进行分类 任务描述 本关任务:编写一个能使用K近邻算法进行简单的二分类的小程序。 相关知识 为了完成本关任务,你需要掌握: 什么是K近邻算法 在sklearn中如何使用K最近邻算法 什么是K最近邻算法 在许多机器学习相关的书籍当中,最开始被介绍的算法很…...