【2025】camunda API接口介紹以及REST接口使用(3)

前言

在前面的兩篇文章我們介紹了Camunda的web端和camunda-modeler的使用。這篇文章主要介紹camunda結合springboot進行使用,以及相關api介紹。

該專欄主要為介紹camunda的學習和使用

  • 🍅【2024】Camunda常用功能基本詳細介紹和使用-下(1)
  • 🍓【2024】Camunda常用功能基本詳細介紹和使用(業務決策和定時事件)-下(2)
  • 🍇【2025】camunda API接口介紹以及REST接口使用(3)

一、項目搭建

1、依賴引入

先創建好一個springboot項目,這里依舊使用的camunda7.20的版本,然后jdk使用的是17的版本,springboot版本使用的是3.3.0。這里可以根據自己的項目情況去跟換camunda7.20版本。可以在官方文檔查看版本適配。
盡量選擇適配的避免增加不必要的麻煩!

??官網地址
在這里插入圖片描述

在這里插入圖片描述

依賴我主要添加了幾個camunda引擎還有web頁面以及rest接口和openapi的幾個依賴;數據庫用的是mysql的數據庫;swagger文檔用了knife4j的。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>org.zheng</groupId><artifactId>camunda-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>camunda-demo</name><description>camunda-demo</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version><camunda.version>7.20.0</camunda.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--        camunda相關 依賴-->
<!--        引擎--><dependency><groupId>org.camunda.bpm.springboot</groupId><artifactId>camunda-bpm-spring-boot-starter</artifactId><version>${camunda.version}</version></dependency>
<!--        web ui界面--><dependency><groupId>org.camunda.bpm.springboot</groupId><artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId><version>${camunda.version}</version></dependency>
<!--        rest接口--><dependency><groupId>org.camunda.bpm.springboot</groupId><artifactId>camunda-bpm-spring-boot-starter-rest</artifactId><version>${camunda.version}</version></dependency>
<!--       openapi 文檔 --><dependency><groupId>org.camunda.bpm</groupId><artifactId>camunda-engine-rest-openapi</artifactId><version>${camunda.version}</version></dependency><!-- swagger文檔--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.4.0</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-spring-boot-starter</artifactId><version>4.4.0</version></dependency><!--       mysql 數據庫--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.32</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></path></annotationProcessorPaths></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

2、配置文件

2.1、yaml配置文件

主要配置了數據庫連接配置,camunda基礎配置,以及swagger相關配置

server:port: 8090spring:application:name: camunda-demo# 數據庫配置datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/camunda?nullDatabaseMeansCurrent=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=falseusername: rootpassword: 123456type: com.mysql.cj.jdbc.MysqlDataSource# camunda基礎配置
camunda.bpm:
#  auto-deployment-enabled: false #如果不是第一次啟動可以把這個打開,避免每次去檢查自動部署數據庫admin-user:id: admin  #用戶名password: 123456  #密碼firstName: yufilter:create: All tasksgeneric-properties:# 歷史生存時間properties:historyTimeToLive: P10D# swagger文檔配置
springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaurls:- url: /openapi.json # camunda中編寫好的api的文檔信息name: camunda- url: /v3/api-docs  # 咱們自己在項目中自定義的文檔信息name: camundaapi-docs:path: /v3/api-docsenabled: true

2.2、添加openapi.json

把依賴下載下來之后我們需要到camunda-engine-rest-openapi把openapi.json文件添加到resources.static目錄下供配置文件讀取

在這里插入圖片描述
存放位置
在這里插入圖片描述

3、驗證

  1. 啟動項目,訪問
    http://localhost:8090/camunda/app/cockpit/default/#/dashboard
    使用自己yaml配置的 賬號 密碼登陸則代表頁面成功
    在這里插入圖片描述

  2. 訪問swagger
    http://localhost:8090/swagger-ui/index.html
    需要把端口改為自己的端口,或者直接修改openapi.json文件
    在這里插入圖片描述

  3. doc.html訪問
    http://localhost:8090/doc.html#/home登陸,然后還需要修改這個地方,改為實際地址的前綴

在這里插入圖片描述

二、REST API介紹

1、Camunda API介紹

中心起點是 ProcessEngine,可以通過配置部分中描述的幾種方式創建。從 ProcessEngine,您可以獲取包含工作流/BPM 方法的各種服務。ProcessEngine 和服務對象是線程安全的。因此,您可以為整個服務器保留對其中一個的引用。

