官方文档

Dart has built-in support for list, set, and map collections. To learn more about configuring the types collections contain, check out Generics.
译文:Dart内置了对list、set和map集合的支持。要了解有关配置集合包含的类型的更多信息,请查看泛型。

非常常规,几乎一致。

List

Perhaps the most common collection in nearly every programming language is the array, or ordered group of objects. In Dart, arrays are List objects, so most people just call them lists.
Dart list literals are denoted by a comma-separated list of elements enclosed in square brackets ([]). Each element is usually an expression
译文:在几乎所有编程语言中,最常见的集合可能是数组,即有序对象组。在Dart中,数组是列表对象,所以大多数人称之为列表。
Dart列表字面量由逗号分隔的元素列表表示,这些元素被括在方括号([])中。每个元素通常是一个表达式。

看例子:

var list = [1, 2, 3];

在这里插入图片描述
在java中array和ArrayList,其实不是一个东西,而且java中的List是个接口,而dart中[]就是List而且可以直接实例化。

You can add a comma after the last item in a Dart collection literal. This trailing comma doesn’t affect the collection, but it can help prevent copy-paste errors.
译文:可以在Dart集合字面量的最后一项后面添加逗号。后面的逗号对集合没有影响,但它有助于防止复制粘贴错误。

看下面的例子

  var list = [1, 2, 3,];
  //可以在Dart集合字面量的最后一项后面添加逗号。后面的逗号对集合没有影响,但它有助于防止复制粘贴错误。

Lists use zero-based indexing, where 0 is the index of the first element and list.length - 1 is the index of the last element. You can get a list’s length using the .length property and access a list’s elements using the subscript operator ([])
译文:列表使用从0开始的索引,其中0是第一个元素和列表的索引。Length - 1是最后一个元素的索引。可以通过**.length()**获得列表的长度。使用下标操作符([])访问列表中的元素。

这部分也很像kotlin的写法,看例子

  var list = [1, 2, 3,];//可以在Dart集合字面量的最后一项后面添加逗号。后面的逗号对集合没有影响,但它有助于防止复制粘贴错误。
  print(list.length);//3
  print(list[0]);//1
  print(list[1]);//2
  print(list[2]);//3

To create a list that’s a compile-time constant, add const before the list literal:
要创建一个编译时常量的列表,在列表字面量之前添加const:

这是一个全新的东西,Android的final只是表示对象不可变,而dart限制了list中的所有元素不可变。

看例子:
在这里插入图片描述
当我对list中的元素重新赋值时,发生了运行时错误,虽然编译可以通过。
接下来回顾一下,我们如果希望实现类似final的作用 需要怎么处理呢?
在这里插入图片描述
final和const都可以实现,如果你忘记了这两个的区别可以回去在看看常量的定义。

前面我们都是使用类型推断来创建列表的,那么如果我想创建一个string类型的列表,该如何做呢?

  var grains = <String>[];

下面列出list的常用函数:

var grains = <String>[];
  grains.add("a");
  grains.addAll(["b", "c"]);//添加一个列表到源列表的末尾
  var index = grains.indexOf("b");//返回第一个匹配项的索引。如果没有匹配项,则返回-1。
  grains.removeAt(index);//删除指定索引的元素。
  grains.remove("b");//删除第一个匹配项。如果没有匹配项,则不执行任何操作。
  print(grains);//[a, b, c]
  print(grains.length);//3
  grains.clear();//删除所有元素。
  print(grains);//[]
  var vegetables = List.filled(99, 'broccoli', growable: true);//创建一个定长列表,99代码list长度,'broccoli'代表默认list元素,growable: true代码list是否可增长,默认为fasle。
  vegetables[vegetables.length-1] = "b";
  vegetables.add("c");//当growable为true时,可添加元素到列表末尾。为false时,添加元素会抛出异常。
  print(vegetables);//[broccoli...b,c]
...

