《JavaSE》---21.<简单认识Java的集合框架包装类泛型>

news2024/11/15 6:47:56

目录

前言

一、什么是集合框架

1.1类和接口总览

 二、集合框架的重要性

2.1 开发中的使用

2.2 笔试及面试题

三、背后所涉及的数据结构

3.1 什么是数据结构

3.2 容器背后对应的数据结构

四、包装类

4.1 基本数据类型和对应的包装类

4.2 装箱和拆箱

1.最初的写法

2.Integer valueOf(int i)源码 

3.自动装箱和自动拆箱 (简化写法)

 【面试题】

五、泛型

5.1什么是泛型

5.2泛型的引入

5.3泛型的语法

示例代码 

5.4泛型类的使用

1.语法

 示例

 类型推导(Type Inference)

泛型小结:

六、裸类型(Raw Type) (了解)

七、泛型如何编译的

7.1 擦除机制

7.2 为什么不能实例化泛型类型数组

正确的方式:【了解即可】

八、泛型的上界

8.1 语法

九、泛型方法

9.1 定义语法


前言

      大家好,本人是普通一本的在校大学生一枚,目前在学习java。之前也学了一段时间,但是没有发布博客。时间过的真的很快。我会利用好这个暑假,来复习之前学过的内容,并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区进行讨论!!!

      喜欢我文章的兄弟姐妹们可以点赞,收藏和评论我的文章。喜欢我的兄弟姐妹们以及也想复习一遍java知识的兄弟姐妹们可以关注我呦,我会持续更新滴,
     望支持!!!!!!一起加油呀!!!!

语言只是工具,不能决定你好不好找工作,决定你好不好找工作的是你的能力!!!!!

学历本科及以上就够用了!!!!!!!!!!!!!!!!!!!!!!!!!!!!


本篇博客主要讲解Java基础语法中的

集合框架、什么是集合框架、集合框架的重要性、集合框架背后所涉及到的数据结构。

包装类、装箱和拆箱、【面试题】

泛型、裸类型、泛型如何编译的、泛型如何编译的

一、什么是集合框架

        Java 集合框架 Java Collection Framework ,又被称为容器 container ,是定义在 java.util 包下的一组接口 interfaces 和其实现类 classes

        其主要表现为将多个元素 element 置于一个单元中,用于对这些元素进行快速、便捷的存储 store 、检索 retrieve 、 管理 manipulate ,即平时我们俗称的增删查改 CRUD

1.1类和接口总览

每一个集合类,描述和组织数据的方式是不一样的。

我们分析这张图。

1.类与接口之间的关系

左边的部分全部是继承 Iterable 接口的。

接口和接口之间的关系用extends

类和接口之间是实现关系。

类与类也是继承关系

2.接口分别是什么、

        Iterable(是迭代器)、Collection(集合类)。

        实现 List 接口的有四个类。Vector(用得少了)、Stack(栈(也相对用得少  ))、ArrayList(顺序表)、LinkedList(链表,且是双向链表)

        实现 Queue(队列) 接口的有一个类。LinkedList(背后是链表,可以当做普通队列使用)PriorityQueue(优先级队列)

        实现 Set 接口的类有 TreeSet(底层搜索树(红黑树))、HashSet(底层哈希表k模型(里面的元素不能重复))

        实现Map接口的类有 HashMap(底层哈希表k-v模型)、TreeMap(底层也是红黑树)

我们可以通过迭代器来遍历集合、在集合中也可以用到对象比较

我们操作数组的工具类叫Arrays。

操作集合的工具类叫Collections

 二、集合框架的重要性

2.1 开发中的使用

  • 使用成熟的集合框架,有助于我们便捷、快速的写出高效、稳定的代码
  • 学习背后的数据结构知识,有助于我们理解各个集合的优缺点及使用场景

2.2 笔试及面试题

有许多是关于集合框架的。

三、背后所涉及的数据结构

3.1 什么是数据结构

数据结构(Data Structure)

计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。

3.2 容器背后对应的数据结构

该阶段,我们主要讲解以下容器,每个容器其实都是对某种特定数据结构的封装,大概了解一下,后序会在数据结构部分给大家详细讲解并模拟实现:

1. Collection:是一个接口,包含了大部分容器常用的一些方法

2. List:是一个接口,规范了ArrayList 和 LinkedList中要实现的方法

  • ArrayList:实现了List接口,底层为动态类型顺序表
  • LinkedList:实现了List接口,底层为双向链表

3. Stack:底层是栈,栈是一种特殊的顺序表

4. Queue:底层是队列,队列是一种特殊的顺序表

5. Deque:是一个接口

6. Set:集合,是一个接口,里面放置的是K模型

  • HashSet:底层为哈希表,查询的时间复杂度为O(1)
  • TreeSet:底层为红黑树,查询的时间复杂度为O(log2N ),关于key有序的

7. Map:映射,里面存储的是K-V模型的键值对

  • HashMap:底层为哈希表,查询时间复杂度为O(1)
  • TreeMap:底层为红黑树,查询的时间复杂度为O(log2N),关于key有序

四、包装类

在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了 一个包装类型。

4.1 基本数据类型和对应的包装类

除了 Integer 和 Character, 其余基本类型的包装类都是首字母大写。

4.2 装箱和拆箱

1.最初的写法

装箱:把一个基本数据类型转换为包装类型的过程。

拆箱:把一个包装类型转换为基本数据类型的过程。

int a = 10;
 
// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer b = Integer.valueOf(i);
Integer c = new Integer(i);
 
// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int d = b.intValue();

2.Integer valueOf(int i)源码 

3.自动装箱和自动拆箱 (简化写法)

为了减少开发者的负担,java 提供了自动机制。

自动装箱和自动拆箱

int a = 10;
 
Integer b = a; // 自动装箱
Integer c = (Integer)a; // 自动装箱

int j = b; // 自动拆箱
int k = (int)b; // 自动拆箱

 【面试题】

下列代码输出什么,为什么?

public static void main(String[] args) {
    Integer a = 127;
    Integer b = 127;
 
    Integer c = 128;
    Integer d = 128;
 
    System.out.println(a == b);
    System.out.println(c == d);
}

答:输出

true
false

 我们看Integer valueOf(int i)源码

IntegerCache.low=(-128)

IntegerCache.high=127

因此如果传入的数据为【-128,127】之间,就直接在这个数组中拿对应的数据了

如果不是【-128,127】之间则新建了一个Integer对象。因此一个是true一个是false

五、泛型

5.1什么是泛型

泛型是在JDK1.5引入的新的语法,通俗讲,

泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。

一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的 代码,这种刻板的限制对代码的束缚就会很大。

----- 来源《Java编程思想》对泛型的介绍。

5.2泛型的引入

class MyArray {
    public Object[] array = new Object[10];
    
    public Object getPos(int pos) {
        return this.array[pos];
   }
    public void setVal(int pos,Object val) {
        this.array[pos] = val;
   }
}
 
public class TestDemo {
    public static void main(String[] args) {
        MyArray myArray = new MyArray();
        myArray.setVal(0,10);
        myArray.setVal(1,"hello");//字符串也可以存放
        String ret = myArray.getPos(1);//编译报错
        System.out.println(ret);
   }
}

我们发现,实现上述代码后

1. 任何类型数据都可以存放

2. 1号下标本身就是字符串,但是确编译报错。因为大范围转小范围(父类给子类)必须进行强制类型转换 。

泛型的主要目的:

就是指定当前的容器,持有什么类型的对象。让编译器去做检查。此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。

5.3泛型的语法

class 泛型类名称<类型形参列表> {
    // 这里可以使用类型参数
}

eg:
class ClassName<T1, T2, ..., Tn> {  
}

class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
    // 这里可以使用类型参数
}
 
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
    // 可以只使用部分类型参数
}

示例代码 

class MyArray<T> {
    public Object[] array = new Object[10];//1
 
    public T getPos(int pos) {
        return (T)array[pos];
   }
    public void setVal(int pos,T val) {
        this.array[pos] = val;
   }
}
public class TestDemo {
    public static void main(String[] args) {
        MyArray<Integer> myArray = new MyArray<>();//2
        myArray.setVal(0,10);
        myArray.setVal(1,12);
        int ret = myArray.getPos(1);//3
        System.out.println(ret);
        myArray.setVal(2,"bit");//4
   }
}