在這里插入圖片描述
ProcessEngines.getDefaultProcessEngine()將在第一次調用時初始化并構建流程引擎,之后始終返回相同的流程引擎。可以使用 和 正確創建和關閉所有流程ProcessEngines.init()引擎ProcessEngines.destroy()。
在這里插入圖片描述

創建流程引擎的時候我們要知道一點,所有流程引擎服務都是無狀態的。這意味著您可以輕松地在集群中的多個節點上運行 Camunda 7,每個節點都訪問同一個數據庫,而不必擔心哪臺機器實際執行了之前的調用。對任何服務的任何調用都是冪等的,無論它在何處執行。

下面就是我們流程引擎內部的api service,這些service都注入到bean容器里面去了,我們可以直接跟其他的接口一樣,使用spring的方式在使用時直接引入

常用介紹:

  • RepositoryService:RepositoryService是你與Camunda引擎交互的第一個切入點。它主要用于管理流程定義的部署,包括上傳流程定義文件(如BPMN文件)到引擎中。
    • 部署和管理流程定義
    • 查詢已部署的流程定義和部署信息
    • 掛起和激活流程定義,控制其是否可以被啟動
    • 檢索流程定義中的文件和流程圖。
  • RuntimeService:RuntimeService是用于在流程執行期間與引擎交互的服務。它允許啟動流程實例,并且可以查詢正在執行的流程實例狀態
    • 啟動流程實例
    • 存儲和檢索流程實例的變量。
    • 查詢正在執行的流程實例和執行實例(指向流程實例當前位置的“令牌”)
    • 處理流程實例的外部觸發。
  • TaskService:TaskService專注于管理流程中的任務,特別是那些需要人為干預的任務。
    • 查詢分配給用戶的任務。
    • 創建新的任務,這些任務可以獨立于任何流程實例。
    • 分配任務給用戶或組。
    • 認領和完成任務。
  • IdentityService:IdentityService提供了管理用戶和組的功能,但請注意,核心引擎并不會在運行時驗證用戶身份。
    • 創建、更新、刪除和查詢用戶和組。
    • 盡管可以將任務分配給任何用戶,但實際的身份驗證和授權需在應用層實現。
  • FormService:FormService是可選的,它支持流程中的表單功能,比如啟動流程前展示的表單或任務完成時所需的表單。
    • 管理和渲染開始表單和任務表單。
    • 表單數據與流程變量的交互。
  • HistoryService:HistoryService提供了訪問流程執行歷史記錄的功能。
    • 查詢流程實例的歷史數據,如開始時間、執行用戶、任務耗時等
    • 數據持久化級別可配置
  • FilterService:FilterService允許創建和管理過濾器,用于簡化常見的查詢需求
    • 創建存儲的查詢,如任務查詢。
    • Tasklist應用使用過濾器來篩選任務。
  • ExternalTaskService:ExternalTaskService專門處理外部任務,即在流程引擎之外執行的工作項。
    • 提供對流程外部任務的訪問和管理
    • 支持異步處理模式下的任務領取和完成。

2、常用API詳細使用

2.1、 RepositoryService

下面的查詢接口我們要知道一點,如ProcessDefinition這個返回出來的實際是使用多態,實際的實體對象會是ProcessDefinitionEntity,Camunda中全部的api返回都是這個格式,要查看實體對象則需要加Entity

	//    管理流程定義相關的api@Autowiredprivate RepositoryService repositoryService;/*** 流程部署*/@Testvoid testRepositoryService(){//        添加流程/** 表示把test.bpmn作為流程部署到數據庫設置name為test** *///        Deployment deployment = repositoryService.createDeployment() //添加流程部署記錄 ACT_RE_DEPLOYMENT//                .name("test")   //name//                .addClasspathResource("test.bpmn")   //文件地址//                .deploy(); //添加流程定義 實際數據 ACT_RE_PROCDEF//        查詢 流程部署 數據執行器 ACT_RE_PROCDEFProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();//        返回全部數據List<ProcessDefinition> processDefinitionList = processDefinitionQuery.list();processDefinitionList.forEach(it-> System.out.println(it.getName()));//        根據key查詢返回符合的流程定義列表(每一個版本算一條記錄)List<ProcessDefinition> processDefinitionList2 = processDefinitionQuery.processDefinitionKey("shopping").list();//        根據流程name查詢,并且按照版本號查詢最新的數據ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionName("shopping").latestVersion().singleResult();//        查詢 流程定義 數據執行器 ACT_RE_DEPLOYMENTDeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();List<Deployment> deploymentList = deploymentQuery.list();List<Resource> resourceList = repositoryService.getDeploymentResources("036d2809-b795-11ef-9e74-46c5fd5dfd3a");System.out.println(resourceList);List<CaseDefinition> caseDefinitionList = repositoryService.createCaseDefinitionQuery().list();System.out.println(caseDefinitionList);//        查詢ACT_RE_DECISION_DEFList<DecisionDefinition> decisionDefinitionList = repositoryService.createDecisionDefinitionQuery().list();System.out.println(decisionDefinitionList);List<DecisionRequirementsDefinition> decisionRequirementsDefinitionList = repositoryService.createDecisionRequirementsDefinitionQuery().list();System.out.println(decisionRequirementsDefinitionList);        根據流程定義刪除數據//        repositoryService.deleteDeployment("WorkOrderProcess:4:3659eb47-b794-11ef-9e74-46c5fd5dfd3a",true);//        根據流程部署id刪除數據//        repositoryService.deleteProcessDefinition("db155b13-b793-11ef-9e74-46c5fd5dfd3a");}

