dart

Dart 基础 – 内置类型 – Set 集合

内容纲要

版权归作者 ©刘龙宾 所有,本文章未经作者允许,禁止私自转载!

在 Dart 中,Set 是一个无序的、元素唯一的集合。

由于 Set 是无序的,所以无法List 数组那样通过索引(下标)获取 Set 中的元素。

1. 创建 Set 集合

1.1 基于字面量创建 Set

温馨提示:尽管 Set 类型(type) 一直都是 Dart 的一项核心功能,但是 Set 字面量(literals) 是在 Dart 2.2 中才加入的。

1.1.1 强类型的 Set

声明 Set 字面量的语法是 <类型>{}。这里需要特别提醒下,左侧的 <类型> 是必须的,如果省略了类型,只写了 {},那么会被 Dart 编译成 Map 的字面量。下面的代码演示了如何声明 Set 字面量:

void main(List<String> args) {
  // 1. 声明字符串类型的 Set 集合
  var names = <String>{'liulongbin', 'escook'};

  // 2. 向 Set 中添加重复的元素
  names.add('liulongbin');

  // 3. 由于 Set 中的元素具有唯一性,所以重复添加的元素会被屏蔽
  // 输出 {liulongbin, escook}
  print(names);
}

1.1.2 dynamic 的 Set

强类型的 Set 只能添加类型相同的元素,如果想创建 dynamic 类型的 Set,推荐使用 <dynamic>{} 的方式。示例代码如下:

void main(List<String> args) {
  // 1. 创建动态类型的 Set,可以向集合中插入任何类型的元素
  var names = <dynamic>{'liulongbin', 666};

  // 2. 输出 {liulongbin, 666}
  print(names);
}

1.2 基于构造函数创建 Set

1.2.1 Set<类型>.identity()

Set 集合的 identity 构造函数,用来创建空白的 Set 集合。如果指定了类型,则是强类型的 Set;如果省略了 <类型> 或提供的类型是 <dynamic>,则创建的是动态类型的 Set。示例代码如下:

void main(List<String> args) {
  // 1.1 创建 String 强类型的空 Set
  var names = Set<String>.identity();

  // 1.2 添加元素
  names.add('liulongbin');
  names.add('escook');

  // 1.3 输出 {liulongbin, escook}
  print(names);

  // ----

  // 2.1 创建动态类型的 Set
  var sets = Set<dynamic>.identity();

  // 2.2 添加字符串、数字、布尔元素
  sets.add('liulongbin');
  sets.add(666);
  sets.add(true);

  // 2.3 输出 {liulongbin, 666, true}
  print(sets);
}

1.2.2 Set<类型>.from(可迭代的集合)

调用 from 构造函数,可以根据给定的元素集合,生成对应的 Set 集合。示例代码如下:

void main(List<String> args) {
  // 1. 声明 int 类型的数组,里面包含重复的元素
  var list = <int>[1, 2, 3, 2, 1];
  // 2. 调用 Set.form() 生成 Set 集合
  var sets = Set<int>.from(list);
  // 3. 输出 {1, 2, 3},重复的元素会被过滤掉
  print(sets);
}

1.2.3 Set<类型>.unmodifiable(可迭代的集合)

调用 unmodifiable 构造函数,可以根据给定的元素集合,创建出一个不可修改的 Set 集合,不允许修改集合中的元素信息。示例代码如下:

void main(List<String> args) {
  // 1. 声明 int 类型的数组,里面包含重复的元素
  var list = <int>[1, 2, 3, 2, 1];
  // 2. 调用 Set.form() 生成 Set 集合
  var sets = Set<int>.unmodifiable(list);
  // 3. 输出 {1, 2, 3},重复的元素会被过滤掉
  print(sets);

  // 4. 删除,添加等操作会报错
  // 报错:Cannot change an unmodifiable set
  // sets.remove(1);
  // sets.add(4);
}

2. 操作 Set 元素

2.1 添加元素

可以调用 addaddAll 方法向 Set 中添加元素。示例代码如下:

void main(List<String> args) {
  // 1. 定义 Set 集合
  var colors = <String>{'red'};

  // 2. 单个添加元素
  colors.add('green');

  // 3. 一次性添加多个元素
  colors.addAll(['blue', 'purple', 'cyan']);

  // 输出 {red, green, blue, purple, cyan}
  print(colors);
}

2.2 移除元素

调用 removeremoveAll 方法可以从集合中移除元素,示例代码如下:

void main(List<String> args) {
  // 1. 定义 Set 集合
  var colors = <String>{'red', 'blue', 'cyan', 'purple', 'orange'};

  // 2. 移除单个元素
  colors.remove('blue');
  // 3. 输出 {red, cyan, purple, orange}
  print(colors);

  // 4. 一次性移除多个元素
  colors.removeAll(['cyan', 'purple']);
  // 5. 输出 {red, orange}
  print(colors);
}

