集合(Collections)
Dart 带有一个核心集合API,其中包括列表(list)、集合(set)和映射(map)的类
List(列表)
// 1.创建列表
// 1) 字面量创建
var list1 = [];
List list2 = [1,2,"a","dart"];
// 2) 通过类构造方法创建
var list3 = List();
// 2. 基本操作
// 1) 增
list1.add("value");
list1.add(88);
list3.insert(0, 1);
list3.insert(0, 2);
list3.insert(1, 3);
// 2) 删除
list2.remove("dart");
list2.removeAt(0);
list2.removeLast();
// 3) 修改
list2.replaceRange(0, 2, ["Java","C"]);
// 4) 查看
print(list2[0]);
print(list2[1]);
print(list2.first);
print(list2.last);
print(list2.length);
print(list2.indexOf(2) == 0);
// 3. 其他操作
// 拼接数组元素
print(list2.join(","));
// 列表合并
var tmpList = [1,2,3,4];
// print(list2 + tmpList); 使用"+"操作符
list2.addAll(tmpList);
print(list2);
列表的6种构造方法
(过时,参考 升级到Dart 2.14) 创建给定长度的列表List([int length])List.filled(int length, E fill, {bool growable: false})创建给定长度并指定填充元素的列表List.from(Iterable elements, {bool growable: true})创建一个包含所有可迭代元素的列表List.generate(int length, E generator(int index), {bool growable: true})创建一个包含所有生成器返回值的列表List.of(Iterable<E> elements, {bool growable: true})从给定的可迭代元素创建一个列表List.unmodifiable(Iterable elements)创建一个包含所有可迭代元素的不可修改的列表
示例:
// 从已有的列表创建一个新的列表 of、from
List<int> list1 = <int>[1,2,3,4,5];
var list2 = List.from(list1);
var list3 = List.of(list1);
// 查看of和from的区别
print(list2.runtimeType);
print(list3.runtimeType);
// 指定填充元素
var list4 = List.filled(5, 1);
print(list4);
// 根据条件生成一个新的列表: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
var list5 = List.generate(10, (i){
return (i*2).toString();
});
var list6 = List.unmodifiable([0,2,4,6,8]);
// 修改列表会报错:Unsupported operation: Cannot add to an unmodifiable list
// list6[0] = 99;
// list6.add(100);
注意:
of和from两个构造方法的区别- 构造方法中
growable参数的作用 - 使用
filled构造方法将对象类型作为填充元素的坑
列表的其他操作
// 根据条件从列表中筛选元素
var list7 = [1,2,3,"4","5","6"].where((el){
if(el.runtimeType == String) return true;
return false;
});
print(list7.toList());
// 列表元素的类型转换
var list8 = [2,4,6,8];
var list9 = list8.map((el)=> el.toDouble());
print(list9.toList());
// 列表遍历
list9.forEach(print);
更多API 参见 Dart语言的 List文档
映射(Map)
通常被称为字典或关联数组,是键-值对的无序集合,相当于Java中的HashMap。与JavaScript不同,Dart的对象不是映射。
Map()使用默认实现 LinkedHashMap 创建一个Map实例Map.from(Map other)从另一个Map创建一个包含所有键值对的新MapMap.fromEntries(Iterable<MapEntry<K, V>> entries)创建一个包含所有entries的新的MapMap.fromIterable(Iterable iterable, {K key(dynamic element), V value(dynamic element)})创建一个Map实例,其中的键和值是从 iterable中计算得到Map.fromIterables(Iterable<K> keys, Iterable<V> values)创建一个Map实例,将给定关联keys到valuesMap.identity()使用默认实现创建一个基于身份的映射。Map.of(Map<K, V> other)从另一个Map创建一个新的Map对象Map.unmodifiable(Map other)创建一个不可修改的映射
Map的默认实现类是LinkedHashMap,除此外,还有HashMap、 HttpSession、 LinkedHashMap、 MapMixin、 MapView等实现类。其中最常用的是LinkedHashMap和HashMap,这两者的主要区别在于保存的键值对是否有序,遍历前者是有序的,如果你不关心键值对的插入顺序,可以直接使用HashMap。
Map m1 = {"name":"Bruce",
"number":[110,119,120],
"addr":{"d1":"xxx"}};
// Map的遍历
m1.forEach((key,value){
print("$key = $value");
});
// 根据条件删除元素
m1.removeWhere((k,v){
return k == "name";
});
// Map元素的类型转换
Map m2 = <String,int>{"a":1,"b":2};
print(m2.runtimeType);
var m3 = m2.map((k,v){
return MapEntry<String,String>(k,v.toString());
});
print(m3.runtimeType);
集合(Set)
Dart中的Set与Java类似,是一组无序的集合,其中每个元素只能出现一次。因为集合是无序的,所以不能通过索引获得集合的项。
Set()创建一个空的SetSet.from(Iterable elements)创建一个包含所有Iterable元素的集合Set.identity()创建一个空的identity 集合Set.of(Iterable<E> elements)从给定的Iterable元素创建一个新集合
var mySets = Set();
mySets.addAll(['gold', 'titanium', 'xenon']);
assert(mySets.length == 3);
// 添加重复元素是无效的
mySets.add('gold');
assert(mySets.length == 3);
// 删除一个元素
mySets.remove('gold');
assert(mySets.length == 2);
使用contains()和containsAll()来检查集合中是否包含一个或多个元素
var mySets = Set();
mySets.addAll(['gold', 'titanium', 'xenon']);
assert(mySets.contains('titanium'));
assert(mySets.containsAll(['titanium', 'xenon']));
交集是一个集合,其项在另外两个集合中。
var mySets = Set();
mySets.addAll(['gold', 'titanium', 'xenon']);
// 创建两个集合的交集
var nobleGases = Set.from(['xenon', 'argon']);
var set2 = mySets.intersection(nobleGases);
assert(set2.length == 1);
assert(set2.contains('xenon'));
关于Set的更多用法,参见 Set文档
集合类型的通用方法
// 使用isEmpty或isNotEmpty检查是否包含有元素
var coffees = [];
var teas = ['green', 'black', 'chamomile', 'earl grey'];
assert(coffees.isEmpty);
assert(teas.isNotEmpty);
// 遍历.注意,在Map上调用时,函数必须接受两个参数(键和值)
teas.forEach((tea) => print('I drink $tea'));
// Iterable提供map()方法,可以在一个对象中提供所有结果
var loudTeas = teas.map((tea) => tea.toUpperCase());
loudTeas.forEach(print);
注意:map()返回的对象是一个可迭代的、延迟求值的对象,而不是集合对象本身,可以使用
map().toList()或map().toSet()进行转换
var loudTeas =
teas.map((tea) => tea.toUpperCase()).toList();
公众号“编程之路从0到1”