2.2、TaskService

	//    查詢流程中的任務相關的api@Autowiredprivate TaskService taskService;/*** 任務查詢*/@Testvoid testTaskService() {taskService.createTaskQuery();//        Java 對象查詢 數據執行器 ACT_RU_TASKTaskQuery taskQuery = taskService.createTaskQuery();List<Task> taskList1 = taskQuery.list();taskList1.forEach(task -> System.out.println(task.getName()));//        根據用戶查詢代辦任務List<Task> taskList2 = taskQuery.taskAssignee("admin").list();System.out.println(taskList2);//        Native sql 查詢 數據執行器NativeTaskQuery nativeTaskQuery = taskService.createNativeTaskQuery();List<Task> taskList3 = nativeTaskQuery.sql("SELECT * from ACT_RU_TASK").list();taskList3.forEach(task -> System.out.println(task.getName()));taskList3.forEach(task -> System.out.println(task.getName()));}

2.3、RuntimeService

	//    管理流程實例相關的api@Autowiredprivate RuntimeService runtimeService;@Testvoid testRuntimeService(){//        查詢 (執行在流程上的每一種結果)   Execution可以代表這個執行過程中的某一個分支或上下文List<Execution> executionList = runtimeService.createExecutionQuery().list();System.out.println(executionList);//        獲取查詢流程實例  ProcessInstance表示整個流程的一次完整執行List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().list();//        查詢當前正在活動的任務ActivityInstance activityInstance = runtimeService.getActivityInstance("86f6ef7d-b935-11ef-8a29-46c5fd5dfd3a");System.out.println(activityInstance);//        根據任務id查詢任務參數Map<String, Object> variables = runtimeService.getVariables("86f6ef7d-b935-11ef-8a29-46c5fd5dfd3a");}

3、REAT API介紹使用

很多時候我們在開發的項目過程中不想和工作流引擎過于緊密,我們通常可能需要做到解耦合。在其他的服務通過調用camunda的Open API的方式去獲取工作流中的相關數據,這時候我們就需要了解常用到的API接口,這時候我們可能需要獲取到對應的接口的實體接收類,但又不想添加工作流引擎的依賴,這時候我們需要添加兩個依賴。

3.1、依賴

添加這兩個依賴,這兩個依賴主要是一些實體類和API接口的相關參數

<!--        實體對象--><dependency><groupId>org.camunda.bpm</groupId><artifactId>camunda-engine-spring-6</artifactId><version>7.20.0</version></dependency><!--        open api接口以及相關的DTO對象--><dependency><groupId>org.camunda.bpm</groupId><artifactId>camunda-engine-rest-core-jakarta</artifactId><version>7.20.0</version></dependency>

3.2、REST API接口介紹

我們打開camunda-engine-rest-core-jakarta依賴的sub包下的對應的這些文件夾是不是很熟悉,是的這些文件夾就是對應的Camunda API中的service名字。
分別對應著task、runtime、repository、management、identity、history 六個service,每個service的具體的介紹就看上面就行。

在這里插入圖片描述

3.2.1、接口介紹

這里介紹一下task,可以看到不同的接口文件分別是表示一個分類。對應著task相關的接口。可以看到這里的一個類對應著swagger 中接口文檔的一個類

在這里插入圖片描述

  • TaskResource
    文件中的TaskResource類就是對應的swagger的task,@GET注解表示請求方式,@Path表示路徑,@Path表示拼接的路徑后綴。
    在這里插入圖片描述

