Map
key-value
键值对(可以使用相关联的key
检索value
值)的集合, 即传说中的字典
Map
中key
的数量是有限的,每个key
正好有一个相关的value
Map
、以及它的键和值,都是可以迭代的, 迭代的顺序由Map
不同的类型定义
- 当
Map
的一个操作正在执行的时候,通常不允许修改Map
(添加或删除key
)
创建Map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Map()
Map.from(Map other)
Map.fromIterable(Iterable iterable, {K key(element), V value(element)})
Map.fromIterables(Iterable<K> keys, Iterable<V> values)
Map.identity()
Map.unmodifiable(Map other)
|
每一种创建方式的具体使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| var dic = new Map(); print(dic);
var dic1 = new Map.from({'name': 'titan'}); print(dic1);
List<int> list = [1, 2, 3];
var dic2 = new Map.fromIterable(list); print(dic2);
var dic3 = new Map.fromIterable(list, key: (item) => item.toString(), value: (item) => item * item); print(dic3);
List<String> keys = ['name', 'age']; var values = ['jun', 20];
var dic4 = new Map.fromIterables(keys, values); print(dic4);
var dic5 = new Map.identity(); print(dic5);
var dic6 = new Map.unmodifiable({'name': 'titan'}); print(dic6);
|
相关属性
Map
中相关属性和一些常用属性的操作如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| var map1 = {'name': 'titan', 'age': 20};
print(map1.hashCode);
print(map1.runtimeType);
print(map1.isEmpty);
print(map1.isNotEmpty);
print(map1.length);
print(map1.keys.toList());
print(map1.values.toList());
print(map1['name'] ?? '');
map1['age'] = 30; print(map1);
|
相关函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| var map2 = {'name': 'titan', 'age': 20};
map2.addAll({'blog': 'titanjun'}); print(map2);
print(map2.containsKey('age'));
print(map2.containsValue('titan'));
map2.forEach((key, value) { print('key = $key, value = $value'); });
for (var key in ['name', 'age', 'king']) { print(map2.putIfAbsent(key, () => key.length)); } print(map2);
print(map2.toString());
print(map2.remove('blog')); print(map2.remove('coder')); print(map2);
map2.clear(); print(map2);
|
Iterable
- 按顺序访问的值或元素的集合,
List
集合也是继承于Iterable
List
和Set
也是Iterable
,dart:collection
库中同样有很多
- 部分
Iterable
集合可以被修改
- 向
List
或Set
添加元素将改变对象所有包含的元素。
- 向Map添加新的
Key
会改变所有Map.keys
的元素。
- 在集合改变后,创建的迭代器将提供新的所有元素,并且可能会保持目前元素的顺序, 也可能不会
创建方式
1 2 3 4 5 6 7
| var ite = Iterable.empty(); print(ite);
var ite1 = Iterable.generate(5); print(ite1);
|
至于Iterable
的所有属性和函数的介绍和使用, 在上篇文章Flutter开发之Dart的数据类型01中的List
模块中已经详细介绍了, 因为List
是继承于Iterable
的, 所以Iterable
有的属性和方法List
中都有
Runes
- 在
Dart
中,Runes
代表字符串的UTF-32
字符集, 另一种Strings
Unicode
为每一个字符、标点符号、表情符号等都定义了 一个唯一的数值
- 由于
Dart
字符串是UTF-16
的字符序列,所以在字符串中表达32的字符序列就需要新的语法了
- 通常使用
\uXXXX
的方式来表示, 这里的XXXX
是4个16进制的数, 如,心形符号(♥)
是\u2665
- 对于非4个数值的情况,把编码值放到大括号中即可, 如,笑脸
emoji
(😆) 是\u{1f600}
String
类有一些属性可以提取rune
信息
codeUnitAt
和codeUnit
属性返回16为字符
- 使用
runes
属性来获取字符串的runes
信息
1 2 3 4
| var clapping = '\u{1f44f}'; print(clapping); print(clapping.codeUnits); print(clapping.runes.toList());
|
简单使用
1 2 3 4 5 6 7
| Runes runes = new Runes('\u2665, \u{1f605}, \u{1f60e}'); print(runes);
print(new String.fromCharCodes(runes));
|
由于Runes
也是继承于Iterable
, 所以Runes
中的属性和方法的使用也和Iterable
一样, 详情参考Runes和Flutter开发之Dart的数据类型01中的介绍
Symbols
- 一个
Symbol
对象代表Dart
程序中声明的操作符或者标识符
- 也许不会用到
Symbol
,但是该功能对于通过名字来引用标识符的情况 是非常有价值的,特别是混淆后的代码,标识符的名字被混淆了,但是Symbol
的名字不会改变
- 使用
Symbol
字面量来获取标识符的symbol
对象,也就是在标识符前面添加一个 #
符号
1 2 3 4 5 6 7
| var sym1 = Symbol('name'); print(sym1);
var sym2 = #titan; print(sym2);
|
Set
- 对象的集合,其中每个对象只能出现一次,
List
中一个对象可以出现多次
- 迭代Set中的元素时,某些时候有可能是无序的,也有可能是有序的。例如:
HashSet
是无序的,这意味着它迭代的顺序是不确定的
LinkedHashSet
按元素的插入顺序进行迭代
SplayTreeSet
按排序顺序迭代元素
Set
除创建方式和List
不同, 其他属性和方法基本一样
创建Set
1 2 3 4 5 6 7 8 9 10 11
| var set1 = Set(); print(set1);
var set2 = Set.from([1, 2, 3]); print(set2);
var set3 = Set.identity(); print(set3);
|
方法
1 2 3 4 5 6 7 8 9 10 11
|
var set4 = Set.from([2, 3, 5, 6]); print(set2.intersection(set4));
print(set2.union(set4));
print(set4.lookup(5)); print(set4.lookup(21));
|
其他更多属性参考Set和Flutter开发之Dart的数据类型01中的介绍
Duration
Duration
表示从一个时间点到另一个时间点的时间差
- 如果是一个较晚的时间点和一个较早的时间点,
Duration
可能是负数
创建Duration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Duration({int days: 0, int hours: 0, int minutes: 0, int seconds: 0, int milliseconds: 0, int microseconds: 0})
Duration ration = Duration(days: 1); print(ration); Duration ration1 = Duration(hours: 10); print(ration1);
Duration ration2 = Duration(days: 1, hours: 3); print(ration2);
Duration ration3 = Duration(days: 2, hours: 2, minutes: 23, seconds: 34, milliseconds: 56, microseconds: 89); print(ration3);
|
相关运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Duration time1 = Duration(days: 1, hours: 1, minutes: 1, seconds: 1, milliseconds: 1, microseconds: 1); Duration time2 = Duration(days: 2, hours: 2, minutes: 2, seconds: 2, milliseconds: 2, microseconds: 2); print(time1); print(time2);
print(time1 + time2);
print(time1 - time2);
print(time1 * 2);
print(time2 ~/ 3);
print(time1 > time2); print(time1 >= time2); print(time1 == time2); print(time1 < time2); print(time1 <= time2);
print(-time1); print(-(time1 - time2));
|
相关函数
1 2 3 4 5 6 7 8 9 10 11
| Duration time3 = -Duration(days: 1, hours: 1, minutes: 1, seconds: 1, milliseconds: 1, microseconds: 1); print(time3);
print(time3.abs());
print(time1.compareTo(time2));
print(time1.toString());
|
DateTime
- 表示一个时间点
- 通过构造函数或解析格式化的字符串创建
DateTime
对象,并且符合ISO 8601
标准的子集,小时是24小时制,范围在0-23之间
DateTime
对象创建之后,将是固定不变的, 不可被修改
DateTime
对象默认使用的是本地时区,除非显示地指定UTC
时区
创建时间点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| var date1 = new DateTime.now(); print(date1);
var date2 = new DateTime(2018, 10, 3, 12, 23, 34, 562, 1002); print(date2);
var date3 = new DateTime.fromMicrosecondsSinceEpoch(1000222);
var date31 = new DateTime.fromMicrosecondsSinceEpoch(1000222, isUtc: true); print(date3);
var date4 = new DateTime.fromMillisecondsSinceEpoch(1000222);
var date41 = new DateTime.fromMillisecondsSinceEpoch(1000222, isUtc: true); print(date4);
var date5 = new DateTime.utc(1969, 7, 20, 20, 18, 04); print(date5);
|
parse
1
| DateTime parse(String formattedString)
|
- 基于时间字符串, 创建
DateTime
- 如果输入的字符串无法解析,将抛出异常
- 当前接受的字符串为:
- 日期:一个有正负号之分的4-6位数的年份,2位数的月份,2位数的号数
- 年、月、日相互间可选-进行分割
- 例如:”19700101”,”-0004-12-24”,”81030-04-01”
- 时间部分为可选项,从日期处以
T
或一个空格分开
- 对于时间部分,包括2位数的小时,然后2位数的分钟值可选,然后2位数的秒钟值可选, 然后
.
加1-6位数的秒数可选
- 分和秒可以用
:
分隔
- 如:”12”,”12:30:24.124”,”123010.50”
- 时区偏移量为可选项,可能用空格与之前的部分分隔开
- 时区是
z
或Z
,或者是一个有正负之分的2位数的小时部分,和可选的2位数的分钟部分
- 符号必须是
+
或-
,并且不能省略
- 分钟和小时可能用
:
分隔
- 接受的字符串例子:
"2012-02-27 13:27:00"
"2012-02-27 13:27:00.123456z"
"20120227 13:27:00"
"20120227T132700"
"20120227"
"+20120227"
"2012-02-27T14Z"
"2012-02-27T14+00:00"
"-123450101 00:00:00 Z"
:年份为-12345
"2002-02-27T14:00:00-0500"
: 与"2002-02-27T19:00:00Z"
相同
1 2 3 4 5
| var date6 = DateTime.parse("2012-02-27 13:27:00"); var date7 = DateTime.parse('20120227T132700'); print(date6); print(date7);
|
属性值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| var time = DateTime.parse("2019-02-25 13:27:04");
print(time.year); print(time.month); print(time.day); print(time.weekday);
print(time.hour); print(time.minute); print(time.second); print(time.millisecond); print(time.microsecond);
print(time.isUtc);
print(time.microsecondsSinceEpoch);
print(time.millisecondsSinceEpoch);
print(time.timeZoneName);
print(time.timeZoneOffset);
|
相关函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| DateTime today = new DateTime.now(); print(today);
DateTime newDay = today.add(new Duration(days: 60)); print(newDay);
DateTime newDay1 = today.subtract(new Duration(days: 60)); print(newDay1);
var isCom = today.compareTo(newDay); print(isCom);
Duration duration = today.difference(newDay); print(duration);
print(today.isAfter(newDay)); print(today.isBefore(newDay));
print(today.isAtSameMomentAs(newDay));
print(today.toLocal());
|
参考文献