在类名的后面写一个<T>代表当前类是一个泛型类。 

此时我们在新建对象的时候

MyArray<Integer> myArray = new MyArray<>();

在类型名后面加上<>并在其中指定我们要放入的数据。我们就会发现此时这个数组只能放入我们指定的类型,不能放入别的类型了。比如上面就只能放入整型。就不能放入字符串了。

<>当中只能是引用类型,不能是基本类型

1. 类名后的 <T> 代表占位符,表示当前类是一个泛型类

了解: 【规范】类型形参一般使用一个大写字母表示,常用的名称有:

  • E 表示 Element
  • K 表示 Key
  • V 表示 Value
  • N 表示 Number
  • T 表示 Type
  • S, U, V 等等 - 第二、第三、第四个类型

2. 注释1处,不能new泛型类型的数组  

T[] ts = new T[5];//是不对的

3. 注释2处,类型后加入 指定当前类型

4. 注释3处,不需要进行强制类型转换

5. 注释4处,代码编译报错,此时因为在注释2处指定类当前的类型,此时在注释4处,编译器会在存放元素的时候帮助我们进行类型检查。


5.4泛型类的使用

1.语法

泛型类<类型实参> 变量名; // 定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象

 示例

MyArray<Integer> list = new MyArray<Integer>();

注意:泛型只能接受类,所有的基本数据类型必须使用包装类! 

 类型推导(Type Inference)

MyArray<Integer> list = new MyArray<>(); // 可以推导出实例化需要的类型实参为 Integer

当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写

泛型小结:

1. 泛型是将数据类型参数化,进行传递

2. 使用 表示当前类是一个泛型类。

3. 泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换


六、裸类型(Raw Type) (了解)

裸类型是一个泛型类但没有带着类型实参,例如 MyArrayList 就是一个裸类型

裸类型实际上就是没有了类型实参的限制,又什么类型都能传入。

MyArray list = new MyArray();

注意: 我们不要自己去使用裸类型,裸类型是为了兼容老版本的 API 保留的机制 下面的类型擦除部分,我们也会讲到编译器是如何使用裸类型的。 

七、泛型如何编译的

7.1 擦除机制

那么,泛型到底是怎么编译的?这个问题,也是曾经的一个面试问题。泛型本质是一个非常难的语法,要理解好他 还是需要一定的时间打磨。

通过命令:javap -c 查看字节码文件,所有的T都是Object。

 在编译的过程当中,将所有的T替换为Object这种机制,我们称为:擦除机制

Java的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。

也就是

编译的过程中将所有的T擦除为Object。

运行的时候没有泛型这样的概念。

提出问题:

1、那为什么,T[] ts = new T[5]; 是不对的,编译的时候,替换为Object,不是相当于:Object[] ts = new Object[5]吗?

java中,数组是一个非常特殊的存在,在JVM中,相当于一种新的数据类型了

在 Java 中,数组是协变的(covariant),这意味着如果 Sub 是 Super 的子类型,

那么Sub[ ]也是Super[ ]的子类型。这种设计导致了类型不安全的问题。

例如:

Object[] objArray = new String[10];
objArray[0] = 10; // 运行时错误:ArrayStoreException

为了避免类似的问题,Java 不允许直接创建泛型数组,因为在运行时无法检查泛型类型的具体类型。例如:

T[] ts = new T[5]; // 编译错误

详细解释

  1. 类型擦除:在编译时,泛型类型被擦除,意味着 T 被替换为其上限(默认为 Object),但数组的运行时类型信息仍然需要保留。

  2. 数组的运行时类型信息:Java 数组会在运行时保留类型信息,例如 new String[10] 创建一个 String 类型的数组,而 new Object[10] 创建一个 Object 类型的数组。这种类型信息在运行时是固定的。

  3. 类型安全:允许 T[] 会导致类型不安全问题,因为 T 在运行时是不可知的。例如,如果允许 T[] ts = new T[5];,在运行时类型信息只能是 Object[],但这与泛型类型检查机制不一致。