在這里插入圖片描述

  • TaskAttachmentResource
    這個就可以很明顯看到他們的區別
    在這里插入圖片描述

在這里插入圖片描述

3.2.2、接口組成

以這個接口舉例

http://localhost:8080/engine-rest/task/47398c44-bab7-11ef-81ba-024191f3177f/form

  • http://localhost:8080/engine-rest:是服務和統一的路徑,不用管
  • task:表示這個類名的前綴
  • 47398c44-bab7-11ef-81ba-024191f3177f:{id}是我們傳入的路徑參數,還沒到接口的位置就被解析了,所以在這個位置沒有參數
  • form:表示接口的路徑

所以我們接收的參數就是FormDto對象,一般可以直接使用,有部分是內部還包裹著的類屬性就不能直接使用,需要做自己去聲明對應的屬性。

在這里插入圖片描述

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/68047.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/68047.shtml
英文地址,請注明出處:http://en.pswp.cn/web/68047.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java進階學習之路

Java進階之路 提示&#xff1a;這里可以添加系列文章的所有文章的目錄&#xff0c;目錄需要自己手動添加 提示&#xff1a;寫完文章后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 目錄 Java進階之路前言一、Java入門 Java基礎 1、Java概述 1.1 什…

JAVA安全—反射機制攻擊鏈類對象成員變量方法構造方法

前言 還是JAVA安全&#xff0c;哎&#xff0c;真的講不完&#xff0c;太多啦。 今天主要是講一下JAVA中的反射機制&#xff0c;因為反序列化的利用基本都是要用到這個反射機制&#xff0c;還有一些攻擊鏈條的構造&#xff0c;也會用到&#xff0c;所以就講一下。 什么是反射…

TfidfVectorizer

TF-IDF / Term Frequency - Inverse Document Frequency 作用&#xff1a;是自然語言處理NLP中常用的文本特征提取工具&#xff0c;用于將文本數據轉換為數據向量。 核心思想&#xff1a;是通過統計詞頻和逆文檔頻率來量化詞語在文本中的重要性。 T F ? I D F ( t , d ) T F…

DeepSeek-R1 論文解讀:強化學習如何 “煉” 出超強推理模型?

深度解析DeepSeek-R1&#xff1a;強化學習驅動大語言模型推理能力新突破 論文鏈接&#xff1a;DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 在大語言模型&#xff08;LLMs&#xff09;飛速發展的當下&#xff0c;提升模型推理能力成…

【數據結構】循環鏈表

循環鏈表 單鏈表局限性單向循環鏈表判斷鏈表是否有環思路code 找到鏈表入口思路代碼結構與邏輯 code 單鏈表局限性 單鏈表作為一種基本的數據結構&#xff0c;雖然在很多場景下都非常有用&#xff0c;但它也存在一些局限性&#xff1a; 單向訪問&#xff1a;由于每個節點僅包含…

ip屬地是手機號還是手機位置?一文理清

在數字化和網絡化的今天&#xff0c;IP屬地這一概念逐漸成為了人們關注的焦點。特別是在社交媒體和在線平臺上&#xff0c;IP屬地的顯示往往讓人聯想到用戶的地理位置。然而&#xff0c;關于IP屬地到底與手機號還是手機位置有關&#xff0c;卻存在著不少誤解和混淆。本文將深入…

【嵌入】基于nomic-embed-text-v1.5和HuggingFaceEmbeddings實現

測試代碼 model_name = /media/zhangbin/DATA/DataCache/nomic-ai/nomic-embed-text-v1.5import osos.environ[HF_HOME] = /media/zhangbin/DATA/DataCache/#os.environ["TRANSFORMERS_CACHE"] = "/media/zhangbin/DATA/DataCache/" # 確保目錄結構正確 if…

離散時間傅里葉變換(DTFT)公式詳解:周期性與連續性剖析

摘要 離散時間傅里葉變換&#xff08;DTFT&#xff09;是數字信號處理領域的重要工具&#xff0c;它能將離散時間信號從時域轉換到頻域&#xff0c;揭示信號的頻率特性。本文將深入解讀DTFT公式&#xff0c;詳細闡述其具有周期性和連續性的原因&#xff0c;幫助讀者全面理解DT…

哈希表與散列表的原理及C++實現

1. 什么是哈希表&#xff1f; 哈希表&#xff08;Hash Table&#xff09;是一種高效的數據結構&#xff0c;用于存儲鍵值對&#xff08;Key-Value Pairs&#xff09;。它通過哈希函數&#xff08;Hash Function&#xff09;將鍵&#xff08;Key&#xff09;映射到一個固定大小…

