前言
集合 —— 操作批量数据的核心工具
在日常生活中,我们经常遇到需要批量处理的数据,例如一个班级里有很多学生、每个班级有学生的花名册、学生考试后有成绩表等。如何高效地管理和维护这些结构相似的批量数据是编程中非常重要的课题。在编程术语中,可以称这样的数据为集合类型或复合数据类型。在 Dart 中,最常用的三种集合类型分别是:列表(List)、集合(Set) 和 映射(Map)。
接来下来我们一起开启探索列表(List)的神奇之旅。
操千曲而后晓声,观千剑而后识器。虐它千百遍方能通晓其真意。
一、基本概念
1.1、图像表示
| 序号 | 姓名 |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
| 4 | David |
如上图所示,有一个班级的学生名单,按学号顺序排列。可以轻松找到第一个、第二个,甚至最后一个学生的名字。这就是 List 的工作方式 —— 它是一个有序的元素序列,可以重复存储相同的元素,并且可以根据位置(索引)快速访问或修改任何元素。
1.2、定义
List是一个基于动态数组实现的数据结构,它可以存储相同类型或不同类型的元素。List 是有序的,这意味着每个元素都有一个固定的索引位置,可以通过索引来快速访问或修改这些元素(随机访问)。
// 创建一个 List
List<String> names = ['Alice', 'Bob', 'Charlie','David'];
1.3、特点
- 1、有序:就像班级里的学生名单,每个学生的
顺序是固定的。 - 2、允许重复:如果某个学生在不同的活动中多次出现,比如参加多个社团,名字可以
重复出现在名单中。
// 学生名单
List<String> studentNames = ['Alice', 'Bob', 'Charlie', 'Alice'];
// 添加新学生
studentNames.add('David');
// 输出名单
print(studentNames); // 输出: [Alice, Bob, Charlie, Alice, David]
1.4、泛型支持
Dart 的 List 支持泛型,允许指定列表中元素的具体类型,从而提高代码的类型安全性和可读性。
// 创建一个泛型为int类型的list
List<int> numbers = [1, 2, 3, 4, 5];
// 创建一个泛型为String类型的list
List<String> names = ['Alice', 'Bob', 'Charlie', 'David'];
// 创建一个泛型为dynamic类型的list
List<dynamic> list = ['Alice', 1, false];
二、创建和初始化
2.1、直接创建
最简单的方式是直接在方括号[]中列出元素。
List<int> numbers = [1, 2, 3, 4, 5];
2.2、使用构造函数
使用 List 类的构造函数来创建一个空列表或具有固定长度的列表。
// 创建一个空列表
List<String> emptyList = List<String>.empty(growable: true);
// 创建一个固定长度的列表,所有元素初始为 null
List<int> fixedLengthList = List<int>.filled(5, 0);
2.3、使用List.generate
List.generate 构造函数可以根据提供的生成器函数创建一个列表。
List<int> generatedNumbers = List.generate(5, (index) => index * 2);
print(generatedNumbers); // 输出: [0, 2, 4, 6, 8]
三、访问和修改
3.1、访问元素
可以通过索引访问 List 中的元素,索引从 0 开始。
List<String> names = ['Alice', 'Bob', 'Charlie'];
print(names[0]); // 输出: Alice
3.2、修改元素
同样,可以通过索引修改 List 中的元素。
names[1] = 'Bobby';
print(names); // 输出: [Alice, Bobby, Charlie]
3.3、添加元素
- 1、添加到末尾:使用
add方法。
names.add('David');
print(names); // 输出: [Alice, Bobby, Charlie, David]
- 2、添加到指定位置:使用
insert方法。
names.insert(1, 'Betty');
print(names); // 输出: [Alice, Betty, Bobby, Charlie, David]
3.4、移除元素
- 1、移除指定元素:使用
remove方法。
names.remove('Betty');
print(names); // 输出: [Alice, Bobby, Charlie, David]
- 2、移除最后一个元素:使用
removeLast方法。
names.removeLast();
print(names); // 输出: [Alice, Bobby, Charlie]
- 3、清空列表:使用
clear方法。
names.clear();
print(names); // 输出: []
四、遍历
4.1、使用for循环
使用传统的for循环来遍历List。
for (int i = 0; i < numbers.length; i++) {
print(numbers[i]);
}
4.2、使用forEach
使用forEach来遍历List,简化遍历操作。
numbers.forEach((number) => print(number));
4.3、使用for-in循环
for-in 循环提供了一种简洁的遍历方式。
for (var number in numbers) {
print(number);
}
五、常用属性和方法
5.1、属性
// length:获取 List 的长度
print(numbers.length); // 输出: 5
// isEmpty 和 isNotEmpty:检查 List 是否为空。
print(emptyList.isEmpty); // 输出: true
5.2、常用方法
- 1、查找元素:使用
indexOf或contains方法。
print(numbers.indexOf(3)); // 输出: 2
print(numbers.contains(5)); // 输出: true
- 2、排序:使用
sort方法。
numbers.sort(); // 默认按升序排序
print(numbers); // 输出: [1, 2, 3, 4, 5]
- 3、转换:使用
map、where等高阶函数。
// map 方法用于对列表中的每个元素进行转换操作,并返回一个新的列表。
List<int> doubledNumbers = numbers.map((n) => n * 2).toList();
print(doubledNumbers); // 输出: [2, 4, 6, 8, 10]
//where方法用于根据指定的条件筛选出符合条件的元素,并返回一个新的列表。
List<int> evenNumbers = numbers.where((n) => n % 2 == 0).toList();
print(evenNumbers); // 输出: [2, 4]
六、不可变List(List.unmodifiable)
有时需要确保一个 List 不会被修改。可以使用 List.unmodifiable 来创建一个不可变的 List。
List<int> immutableNumbers = List.unmodifiable([1, 2, 3, 4, 5]);
// 下面这行代码会抛出异常,因为 immutableNumbers 是不可变的
// immutableNumbers.add(6);
七、总结
Dart 的 List 提供了丰富的功能和灵活的操作方式,使得处理有序数据变得非常方便。通过合理利用 List 的各种特性,可以编写出更加简洁、高效和易于维护的代码。
欢迎一键四连(
关注+点赞+收藏+评论)