dart系列之:集合使用实践
文章目錄
- 簡介
- 使用字面量創建集合
- 不要使用.length來判斷集合是否為空
- 可遍歷對象的遍歷
- List.from和iterable.toList
- where和whereType
- 避免使用cast
- 總結
簡介
dart中有四種集合,分別是Set,List,Map和queues。這些集合在使用中需要注意些什么呢?什么樣的使用才是最好的使用方法呢?一起來看看吧。
使用字面量創建集合
對于常用的Set,Map和List三個集合來說,他們是有自己的無參構造函數的:
factory Set() = LinkedHashSet<E>;external factory Map();@Deprecated("Use a list literal, [], or the List.filled constructor instead")external factory List([int? length]);可以看到Set和Map是可以使用構造函數的。但是對于List來說,無參的構造函數已經不推薦使用了。
對于Set和Map來說,可以這樣構造:
var studentMap = Map<String, Student>(); var ages = Set<int>();但是dart官方推薦直接使用字面量來創建這些集合,如下所示:
var studentMap = <String, Student>{}; var ages = <int>{};為什么呢?這是因為dart中的字面量集合是非常強大的。可以通過擴展運算符,if和for語句對集合進行構造和擴展,如下所示:
var studentList = [...list1,student1,...?list2,for (var name in list3)if (name.endsWith('jack'))name.replaceAll('jack', 'mark') ];不要使用.length來判斷集合是否為空
對應dart的可遍歷集合來說,這些集合并沒有存儲集合的長度信息,所以如果你調用集合的.length方法,可能會導致集合的遍歷,從而影響性能。
注意Set和List是可遍歷的,而Map是不可遍歷的。
所以,我們需要調用集合的.isEmpty 和 .isNotEmpty方法來判斷集合是否為空,這樣速度更快。
if (studentList.isEmpty) print('it is empty'); if (studentList.isNotEmpty) print('it is not empty');可遍歷對象的遍歷
對應Set和List這兩個可遍歷的集合來說,有兩種遍歷方法,可以通過調用forEach() 方法或者for-in來進行遍歷,如下所示:
for (final student in studentList) {... } studentList.forEach((student) {... });這兩種方法中,dart推薦使用for in的寫法。
當然,如果你想將現有的function應用在集合中的每個元素中,forEach也是可以的:
studentList.forEach(print);注意,因為Map是不可遍歷的,所以上面的規則對Map并不適用。
List.from和iterable.toList
可遍歷對象可以通過調用toList將其轉換成為List,同樣的List.from也可以將可遍歷對象轉換成為List。
那么兩者有什么區別呢?
var list1 = iterable.toList(); var list2 = List.from(iterable);兩者的區別是iterable.toList并不會改變list中數據的類型,而List.from會. 舉個例子:
// Creates a List<String>: var studentList = ['jack', 'mark', 'alen'];// Prints "List<String>": print(studentList.toList().runtimeType);// Prints "List<dynamic>": print(List.from(studentList).runtimeType);當然,你也可以使用List.from來強制對創建出來的List進行類型轉換。
List<String>.from(studentList)where和whereType
對于可遍歷對象來說,兩個過濾集合中元素的方法,他們是where和whereType。
比如,我們需要過濾List中的字符串,則可以這樣寫:
var studentList = ['jack', 'ma', 18, 31]; var students1 = studentList.where((e) => e is String); var students2 = studentList.whereType<String>();看上去兩者沒有太大的區別,都可以得到應有的結果。但是兩者事實上還是有區別的,因為對應where來說,返回的是一個Iterable<Object>,所以上面的例子中,如果我們真的需要返回String,還需要對返回結果進行case:
var students1 = studentList.where((e) => e is String).cast<String>();;所以,如果你要返回特定的對象時候,記得使用whereType。
避免使用cast
cast通常用來對集合中的元素進行類型轉換操作,但是cast的性能比較低,所以在萬不得已的情況下,一定要避免使用cast。
那么如果不使用cast,我們怎么對類型進行轉換呢?
一個基本的原則就是在構建集合的時候提前進行類型轉換,而不是在構建集合之后再進行整體的cast。
比如下面的例子從一個dynamic類型的List轉換成為int類型的List,那么我們可以在調用List.from方法的時候進行類型轉換:
var stuff = <dynamic>[1, 2]; var ints = List<int>.from(stuff);如果是map的話,可以這樣操作:
var stuff = <dynamic>[1, 2]; var reciprocals = stuff.map<double>((n) => 1 / n);比如我們需要構建一個int的List,那么在創建之初就可以指定List的內部類型,然后再對其添加元素:
List<int> singletonList(int value) {var list = <int>[];list.add(value);return list; }總結
以上就是dart中的集合使用最佳實踐。
本文已收錄于 http://www.flydean.com/30-dart-collection/
最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!
總結
以上是生活随笔為你收集整理的dart系列之:集合使用实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dart系列之:和null说再见,nul
- 下一篇: netty系列之:channelPipe