### sort排序
>Sort a list using the sort() method. You can provide a sorting function that compares two objects. This sorting function must return < 0 for smaller, 0 for the same, and > 0 for bigger. 
>译文:使用方法Sort()对列表排序。你可以提供一个排序函数来比较两个对象。这个排序函数必须返回 < 0表示小,返回0表示相同,返回>0表示大。

看例子

```dart
  var strList = ["aaaa", "bb", "ccc"];
  strList.sort((a, b)=> a.length.compareTo(b.length));//按字符串长度排序。
  print(strList);//[bb, ccc, aaaa]

Set

A set in Dart is an unordered collection of unique elements. Dart support for sets is provided by set literals and the Set type.
译文:Dart中的集合(set)是一组唯一元素的无序集合。Dart对集合的支持是通过集合字面量和集合类型提供的。

学习到现在,我们也可以推断出来了字面量就是类型推断,或者直接声明。

看下面通过类型推断创建的set:

 var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};

花括号都快被玩出花了,稍微有点不太好理解了。
下面是通过类型声明定义的set:
在这里插入图片描述

常用的函数和list基本雷同就不多介绍了。

Map

In a map, each element is a key-value pair. Each key within a pair is associated with a value, and both keys and values can be any type of object. Each key can occur only once, although the same value can be associated with multiple different keys. Dart support for maps is provided by map literals and the Map type.
译文:在map中,每个元素都是一个键值对。键对中的每个键都与一个值相关联,键和值都可以是任何类型的对象。尽管同一个值可以关联到多个不同的键,但每个键只能出现一次。Dart对MAp的支持是通过map字面量和map类型提供的。

直接看例子:

 var gifts = {
    // Key:    Value
    'first': 'partridge',
    'second': 'turtledoves',
    'fifth': 'golden rings',
  };
  
  var gifts2 = <String, String>{};

对map中添加值、改变原有的值、读取键的值:

  var gifts = {
    // Key:    Value
    'first': 'partridge',
    'second': 'turtledoves',
    'fifth': 'golden rings',
  };
  gifts["a"] = 'b';//添加键值对
    print(gifts);//{first: partridge, second: turtledoves, fifth: golden rings, a: b}
  gifts["a"] = 'c';//修改键a对应的值为c
    print(gifts);//{first: partridge, second: turtledoves, fifth: golden rings, a: c}
      print(gifts["a"]);//c


Collections elements

Expression elements & Map entry elements

An expression element evaluates a single expression and inserts the resulting value into a collection. This expression can encompass various constructs like literals, variables, operators, function calls, and constructor calls.
译文:表达式元素计算单个表达式的值,并将结果插入到集合中。这个表达式可以包含各种结构,如字面量、变量、操作符、函数调用和构造函数调用。
A map entry element evaluates a pair of key and value expressions and inserts the resulting entry into a collection. Both the key and the value within this pair can be expressions
map条目元素对键值表达式对求值,并将结果条目插入到集合中。这个对中的键和值都可以是表达式。

看例子:

  var a = 2;
  var b = 1;
  var list = <int>[];
  list.add(a);
  list.add(a-b);
  list.add(a > b ? 4:5);
  list.add(getTen());

  var map = <int, int> {};
  map[a] = b;
  map[getTen()] = a;

Null-aware elements

A null-aware element evaluates an expression and if the result is not null, inserts the value into the surrounding collection.
译文:能够识别null的元素计算表达式,如果结果不是null,就将值插入到周围的集合中。

此特性需要sdk最低版本3.8.0及以上
看例子:

  int? absentValue = null;
  int? presentValue = 3;
  var items = [
    1,
    ?absentValue,//null
    ?presentValue,
    absentValue,
    5,
  ]; // [1, 3, null, 5]

当?在值的前面时,表示如果后面的值为null,则跳过此元素。
map同理,且对于键值都有效果:

String? presentKey = 'Apple';
String? absentKey = null;

int? presentValue = 3;
int? absentValue = null;

var itemsA = {presentKey: absentValue}; // {Apple: null}
var itemsB = {presentKey: ?absentValue}; // {}

var itemsC = {absentKey: presentValue}; // {null: 3}
var itemsD = {?absentKey: presentValue}; // {}

var itemsE = {absentKey: absentValue}; // {null: null}
var itemsF = {?absentKey: ?absentValue}; // {}

Spread elements

支持展开语法,案例如下:

 var a = [1, 2, null, 4];
  var items = [0, ...a, 5]; // [0, 1, 2, null, 4, 5]

map同理

 var map = {"a":"b"};
  var map2 = {"a":"c", ...map};
  print(map2);//{a: b} map展开后的元素覆盖了a:c

Null-aware spread elements

上面两个个知识点的结合,当被展开的集合可能为null时使用
…?

  var a = [1, 2, null, 4];
  List<int>? b = null;
  var items = [0, ...a, ...?b,5];
  print(items);//[0, 1, 2, null, 4, 5]

下面演示一个错误案例,当list可能为null时,必须使用…?

List<String> buildCommandLine(
  String executable,
  List<String> options, [
  List<String>? extraOptions,
]) {
  return [
    executable,
    ...options,
    ...extraOptions, // <-- Error
      //  ...?extraOptions, // <-- OK now.

  ];
}

// Usage:
//   buildCommandLine('dart', ['run', 'my_script.dart'], null);
// Result:
//   Compile-time error

If elements

可以直接在list中添加if节点,如果条件为假,则可以选择评估另一个else元素。
注意这里的选择,即可以只有一个if节点。
案例如下:

  var a = [1, 2, null, 4, if(3>2) 3];
  var map = {"a": 2, if(3>2) "b":2 else if(4 > 5) "c": 3 else "d": 4, };

var word = 'hello';
var items = [
  1,
  if (word case String(length: var wordLength)) wordLength,
  3,
]; // [1, 5, 3]

var orderDetails = ['Apples', 12, ''];
var summary = [
  'Product: ${orderDetails[0]}',
  if (orderDetails case [_, int qty, _]) 'Quantity: $qty',
  if (orderDetails case [_, _, ''])
    'Delivery: Not Started'
  else
    'Delivery: In Progress',
]; // [Product: Apples, Quantity: 12, Delivery: Not Started]

For elements

同时支持在集合中,增加for节点,案例如下:

var numbers = [2, 3, 4];
var items = [1, for (var n in numbers) n * n, 7]; // [1, 4, 9, 16, 7]

var items = [1, for (var x = 5; x > 2; x--) x, 7]; // [1, 5, 4, 3, 7]

Nest control flow elements

可以相互嵌套控制流元素
案例如下:

var numbers = [1, 2, 3, 4, 5, 6, 7];
var items = [
  0,
  for (var n in numbers)
    if (n.isEven) n,
  8,
]; // [0, 2, 4, 6, 8]

您可以将各种元素嵌套到任意深度。在以下示例中,if、for和扩展元素在集合中相互嵌套:

var nestItems = true;
var ys = [1, 2, 3, 4];
var items = [
  if (nestItems) ...[
    for (var x = 0; x < 3; x++)
      for (var y in ys)
        if (x < y) x + y * 10,
  ],
]; // [10, 20, 30, 40, 21, 31, 41, 32, 42]

结语

相较于 Java 或 Kotlin 中细分的集合类型,Dart 的集合设计更为简洁统一。这种简洁性源于语言层面的合理预设:例如,List 默认采用动态数组实现,旨在降低开发者的选择负担,提升开发体验与效率。

此外,Dart 集合原生支持空安全、条件插入、元素跳过等常见逻辑,配合函数式方法(如 where、map),能够以极简的语法实现复杂的集合操作,显著提升了代码的简洁性与表达力。

当然,这种便利性也伴随着潜在风险。若使用不当,例如在频繁增删或数据量极大的场景中,动态数组可能因自动扩容或元素搬移而产生性能开销,甚至导致内存浪费。因此,如何在实际项目中合理运用集合,平衡简洁与性能,仍是一个需要在实践中不断积累经验的课题。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