- 原文博客地址: Flutter開發(fā)之Dart的數(shù)據(jù)類型02
- 這幾篇文章都是在學習
Dart
過程中所記錄的學習筆記, 都是一些基礎(chǔ)知識, 幾乎沒什么技術(shù)含量, 主要是方便后期使用的時候方便查閱 - 之前的一篇文章已經(jīng)介紹了一部分的數(shù)據(jù)類型Flutter開發(fā)之Dart的數(shù)據(jù)類型01, 這里主要記錄剩下的一些常用的數(shù)據(jù)類型
- 我寫的Flutter和Dart語法系列相關(guān)的文章, 有興趣的可參考隨便看看
Map
-
key-value
鍵值對(可以使用相關(guān)聯(lián)的key
檢索value
值)的集合, 即傳說中的字典 -
Map
中key
的數(shù)量是有限的够委,每個key
正好有一個相關(guān)的value
-
Map
、以及它的鍵和值,都是可以迭代的, 迭代的順序由Map
不同的類型定義-
HashMap
是無序的擎场,這意味著它迭代的順序是不確定的 -
LinkedHashMap
按key
的插入順序進行迭代 -
SplayTreeMap
按key
的排序順序進行迭代
-
- 當
Map
的一個操作正在執(zhí)行的時候,通常不允許修改Map
(添加或刪除key
)
創(chuàng)建Map
Map()
// 創(chuàng)建一個Map實例,默認實現(xiàn)是LinkedHashMap。
Map.from(Map other)
// 創(chuàng)建一個LinkedHashMap實例衰絮,包含other的所有鍵值對。
Map.fromIterable(Iterable iterable, {K key(element), V value(element)})
// 創(chuàng)建一個Map實例磷醋,其中Key和Value由iterable的元素計算得到猫牡。
Map.fromIterables(Iterable<K> keys, Iterable<V> values)
// 將指定的keys和values關(guān)聯(lián),創(chuàng)建一個Map實例邓线。
Map.identity()
// 使用默認實現(xiàn)LinkedHashMap創(chuàng)建一個嚴格的Map淌友。
Map.unmodifiable(Map other)
// 創(chuàng)建一個不可修改、基于哈希值的Map骇陈,包含other所有的項
每一種創(chuàng)建方式的具體使用
// 創(chuàng)建一個Map實例, 插入順序進行排列
var dic = new Map();
print(dic); // {}
// 根據(jù)一個Map創(chuàng)建一個新的Map, 插入順序進行排列
var dic1 = new Map.from({'name': 'titan'});
print(dic1); // {name: titan}
// 根據(jù)List創(chuàng)建Map, 插入順序進行排列
List<int> list = [1, 2, 3];
// 使用默認方式, key和value都是數(shù)組對應(yīng)的元素
var dic2 = new Map.fromIterable(list);
print(dic2); // {1: 1, 2: 2, 3: 3}
// 設(shè)置key和value的值
var dic3 = new Map.fromIterable(list, key: (item) => item.toString(), value: (item) => item * item);
print(dic3); // {1: 1, 2: 4, 3: 9}
// 兩個數(shù)組映射一個字典, 插入順序進行排列
List<String> keys = ['name', 'age'];
var values = ['jun', 20];
// 如果有相同的key值, 后面的值會覆蓋前面的值
var dic4 = new Map.fromIterables(keys, values);
print(dic4); // {name: jun, age: 20}
// 創(chuàng)建一個空的Map, Map允許null作為key
var dic5 = new Map.identity();
print(dic5); //{}
// 創(chuàng)建一個不可修改震庭、基于哈希值的Map
var dic6 = new Map.unmodifiable({'name': 'titan'});
print(dic6);
相關(guān)屬性
Map
中相關(guān)屬性和一些常用屬性的操作如下:
var map1 = {'name': 'titan', 'age': 20};
// 哈希值
print(map1.hashCode);
// 運行時類型
print(map1.runtimeType); //_InternalLinkedHashMap<String, Object>
// 是否為空, null不能判斷, 會報錯
print(map1.isEmpty); // false
// 是否不為空
print(map1.isNotEmpty); // true
// 鍵值對個數(shù)
print(map1.length); // 2
// 所有的key值, 返回Iterable<K>類型
print(map1.keys.toList()); // [name, age]
// 所有的value值, 返回Iterable<K>類型
print(map1.values.toList()); // [titan, 20]
// 根據(jù)key取值
print(map1['name'] ?? ''); // titan
// 根據(jù)key賦值
map1['age'] = 30;
print(map1); // {name: titan, age: 30}
相關(guān)函數(shù)
var map2 = {'name': 'titan', 'age': 20};
// 添加一個map
map2.addAll({'blog': 'titanjun'});
print(map2);
// {name: titan, age: 20, blog: titanjun}
// 判斷是否包含指定的key
print(map2.containsKey('age')); //
// 判斷是否包含指定的value
print(map2.containsValue('titan'));
// 操作每個鍵值對
map2.forEach((key, value) {
print('key = $key, value = $value');
});
// 查找key對應(yīng)的value,或添加一個新的值為key.length的value
for (var key in ['name', 'age', 'king']) {
// 函數(shù)的返回值為查找到的對應(yīng)的value值
print(map2.putIfAbsent(key, () => key.length));
}
print(map2);
// {name: titan, age: 20, blog: titanjun, king: 4}
// 轉(zhuǎn)成字符串
print(map2.toString());
// 刪除鍵值對, 返回刪除key對應(yīng)的value值, 沒有則返回null
print(map2.remove('blog')); //titanjun
print(map2.remove('coder')); //null
print(map2);
// 刪除所有的鍵值對
map2.clear();
print(map2); //{}
Iterable
- 按順序訪問的值或元素的集合,
List
集合也是繼承于Iterable
-
List
和Set
也是Iterable
你雌,dart:collection
庫中同樣有很多 - 部分
Iterable
集合可以被修改- 向
List
或Set
添加元素將改變對象所有包含的元素器联。 - 向Map添加新的
Key
會改變所有Map.keys
的元素。 - 在集合改變后婿崭,創(chuàng)建的迭代器將提供新的所有元素拨拓,并且可能會保持目前元素的順序, 也可能不會
- 向
創(chuàng)建方式
// 創(chuàng)建空的可迭代對象
var ite = Iterable.empty();
print(ite); // ()
// 創(chuàng)建一個Iterable,通過序列來動態(tài)生成元素
var ite1 = Iterable.generate(5);
print(ite1); // (0, 1, 2, 3, 4)
至于Iterable
的所有屬性和函數(shù)的介紹和使用, 在上篇文章Flutter開發(fā)之Dart的數(shù)據(jù)類型01中的List
模塊中已經(jīng)詳細介紹了, 因為List
是繼承于Iterable
的, 所以Iterable
有的屬性和方法List
中都有
Runes
- 在
Dart
中氓栈,Runes
代表字符串的UTF-32
字符集, 另一種Strings
-
Unicode
為每一個字符渣磷、標點符號、表情符號等都定義了 一個唯一的數(shù)值 - 由于
Dart
字符串是UTF-16
的字符序列授瘦,所以在字符串中表達32的字符序列就需要新的語法了 - 通常使用
\uXXXX
的方式來表示, 這里的XXXX
是4個16進制的數(shù), 如醋界,心形符號(?)
是\u2665
- 對于非4個數(shù)值的情況竟宋,把編碼值放到大括號中即可, 如,笑臉
emoji
(??) 是\u{1f600}
-
String
類有一些屬性可以提取rune
信息-
codeUnitAt
和codeUnit
屬性返回16為字符 - 使用
runes
屬性來獲取字符串的runes
信息
-
var clapping = '\u{1f44f}';
print(clapping); // ??
print(clapping.codeUnits); // [55357, 56399]
print(clapping.runes.toList()); // [128079]
簡單使用
// 根據(jù)字符串創(chuàng)建
Runes runes = new Runes('\u2665, \u{1f605}, \u{1f60e}');
print(runes);
// (9829, 44, 32, 128517, 44, 32, 128526)
// 輸出特殊字符的字符串
print(new String.fromCharCodes(runes));
// ?, ??, ??
由于Runes
也是繼承于Iterable
, 所以Runes
中的屬性和方法的使用也和Iterable
一樣, 詳情參考Runes和Flutter開發(fā)之Dart的數(shù)據(jù)類型01中的介紹
Symbols
- 一個
Symbol
對象代表Dart
程序中聲明的操作符或者標識符 - 也許不會用到
Symbol
形纺,但是該功能對于通過名字來引用標識符的情況 是非常有價值的丘侠,特別是混淆后的代碼,標識符的名字被混淆了挡篓,但是Symbol
的名字不會改變 - 使用
Symbol
字面量來獲取標識符的symbol
對象婉陷,也就是在標識符前面添加一個#
符號
// 獲取symbol 對象
var sym1 = Symbol('name');
print(sym1); // Symbol("name")
// #號創(chuàng)建
var sym2 = #titan;
print(sym2); // Symbol("titan")
Set
- 對象的集合帚称,其中每個對象只能出現(xiàn)一次,
List
中一個對象可以出現(xiàn)多次 - 迭代Set中的元素時官研,某些時候有可能是無序的,也有可能是有序的闯睹。例如:
-
HashSet
是無序的戏羽,這意味著它迭代的順序是不確定的 -
LinkedHashSet
按元素的插入順序進行迭代 -
SplayTreeSet
按排序順序迭代元素
-
-
Set
除創(chuàng)建方式和List
不同, 其他屬性和方法基本一樣
創(chuàng)建Set
// 創(chuàng)建一個空的Set。
var set1 = Set();
print(set1); // {}
// 創(chuàng)建一個包含所有elements的Set
var set2 = Set.from([1, 2, 3]);
print(set2); // {1, 2, 3}
// 創(chuàng)建一個空的楼吃,元素嚴格相等的Set
var set3 = Set.identity();
print(set3); // {}
方法
// set2 = {1, 2, 3}
//返回一個新的Set始花,它是this和other的交集
var set4 = Set.from([2, 3, 5, 6]);
print(set2.intersection(set4)); //{2, 3}
// 返回一個新的Set,它包含this和other的所有元素(并集)
print(set2.union(set4)); // {1, 2, 3, 5, 6}
// 檢查Set中是否包含object, 有則返回該object, 沒有則返回null
print(set4.lookup(5)); // 5
print(set4.lookup(21)); // null
其他更多屬性參考Set<E>和Flutter開發(fā)之Dart的數(shù)據(jù)類型01中的介紹
Duration
-
Duration
表示從一個時間點到另一個時間點的時間差 - 如果是一個較晚的時間點和一個較早的時間點孩锡,
Duration
可能是負數(shù)
創(chuàng)建Duration
// 唯一的構(gòu)造函數(shù)創(chuàng)建Duration對象
Duration({int days: 0, int hours: 0, int minutes: 0, int seconds: 0, int milliseconds: 0, int microseconds: 0})
// 可以使用其中的一個或者幾個參數(shù)創(chuàng)建
// 只是用其中的一個參數(shù)
Duration ration = Duration(days: 1);
print(ration); //24:00:00.000000
Duration ration1 = Duration(hours: 10);
print(ration1); //10:00:00.000000
// 只是用其中的兩個參數(shù)
Duration ration2 = Duration(days: 1, hours: 3);
print(ration2); //27:00:00.000000
// 使用所有的參數(shù)
Duration ration3 = Duration(days: 2, hours: 2, minutes: 23, seconds: 34, milliseconds: 56, microseconds: 89);
print(ration3); //50:23:34.056089
相關(guān)運算
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); //25:01:01.001001
print(time2); //50:02:02.002002
// 加
print(time1 + time2); //75:03:03.003003
// 減
print(time1 - time2); //-25:01:01.001001
// 乘
print(time1 * 2); //50:02:02.002002
// 除(取整)
print(time2 ~/ 3); //16:40:40.667334
// 比較
print(time1 > time2); //false
print(time1 >= time2); //false
print(time1 == time2); //false
print(time1 < time2); //true
print(time1 <= time2); //true
// 取相反值
print(-time1); //-25:01:01.001001
print(-(time1 - time2)); //25:01:01.001001
相關(guān)函數(shù)
Duration time3 = -Duration(days: 1, hours: 1, minutes: 1, seconds: 1, milliseconds: 1, microseconds: 1);
print(time3); //-25:01:01.001001
// 取絕對值
print(time3.abs()); //25:01:01.001001
// 比較, 返回值, 0: 相等, -1: time1 < time2, 1: time1 > time2
print(time1.compareTo(time2)); //-1
// 字符串形式
print(time1.toString());
DateTime
- 表示一個時間點
- 通過構(gòu)造函數(shù)或解析格式化的字符串創(chuàng)建
DateTime
對象酷宵,并且符合ISO 8601
標準的子集,小時是24小時制躬窜,范圍在0-23之間 -
DateTime
對象創(chuàng)建之后浇垦,將是固定不變的, 不可被修改 -
DateTime
對象默認使用的是本地時區(qū),除非顯示地指定UTC
時區(qū)
創(chuàng)建時間點
// 當前時間
var date1 = new DateTime.now();
print(date1); //2019-02-23 16:43:15.505305
// 構(gòu)造一個指定為本地時區(qū)的DateTime
//DateTime(int year, [int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0])
var date2 = new DateTime(2018, 10, 3, 12, 23, 34, 562, 1002);
print(date2); //2018-10-03 12:23:34.563002
// 用微秒創(chuàng)建
var date3 = new DateTime.fromMicrosecondsSinceEpoch(1000222);
// isUtc: true: UTC時區(qū), 默認false
var date31 = new DateTime.fromMicrosecondsSinceEpoch(1000222, isUtc: true);
print(date3); //1970-01-01 08:00:01.000222
// 用毫秒創(chuàng)建
var date4 = new DateTime.fromMillisecondsSinceEpoch(1000222);
// isUtc: true: UTC時區(qū), 默認false
var date41 = new DateTime.fromMillisecondsSinceEpoch(1000222, isUtc: true);
print(date4); //1970-01-01 08:16:40.222
// 指定為UTC時區(qū)的時間
var date5 = new DateTime.utc(1969, 7, 20, 20, 18, 04);
print(date5); //1969-07-20 20:18:04.000Z
parse
DateTime parse(String formattedString)
- 基于時間字符串, 創(chuàng)建
DateTime
- 如果輸入的字符串無法解析荣挨,將拋出異常
- 當前接受的字符串為:
- 日期:一個有正負號之分的4-6位數(shù)的年份男韧,2位數(shù)的月份,2位數(shù)的號數(shù)
- 年默垄、月此虑、日相互間可選-進行分割
- 例如:"19700101","-0004-12-24"口锭,"81030-04-01"
- 時間部分為可選項朦前,從日期處以
T
或一個空格分開- 對于時間部分,包括2位數(shù)的小時鹃操,然后2位數(shù)的分鐘值可選韭寸,然后2位數(shù)的秒鐘值可選, 然后
.
加1-6位數(shù)的秒數(shù)可選 - 分和秒可以用
:
分隔 - 如:"12"组民,"12:30:24.124"棒仍,"123010.50"
- 對于時間部分,包括2位數(shù)的小時鹃操,然后2位數(shù)的分鐘值可選韭寸,然后2位數(shù)的秒鐘值可選, 然后
- 時區(qū)偏移量為可選項,可能用空格與之前的部分分隔開
- 時區(qū)是
z
或Z
臭胜,或者是一個有正負之分的2位數(shù)的小時部分莫其,和可選的2位數(shù)的分鐘部分 - 符號必須是
+
或-
癞尚,并且不能省略 - 分鐘和小時可能用
:
分隔
- 時區(qū)是
- 日期:一個有正負號之分的4-6位數(shù)的年份男韧,2位數(shù)的月份,2位數(shù)的號數(shù)
- 接受的字符串例子:
"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"
相同
// 格式化時間字符串
var date6 = DateTime.parse("2012-02-27 13:27:00");
var date7 = DateTime.parse('20120227T132700');
print(date6); // 2012-02-27 13:27:00.000
print(date7); // 2012-02-27 13:27:00.000
屬性值
var time = DateTime.parse("2019-02-25 13:27:04");
// 獲取年-月-日-周幾
print(time.year); //2019
print(time.month); //2
print(time.day); //25
print(time.weekday);//1
// 獲取時-分-秒-毫秒-微秒
print(time.hour); //13
print(time.minute); //27
print(time.second); //4
print(time.millisecond);//0
print(time.microsecond);//0
// 是不是utc時區(qū)
print(time.isUtc);
//1970-01-01T00:00:00Z (UTC)開始經(jīng)過的微秒數(shù)
print(time.microsecondsSinceEpoch);
//1970-01-01T00:00:00Z (UTC)開始經(jīng)過的毫秒數(shù)
print(time.millisecondsSinceEpoch);
//平臺提供的時區(qū)名稱
print(time.timeZoneName);
//時區(qū)偏移量,即本地時間和UTC之間的時間差
print(time.timeZoneOffset);
相關(guān)函數(shù)
// 獲取當前時間
DateTime today = new DateTime.now();
print(today); //2019-02-28 11:18:16.198088
//加上duration乱陡,返回一個新的DateTime實例
DateTime newDay = today.add(new Duration(days: 60));
print(newDay); //2019-04-29 11:18:16.198088
//減去duration浇揩,返回一個新的DateTime實例
DateTime newDay1 = today.subtract(new Duration(days: 60));
print(newDay1); //2018-12-30 11:25:31.741382
// 比較兩個時間值的大小, 0: 相等, -1: 前值<后值, 1: 前值>后值
var isCom = today.compareTo(newDay);
print(isCom); // -1
// 計算兩個時間的差值
Duration duration = today.difference(newDay);
print(duration); //-1440:00:00.000000
// 比較兩個時間
print(today.isAfter(newDay)); // false
print(today.isBefore(newDay)); // true
// 比較是否是同一時刻
print(today.isAtSameMomentAs(newDay)); //false
// 返回此DateTime在本地時區(qū)的值
print(today.toLocal()); //2019-02-28 11:30:51.713069
參考文獻
歡迎您掃一掃下面的微信公眾號,訂閱我的博客憨颠!