不能直接创建泛型数组是因为类型擦除和数组的协变性设计导致的类型安全问题。使用集合类或通过反射创建数组是常见的解决方案。尽管这些方法可以绕过编译限制,但需要注意它们可能带来的运行时问题。

2、类型擦除,一定是把T变成Object吗?

总结

  • 未指定上界的泛型类型:类型擦除后,泛型类型 T 被替换为 Object
  • 指定了上界的泛型类型:类型擦除后,泛型类型 T 被替换为其上界。
  • 泛型方法:类型擦除后的泛型方法会根据泛型参数的上界进行替换。

类型擦除确保了泛型在运行时不产生新的类型,但依然提供了编译时的类型检查和安全性。通过理解类型擦除的机制,可以更好地掌握泛型的使用和限制。

7.2 为什么不能实例化泛型类型数组

class MyArray<T> {
    public T[] array = (T[])new Object[10];
 
    public T getPos(int pos) {
        return this.array[pos];
   }
    public void setVal(int pos,T val) {
        this.array[pos] = val;
   }
    public T[] getArray() {
        return array;
   }
}
 
 public static void main(String[] args) {
     MyArray<Integer> myArray1 = new MyArray<>();
 
     Integer[] strings = myArray1.getArray();
 
 }
 
/*
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
 at TestDemo.main(TestDemo.java:31)
*/

数组不能整体进行强制类型转换

除非实例化一个具体类型的数组

原因:替换后的方法为:将Object[]分配给Integer[]引用,程序报错。 

public Object[] getArray() {
    return array;
}

通俗讲就是:返回的Object数组里面,可能存放的是任何的数据类型,可能是String,可能是Person,运行的时候,直接转给Integer类型的数组,编译器认为是不安全的。 

正确的方式:【了解即可】

class MyArray<T> {
    public T[] array;
 
    public MyArray() {
   }
 
    /**
     * 通过反射创建,指定类型的数组
     * @param clazz
     * @param capacity
     */
    public MyArray(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
   }
 
    public T getPos(int pos) {
        return this.array[pos];
   }
    public void setVal(int pos,T val) {
        this.array[pos] = val;
   }
    public T[] getArray() {
        return array;
   }
}
public static void main(String[] args) {
    MyArray<Integer> myArray1 = new MyArray<>(Integer.class,10);
 
    Integer[] integers = myArray1.getArray();
 
}

八、泛型的上界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。

8.1 语法

简单示例

class 泛型类名称<类型形参 extends 类型边界> {
   ...
}

public class MyArray<E extends Number> {
   ...
}

只接受 Number 的子类型作为 E 的类型实参

MyArray<Integer> l1; // 正常,因为 Integer 是 Number 的子类型
MyArray<String> l2; // 编译错误,因为 String 不是 Number 的子类型
error: type argument String is not within bounds of type-variable E
       MyArrayList<String> l2;
                   ^
where E is a type-variable:
       E extends Number declared in class MyArrayList

了解: 没有指定类型边界 E,可以视为 E extends Object 


复杂示例 

public class MyArray<E extends Comparable<E>> {
   ...
}

 E必须是实现了Comparable接口的

写一个方法,求指定类型数组的最大值

class Alg<T>{
    public T findMax(T[] array){
        T max = array[0];
        for(int i = 1;i < array.length; i++){
            if(array[i] > max){
                max = array[i];
            }
        }
        return max;
    }    
}

以为这样就对了吗? 

我们发现不能比大小,会报错,那是为什么呢。因为Object类中没有比较的方法。

我们必须实现 comparable 接口来进行比较 

这样就可以了 

这就类似于上面所提到的

public class MyArray<E extends Number> {
   ...
}

九、泛型方法

9.1 定义语法

方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }

 示例

public class Util {
    //静态的泛型方法 需要在static后用<>声明泛型类型参数
    public static <E> void swap(E[] array, int i, int j) {
        E t = array[i];
        array[i] = array[j];
        array[j] = t;    
    }
}

使用示例-可以类型推导 

Integer[] a = { ... };
swap(a, 0, 9);

String[] b = { ... };
swap(b, 0, 9);

使用示例-不使用类型推导

Integer[] a = { ... };
Util.<Integer>swap(a, 0, 9);