2.3 清空元素

调用 clear 方法可以清空 Set 集合中的元素,示例代码如下:

void main(List<String> args) {
  // 1. 定义 Set 集合
  var colors = <String>{'red', 'blue', 'cyan'};

  // 2. 调用 clear 方法清空 Set
  colors.clear();

  // 3. 输出 true,证明集合已被清空
  print(colors.isEmpty);
}

3. Set 常用方法

3.1 是否包含对应的元素

  1. contains 用来判断是否包含单个元素
  2. containsAll 用来判断是否包含所有指定的元素

示例代码如下:

void main(List<String> args) {
  // 1. 定义 Set 集合
  var colors = <String>{'red', 'blue', 'cyan'};

  print(colors.contains('red')); // true
  print(colors.contains('white')); // false
  print(colors.containsAll(['red', 'blue'])); // true
  print(colors.containsAll(['red', 'white'])); // false
}

3.2 difference

集合A.difference(集合B) 循环集合A中的每个元素,如果当前循环的元素不包含在集合B中,则把当前元素收集到一个新 Set 中返回。示例代码如下:

void main(List<String> args) {
  var colorsA = <String>{'red', 'blue', 'cyan', 'orange'};
  var colorsB = <String>{'blue', 'white', 'black', 'cyan'};

  var diff = colorsA.difference(colorsB);
  // 输出 {red, orange}
  print(diff);
}

3.3 intersection

intersection 方法用来提取两个集合相交(共有)的元素,示例代码如下:

void main(List<String> args) {
  var colorsA = <String>{'red', 'blue', 'cyan', 'orange'};
  var colorsB = <String>{'blue', 'white', 'black', 'cyan'};

  var result = colorsA.intersection(colorsB);
  // 输出 {blue, cyan}
  print(result);
}

3.4 union

union 方法用来合并两个 Set 集合,并返回合并后的新 Set 集合,示例代码如下:

void main(List<String> args) {
  var colorsA = <String>{'red', 'blue', 'cyan', 'orange'};
  var colorsB = <String>{'blue', 'white', 'black', 'cyan'};

  var result = colorsA.union(colorsB);
  // 输出 {red, blue, cyan, orange, white, black}
  print(result);
}

3.5 lookup

lookup 方法用来从 Set 集合中查找对应的元素,如果找不到就返回 null,如果找到了就返回这个元素。示例代码如下:

void main(List<String> args) {
  var colorsA = <String>{'red', 'blue', 'cyan', 'orange'};

  var result1 = colorsA.lookup('red');
  // 能找到,输出 red
  print(result1);

  var result2 = colorsA.lookup('black');
  // 找不到,输出 null
  print(result2);
}

3.6 retainAll

集合A.retainAll(集合B) 从 Set 集合A中保留集合B中的所有元素,不包含在集合B中的元素将从集合A中移除。示例代码如下:

void main(List<String> args) {
  var colorsA = <String>{'red', 'blue', 'cyan', 'orange'};

  // 注意:retainAll 方法会修改原集合 colorsA
  colorsA.retainAll(['red', 'blue']);
  // 输出 {red, blue}
  print(colorsA);
}

3.7 retainWhere

retainWhere 方法可以把符合 where 条件的元素保留下来,去除不符合条件的元素。示例代码如下:

void main(List<String> args) {
  var colorsA = <String>{'red', 'blue', 'cyan', 'orange'};

  // 把符合条件的元素保留下来
  colorsA.retainWhere((element) => element.contains('e'));
  // 输出 {red, blue, orange}
  print(colorsA);
}

3.8 join

join 方法用来根据指定的字符串拼接集合中的所有元素,并返回拼接的结果。示例代码如下:

void main(List<String> args) {
  var colorsA = <String>{'red', 'blue', 'cyan', 'orange'};

  // 根据指定的字符串拼接 Set 中的每个元素
  var result = colorsA.join(', ');
  // 输出字符串 red, blue, cyan, orange
  print(result);
}

3.9 Set 中的 if 和 for

Set 集合中支持使用 iffor,用法和 List 数组相同,示例代码如下:

void main(List<String> args) {
  // 定义布尔变量
  var flag = true;

  var sets = <dynamic>{
    'red',
    // Set 中的 if
    if (flag) 'cyan',
    // Set 中的 for
    for (var i = 0; i < 3; i++) '#${i}'
  };

  // 输出 {red, cyan, #0, #1, #2}
  print(sets);
}

关于 Set 集合的更多用法,请参考 Set 的官方文档

版权归作者 ©刘龙宾 所有,本文章未经作者允许,禁止私自转载!

一个自由の前端程序员

留言

您的电子邮箱地址不会被公开。 必填项已用 * 标注