Dart 中的聚合类型与容器类型详解

Dart 中的聚合类型与容器类型详解

在 Dart 中,聚合类型(Aggregate Types)容器类型(Container Types) 是指能够存储和管理一组数据的类型。它们的核心功能是将多个元素组合成一个整体,便于统一操作和管理。尽管这两个术语有时会被混用,但可以这样理解:

  • 聚合类型:强调数据结构的"聚合"特性,即由多个元素组合而成的类型(如数组、列表、集合等)。
  • 容器类型:更广泛的概念,指能够"容纳"其他对象或数据的结构(如列表、集合、映射、队列等)。

Dart 提供了多种容器类型,最核心的包括 List、Set、Map ,以及一些衍生类型(如 Queue)。以下是详细说明:

1. 核心容器类型详解

1.1 List(列表)

List 是一种有序、可重复、可变 的集合,通过索引访问元素,类似于数组。

特性
  • 有序性 :元素按插入顺序存储,可通过索引(从 0 开始)访问。
  • 可重复性:允许存储重复元素。
  • 可变性 :默认支持增删改操作,但可通过 const 声明不可变列表。
声明与初始化
dart 复制代码
// 可变列表
List<int> numbers = [1, 2, 3]; // 显式类型
var strings = <String>['a', 'b', 'c']; // 类型推导

// 不可变列表(使用 const)
const immutableList = const [4, 5, 6]; // 无法修改
常用操作
方法/属性 说明 示例
add(element) 在列表末尾添加元素。 numbers.add(4);[1, 2, 3, 4]
insert(index, element) 在指定位置插入元素。 numbers.insert(0, 0);[0, 1, 2, 3, 4]
remove(element) 移除第一个匹配的元素。 numbers.remove(2);[1, 3, 4]
removeAt(index) 移除指定索引的元素。 numbers.removeAt(0);[2, 3, 4]
length 获取列表长度。 print(numbers.length);4
[] 通过索引访问或修改元素。 numbers[0] = 10;[10, 1, 2, 3]
addAll(iterable) 将另一个集合的元素追加到列表末尾。 numbers.addAll([5, 6]);[1, 2, 3, 5, 6]

1.2 Set(集合)

Set 是一种无序、不可重复、可变的集合,用于存储唯一元素。

特性
  • 无序性:元素存储顺序不固定,遍历时可能与插入顺序不同。
  • 唯一性:不允许重复元素。
  • 可变性 :默认支持增删操作,但可通过 const 声明不可变集合。
声明与初始化
dart 复制代码
// 可变集合
Set<String> fruits = {'apple', 'banana', 'orange'}; // 显式类型
var uniqueNumbers = <int>{1, 2, 3}; // 类型推导

// 不可变集合(使用 const)
const immutableSet = const {'apple', 'banana'}; // 无法修改
常用操作
方法/属性 说明 示例
add(element) 添加元素,若已存在则返回 false fruits.add('grape');{'apple', 'banana', 'orange', 'grape'}
remove(element) 移除指定元素。 fruits.remove('banana');{'apple', 'orange', 'grape'}
contains(element) 检查元素是否存在。 fruits.contains('apple');true
addAll(iterable) 合并另一个集合的元素(重复元素会被忽略)。 fruits.addAll({'apple', 'mango'});{'apple', 'mango', ...}

1.3 Map(映射)

Map 是一种键值对(Key-Value) 的无序集合,通过快速查找值。键必须唯一,但值可以重复。

特性
  • 无序性:元素存储顺序不固定。
  • 唯一性:键必须唯一,但值可以重复。
  • 快速查找:通过键查找值的时间复杂度为 O(1)。
声明与初始化
dart 复制代码
// 可变映射
Map<String, int> ageMap = {'Alice': 30, 'Bob': 25}; // 显式类型
var scores = <String, double>{'Math': 90.5, 'Science': 85.0}; // 类型推导