String[] b = { ... };
Util.<String>swap(b, 0, 9);

 写一个方法,求指定类型数组的最大值(泛型方法示例)

也可以是设置成一个静态方法,不实例化对象,用类名调用这个方法 

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

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

相关文章

向量数据库|一文全面了解向量数据库的基本概念、原理、算法、选型

向量数据库的原理和实现&#xff0c;包括向量数据库的基本概念、相似性搜索算法、相似性测量算法、过滤算法和向量数据库的选型等等。向量数据库是崭新的领域&#xff0c;目前大部分向量数据库公司的估值乘着 AI 和 GPT 的东风从而飞速的增长&#xff0c;但是在实际的业务场景中…

NodeRed测试modbus RTU或modbus TCP通讯

目录标题 STEP1 添加modbus节点STEP2 查看是否安装成功STEP3 modbusTCP读取写入设置读取设置写入设置 STEP4 读写测试 STEP1 添加modbus节点 节点管理——控制板——安装 找到node-red-contrib-modbus&#xff0c;点击安装 STEP2 查看是否安装成功 安装成功后&#xff0c;左…

Day14 | 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树

语言 Java 找树左下角的值 题目链接&#xff1a;找树左下角的值 题目 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 思路 本题有两种做法我主要讲一下递归的思路&#xff0c;创建两个全局变量&…

blender使用(三)常用建模操作及修改器

1&#xff0c;挤出图形 tab编辑模式&#xff0c;选中一个点/线/面&#xff0c;按键E&#xff0c;可以挤出对应的图形。选中点会挤出一条线&#xff0c;线会挤出一个面&#xff0c;面挤出体 2&#xff0c;倒角 选中一个边后&#xff0c;ctrlB &#xff0c;拖动鼠标是倒角范围&am…

MINIO集群部署手册

为了满足电子仓库功能相关部署与扩容等操作&#xff0c;因此提供电子仓库部署手册。手册中我们以2个minio节点&#xff0c;每个节点2个盘来进行分布式部署&#xff1b;并且最终扩容成4个节点每个节点2个盘。 操作系统 由于在Windows下运行分布式Minio处于实验阶段&#xff0c;因…

Web前端浅谈ArkTS组件开发

本文由JS老狗原创。 有幸参与本厂APP的鸿蒙化改造&#xff0c;学习了ArkTS以及IDE的相关知识&#xff0c;并有机会在ISSUE上与鸿蒙各路大佬交流&#xff0c;获益颇丰。 本篇文章将从一个Web前端的视角出发&#xff0c;浅谈ArkTS组件开发的基础问题&#xff0c;比如属性传递、插…

定积分与不定积分

定积分与不定积分 引言正文不定积分理解角度1理解角度2 定积分 引言 可能大家看到这个标题会不屑一顾&#xff0c;觉得这个还用你教我吗&#xff0c;高等数学最简单的内容。今天突然想到一个问题&#xff0c;就是为什么不定积分会有一个常数 C C C 出现&#xff0c;这个常数 …

继电器驱动电路的可靠性设计分析

在温度-30℃到85℃、供电电源9V-16V范围条件下&#xff0c;保证外部继电器能正常作动&#xff0c;且不发生负载能力降低的情况。&#xff08;注&#xff1a;需要详细的外部继电器规格说明&#xff09; 对于控制多路输出而且要求负载同时打开的模块&#xff0c;必须以50ms(10ms…

C++_单例模式

目录 1、饿汉方式实现单例 2、懒汉方式实现单例 3、单例模式的总结 结语 前言&#xff1a; 在C中有许多设计模式&#xff0c;单例模式就是其中的一种&#xff0c;该模式主要针对类而设计&#xff0c;确保在一个进程下该类只能实例化出一个对象&#xff0c;因此名为单例。而…

OpenCV 图像旋转和平移 数学和代码原理详解

文章目录 数学原理旋转矩阵平移和旋转合成变换矩阵应用在OpenCV中的实现 代码关键点解读完整代码C代码&#xff1a;Python代码&#xff1a; 在OpenCV中进行图像旋转涉及到一些基本的几何变换和图像处理操作。 数学原理 在图像旋转中&#xff0c;背后的数学原理主要涉及二维欧…