圖像分類與目標檢測算法

在計算機視覺領域&#xff0c;圖像分類與目標檢測是兩項至關重要的技術。它們通過對圖像進行深入解析和理解&#xff0c;為各種應用場景提供了強大的支持。本文將詳細介紹這兩項技術的算法原理、技術進展以及當前的落地應用。 一、圖像分類算法 圖像分類是指將輸入的圖像劃分為…

前端框架中 HTML 的應用技巧:React、Vue、Angular 深度解析

系列文章目錄 01-從零開始學 HTML&#xff1a;構建網頁的基本框架與技巧 02-HTML常見文本標簽解析&#xff1a;從基礎到進階的全面指南 03-HTML從入門到精通&#xff1a;鏈接與圖像標簽全解析 04-HTML 列表標簽全解析&#xff1a;無序與有序列表的深度應用 05-HTML表格標簽全面…

Vue - customRef 自定義ref

customRef 作用&#xff1a;創建一個自定義的 ref , 并對其依賴項跟蹤和更新觸發進行邏輯控制。 在原生 ref 的基礎上&#xff0c;添加自己的邏輯等... 在 Vue 3 中&#xff0c;customRef 是一個用于創建自定義響應式引用的 API。它允許開發者控制和優化響應式引用的行為&…

數字化轉型:概念性名詞淺談(第四講)

?大家好&#xff0c;本篇文章是在新年之際寫的&#xff0c;所以在這里先給大家拜個年。 今天要介紹的名詞為ETL: ETL&#xff0c;是英文Extract-Transform-Load的縮寫&#xff0c;用來描述將數據從來源端經過抽取&#xff08;extract&#xff09;、轉換&#xff08;transfor…

UE學習日志#22 C++筆記#8 基礎復習8 string和string_view2

1 std::string_view類 string_view基本上就是const string&的簡單替代品&#xff0c;但不會產生開銷。他不復制字符串。 string_view添加了remove_prefix(size_t)和remove_suffix(size_t)方法&#xff0c;前者將起始指針給定的偏移量來收縮字符串&#xff0c;后者則將結尾指…

UVM factory機制

目錄 1. factory-register 1.1 uvm_object_registry#(type T=uvm_object, string Tname="") 1.1 uvm_default_factory::register 2. factory-override 2.1 set_type_override(uvm_object_wrapper override_type) 2.2 set_inst_override(uvm_object_wrapper ove…

Spring MVC學習——發送請求(@RequestMapping注解及請求參數綁定)

前言 Spring MVC作為Spring框架中的核心組件之一&#xff0c;其強大的功能在于能簡潔高效地處理HTTP請求和響應。在開發Web應用時&#xff0c;理解和正確使用Spring MVC的注解&#xff0c;尤其是RequestMapping注解&#xff0c;至關重要。本文將詳細講解RequestMapping注解的使…

C# Action和 Func的用法

C#中的數據類型 函數數據類型 Action 是一個數據類型 但是是沒有返回值得函數數據類型 Func 用于指定一個有返回值的委托 internal class Program{static void Main(string[] args){TT.F1(NoVoid);TT.F2(Void1);Void2(() > { Console.WriteLine("Void2執行了");…

C++中的模板(上)

C中的模板(上) 模板參數和函數參數是很像的,函數參數定義的形參對象,而模板參數定義的是類型. 模板分為函數模板和類模板 函數模板 一個交換兩個數的函數模板: template<class T> // 此處typename和class是等價的 void Swap(T &a, T &b) {T temp a;a b;b …

MySQL面試題----如何進行 MySQL 數據庫備份與恢復

MySQL 數據庫備份 1. 使用 mysqldump 工具(邏輯備份) 全量數據庫備份 該方式會備份指定數據庫中的所有數據和表結構。在命令行中輸入以下命令,將 username 替換為你的 MySQL 用戶名,password 替換為對應的密碼,database_name 替換為要備份的數據庫名,backup.sql 為備份文…

Java集合面試總結(題目來源JavaGuide)

問題1&#xff1a;說說 List,Set,Map 三者的區別&#xff1f; 在 Java 中&#xff0c;List、Set 和 Map 是最常用的集合框架&#xff08;Collection Framework&#xff09;接口&#xff0c;它們的主要區別如下&#xff1a; 1. List&#xff08;列表&#xff09; 特點&#xf…