// 不可变映射(使用 const)
const immutableMap = const {'name': 'Alice', 'age': 30}; // 无法修改
常用操作
方法/属性 说明 示例
putIfAbsent(key, ifAbsent) 如果键不存在,则添加键值对;否则返回现有值。 ageMap.putIfAbsent('Charlie', () => 20); → 新增键 'Charlie'
remove(key) 移除指定键的条目。 ageMap.remove('Bob'); → 移除键 'Bob'
containsKey(key) 检查是否存在指定键。 ageMap.containsKey('Alice');true
addAll(map) 合并另一个 Map 的键值对(重复键会被覆盖)。 ageMap.addAll({'Alice': 35}); → 键 'Alice' 的值被更新为 35

2. 其他容器类型

2.1 Queue(队列)

Queue 是一种先进先出(FIFO)的容器,需导入 dart:collection

dart 复制代码
import 'dart:collection';

void main() {
  Queue<int> queue = Queue();
  queue.add(1);
  queue.add(2);
  print(queue.removeFirst()); // 输出 1
  print(queue.first); // 输出 2
}

3. 容器类型的共同特性

所有容器类型(List、Set、Map)都实现了 Iterable 接口,支持以下操作:

  • 遍历

    dart 复制代码
    numbers.forEach((num) => print(num));
    for (var fruit in fruits) { ... }
  • 转换与筛选

    dart 复制代码
    var doubled = numbers.map((x) => x * 2); // [2, 4, 6, 8]
    var even = numbers.where((x) => x.isEven); // 过滤偶数
    var sum = numbers.reduce((a, b) => a + b); // 求和

4. 对比表格:快速选择容器类型

类型 有序性 可重复性 存储形式 适用场景
List 索引访问 需要有序、可重复的元素集合
Set 唯一元素集合 需要去重的场景
Map ✅(值可重复) 键值对(键唯一) 需要通过键快速查找值的场景
Queue 先进先出(FIFO) 需要队列操作的场景(如任务队列)

5. 注意事项

  1. 不可变容器

    • 通过 const 声明的容器(如 const Listconst Set)无法修改。
    • 示例:const colors = const ['red', 'green', 'blue'];
  2. 类型安全

    • 始终使用类型注解(如 List<int>)确保数据一致性。
  3. 性能考量

    • List 的索引访问是 O(1),但频繁插入/删除中间元素可能效率较低。
    • Map 的键查找是 O(1),适合需要快速查找的场景。

6. 示例代码

dart 复制代码
void main() {
  // List 示例
  List<int> numbers = [1, 2, 3];
  numbers.add(4);
  print(numbers[0]); // 输出 1

  // Set 示例
  Set<String> fruits = {'apple', 'banana'};
  fruits.add('grape');
  print(fruits.contains('apple')); // true

  // Map 示例
  Map<String, int> ageMap = {'Alice': 30};
  ageMap['Bob'] = 25;
  print(ageMap['Alice']); // 30
}

总结

  • 聚合类型容器类型 在 Dart 中通常指能存储一组数据的结构,核心类型为 ListSetMap
  • 根据需求选择:
    • 有序、可重复List
    • 去重、无序Set
    • 键值对快速查找Map
  • 充分利用容器的共同特性(如迭代、转换)和不可变性,提升代码健壮性。

相关推荐
BillKu7 分钟前
scss(sass)中 & 的使用说明
前端·sass·scss
疯狂的沙粒11 分钟前
uni-app 项目支持 vue 3.0 详解及版本升级方案?
前端·vue.js·uni-app
Jiaberrr20 分钟前
uniapp Vue2 获取电量的独家方法:绕过官方插件限制
前端·javascript·uni-app·plus·电量
谢尔登1 小时前
【React】React 18 并发特性
前端·react.js·前端框架
Joker`s smile1 小时前
使用React+ant Table 实现 表格无限循环滚动播放
前端·javascript·react.js
国家不保护废物1 小时前
🌟 React 魔法学院入学指南:从零构建你的第一个魔法阵(项目)!
前端·react.js·架构
import_random1 小时前
[机器学习]svm支持向量机(优势在哪里)
前端
国家不保护废物1 小时前
从刀耕火种到现代框架:DOM编程 vs Vue/React 进化史
前端·vue.js·react.js
陈随易1 小时前
Univer v0.8.0 发布,开源免费版 Google Sheets
前端·后端·程序员
不怎么爱学习的dan1 小时前
实现 ECharts 多国地区可视化方案
前端