嵌入式硬件-Xilinx FPGA DDR4 接口配置基础(PG150)

1. 简介 1.1 DDR4 SDRAM 控制器主要特点 支持8到80位接口宽度的组件&#xff08;支持 RDIMM、LRDIMM、UDIMM 和 SODIMM&#xff09; 最大组件限制为9&#xff0c;此限制仅适用于组件&#xff0c;不适用于 DIMM。密度支持 最高支持 32 GB 的组件密度&#xff0c;64 GB 的 LRDI…

步步精慕尼黑上海电子展完美收官,感恩所有相遇,期待下次再会

2024年7月11日至13日&#xff0c;慕尼黑上海电子展圆满落幕&#xff0c;步步精科技&#xff08;以下简称步步精&#xff09;在此次展会上取得了丰硕的成果。作为连接器行业的重要制造商&#xff0c;步步精携带其最新产品和连接器技术方案亮相展会&#xff0c;吸引了大量参观者的…

【HarmonyOS】HarmonyOS NEXT学习日记:六、渲染控制、样式结构重用

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;六、渲染控制、样式&结构重用 渲染控制包含了条件渲染和循环渲染&#xff0c;所谓条件渲染&#xff0c;即更具状态不同&#xff0c;选择性的渲染不同的组件。 而循环渲染则是用于列表之内的、多个重复元素组成的结构中。 …

RK3568笔记四十二:OLED 屏幕驱动(模拟I2C)

若该文为原创文章&#xff0c;转载请注明原文出处。 本篇记录使用GPIO模拟I2C驱动OLED屏幕&#xff0c;显示界面效果如下。 主要流程是&#xff0c;修改设备树&#xff0c;使用普通IO口&#xff0c;驱动模拟I2C方式&#xff0c;应用程直接传输数据控制。 1、修改设备 2、编写…

Go语言 Import导入

本文主要介绍Go语言import导入使用时注意事项和功能实现示例。 目录 Import 创建功能文件夹 加法 减法 主函数 优化导入的包名 .引入方法 总结 Import 创建功能文件夹 做一个计算器来演示&#xff0c;首先创建test文件夹。 加法 在test文件夹中创建add文件夹&#xff…

数据预处理在建模中的重要性与常见方法(三):特征工程篇

数据预处理在建模中的重要性与常见方法&#xff08;三&#xff09;&#xff1a;特征工程篇 特征工程是数据预处理中至关重要的一步&#xff0c;通过构建、转换和选择最能代表数据特性的特征&#xff0c;以提高模型的性能和准确性。常见的特征工程方法包括特征选择、特征提取和特…

前端-模拟请求数据mook第三方插件 json-server的使用

大纲 第一步下载第二配置mook的数据源第三配置启动命令第四运行模拟服务第五测试接口如果要进行更复杂的操作 第一步下载 npm install json-server -D"devDependencies": {"json-server": "^1.0.0-beta.1"}第二配置mook的数据源 在项目的根目录…

某指挥调度系统功能展示(下)

照片管理 拍照是普通执勤巡检中很常用的信息记录功能。 通过此功能可以看到设备本地拍摄的照片&#xff0c;此平台分成了两部分&#xff1a; 一部分是设备上的&#xff0c;需要设备在线才可以访问&#xff1b;支持上传到平台&#xff0c;并且在设备端有相应的选择&#xff0…

人、智能、机器人……

在遥远的未来之城&#xff0c;智能时代如同晨曦般照亮了每一个角落&#xff0c;万物互联&#xff0c;机器智能与人类智慧交织成一幅前所未有的图景。这座城市&#xff0c;既是科技的盛宴&#xff0c;也是人性与情感深刻反思的舞台。 寓言&#xff1a;《智光与心影》 在智能之…

Linux性能分析之-CPU篇

开发车载软件app&#xff0c;除了常用Android操作系统外&#xff0c;还可能是基于Linux系统开发。对于web应用基本也都部署在Linux系统上&#xff0c;所以&#xff0c;进行系统性能分析&#xff0c;很大情况下都是对Linux系统进行性能分析。此篇博客将重点介绍如果收集CPU相关指…