前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dart collection 库

dart collection 库

原创
作者头像
三流之路
发布2024-08-27 17:56:19
490
发布2024-08-27 17:56:19
举报
文章被收录于专栏:Flutter

在看 Flutter 官方的 Flutter Widget of the Week 系列视频时,有一个视频讲 collection 库提供了许多方便的功能,值的从头到晚看一下,网上没搜到什么资料,于是便看下它的 API,试用了一遍。

作为 Dart 官方的库,主要是提供一些操作集合的方法。总体分为三类:封装的类,扩展的方法,顶层的函数。下面先看封装的类。

Delegating

DelegatingIterableDelegatingListDelegatingSetDelegatingMapDelegatingQueue

参数是原始类型的值,有什么用处呢,比如 DelegatingIterable

一来可以扩展它,添加了自定义的操作,原来 Iterable 的操作也可以继续用,并且不直接扩展 Iterable,这样普通的 Iterable 没有这些扩展方法,必须是 DelegatingXXX 类型的才可以用这个扩展方法。

二来假如别的地方扩展了 Iterable 了,但是我现在一些地方不想用,用 DelegatingXXX 后,就只能用属于 Iterable 的方法,而用不了别人扩展 Iterable 的方法。

Combined

CombinedIterableView

将多个集合合并成一个,元素类型可以都不一样。

代码语言:dart
复制
CombinedIterableView civ = const CombinedIterableView([{1,2,3},['a','b','c']]);  
print(civ); // (1, 2, 3, a, b, c)

CombinedListView

将多个列表合并成一个列表,元素类型必须一样。

代码语言:dart
复制
CombinedListView clv = CombinedListView<int>([[1, 2, 3], [5,6,7]]);  
print(clv); // [1, 2, 3, 5, 6, 7]

CombinedMapView

将多个 Map 合并成一个。

代码语言:dart
复制
var map1 = {'a':1,'b':2};  
var map2 = {'cd':3, 'de':4, 'fg': 5};  
var set = {map1, map2};  
CombinedMapView cmv = CombinedMapView(set);  
assert(cmv.length == 5);  
assert(cmv['cd'] == 3);

Equality

CaseInsensitiveEquality

忽略大小写,判断两个字符串是否相同。

代码语言:dart
复制
CaseInsensitiveEquality equality = const CaseInsensitiveEquality();  
bool equal = equality.equals('abc', 'ABC');  
assert(equal);

DeepCollectionEquality

如果是集合,递归往里面去对比。

代码语言:dart
复制
// 两个不同的内存地址  
var list1 = [2];  
var list2 = [2];  
assert(list1 != list2);  
  
DeepCollectionEquality dce = const DeepCollectionEquality();  
bool equal = dce.equals(list1, list2); // true,比较里面的元素

DefaultEquality

使用参数对象的 == 和 hashcode 来判断。就类似 Java 中重写类的 equals/hashCode 方法后调用 equals 判断两个对象是否相等。

EqualityBy

每个元素使用构造方法的函数参数的返回值来判断是否相等。

代码语言:dart
复制
EqualityBy<String, int> eb = EqualityBy((String e)=>e.length);  
bool equal = eb.equals('abc', 'def');  
assert(equal); // 长度相同,所以是 ture

IdentityEquality

Dart 对象都有一个 identity,底层 identical() 方法判断两个 identity 是否相等,其实就是判断引用是否一样。

IterableEquality/ListEquality/SetEquality/MapEquality

对于集合,相同位置的元素相同为 true。如果 Map,就是键值都相等。

MultiEquality

代码语言:dart
复制
@override  
bool equals(E e1, E e2) {  
  for (var eq in _equalities) {  
    if (eq.isValidKey(e1)) return eq.isValidKey(e2) && eq.equals(e1, e2);  
  }  
  return false;  
}

参数是其它比较器的列表,然后调用 equals,开始遍历这些比较器,只要一个比较器第一个参数通过 isValidKey 判断为 true 时,就用这个比较器了,第二个参数判断是否有效和 equals 作与。

怎么用,可能要自定义子类,修改 isValidKey 的实现。

代码语言:dart
复制
var equalities = [ // 范型要一样  
  const DefaultEquality<String>(),  
  const IdentityEquality<String>(),  
  const CaseInsensitiveEquality(),  
];  
  
MultiEquality me = MultiEquality(equalities);  
bool b = me.equals('abc', 'ABC'); // false

Unmodifiable

UnmodifiableListView

不可变 List,但原始 List 可以变,由于同一个引用,原始的变了,它也变了。

代码语言:dart
复制
final numbers = <int>[10, 20, 30];  
final unmodifiableListView = UnmodifiableListView(numbers);  
numbers.addAll([40, 50]);  
print(numbers);  
print(unmodifiableListView); // [10,20,30,40,50]
unmodifiableListView.add(60); // 报错

UnmodifiableSetMixin/UnmodifiableSetView

不可以修改内容的 Set,UnmodifiableSetView 混入了 UnmodifiableSetMixin,UnmodifiableSetMixin 适合其它的 Set,不想让它可变的情况。

代码语言:dart
复制
final numbers = <int>{10, 20, 30};  
final unmodifiableSetView = UnmodifiableSetView(numbers);  
numbers.addAll([40, 50]);  
print(numbers); // [10,20,30,40,50]  
print(unmodifiableSetView); // [10,20,30,40,50]  
unmodifiableSetView.add(60); // 报错

UnmodifiableMapView

不可以改变元素的 Map。

代码语言:dart
复制
final map = {'a':1, 'b':2};  
final unmodifiableMapView = UnmodifiableMapView(map);  
map['c'] = 3;  
print(unmodifiableMapView); // {a: 1, b: 2, c: 3}  
unmodifiableMapView['d'] = 4; // 报错

UnmodifiableMapMixin

不是 mixin,是 abstract class,UnmodifiableMapView 并不是它的子类。其它 Map 不允许修改的时候继承它。

Map

CanonicalizedMap

将键用一个函数转换。

代码语言:dart
复制
// 键长度大于 2 的情况下,变成大写作为键 
CanonicalizedMap<String, String, int> c = CanonicalizedMap((String key)=>key.toUpperCase(), isValidKey: (String key)=>key.length>2);  
c['a'] = 1; // 长度小于 2,不会被插入  
c['cde'] = 2; // 键变成了 CDE
c['cDE'] = 4; // CDE 这个键的值变成了 4
assert(c['CDE']==4);  
  
CanonicalizedMap<String, String, int> c2 = CanonicalizedMap.from({  
  'a': 1,  
  'cde': 2,  
  'cDE': 4  
}, (String key)=>key.toUpperCase());  
assert(c2.length==2);

EqualityMap/EqualitySet

键的相等性由参数的 Equality 对象的 equals 判断

代码语言:dart
复制
EqualityMap map = EqualityMap(const CaseInsensitiveEquality());

EqualitySet set = EqualitySet(EqualityBy<String, String>((String e)=>e.toUpperCase()));

MapKeySet

把一个 Map 的所有键拿出来放到一个 Set 里。没看出来有什么用处,因为 keys.toSet 结果都一样的。

代码语言:dart
复制
var map = {'b':1, 'a':2, 'bd': 3, 'ae': 4};  
map.keys.toSet();  
bool b = const SetEquality().equals(map.keys.toSet(), MapKeySet(map));  
assert(b);

List

BoolList

值都是布尔值,底层用 Uint32List 存储,节约空间。

代码语言:dart
复制
// growable true 表示长度自动增长
factory BoolList(int length, {bool fill = false, bool growable = false})

IterableZip

和 Kotlin 类似。

代码语言:dart
复制
IterableZip iz = IterableZip({[1,2], {'a','b','c'},[true, false, true, false]});  
print(iz); // ([1, a, true], [2, b, false])

ListSlice

列表切片,有点类似 Swift 中的字符串切片,和原来的列表共享内存,要变成独立的调用 toList()

在使用列表切片时,源列表不得更改长度。,内部有判断这个,如果不一样,操作会报错。

代码语言:dart
复制
var list = ['a','b','c','d','e','f','g'];  
ListSlice<String> slice = ListSlice<String>(list, 2, 5); // [c,d,e],含头不含尾  
assert(slice[0]=='c');  
slice[0]='h'; // list[2] 变成了 h
// 内部调用 source.setRange(start + start, start + end, iterable, skipCount);
// 一个奇怪的算法,参数 1,3,就是修改原 List 的 1+1 到 1+3
slice.setRange(1, 3, ['j','k','l','m']);  
// slice.insert(5, 'f2h'); // 插入会修改长度,报错

NonGrowableListMixin/NonGrowableListView

从一个 List 搞一个长度不可修改的副本。

代码语言:dart
复制
var list = [1,2,3,4];  
NonGrowableListMixin nglm = NonGrowableListView(list);
// 内容可以修改,但长度不能修改
nglm[1]=5;

NonGrowableListView 混入了 NonGrowableListMixin 的类,所以要创建 List 用这个功能,就直接用 NonGrowableListView。如果有其它的 List 子类,想让它长度不可变,就自己 with NonGrowableListMixin。

Set

UnionSet

和 set.union() 没什么差别,所以作用不大。混入了 UnmodifiableSetMixin,所以不能修改值。

代码语言:dart
复制
var set1 = {1,2,3};  
var set2 = {2,3,4};  
bool equal = const SetEquality().equals(set1.union(set2), UnionSet({set1, set2}));  
assert(equal);

UnionSetController

内部封装了 UnionSet,UnionSet 不可修改,所以合并后就不能再添加新的 Set 去合并,不能删除之前的一个 Set,而 UnionSetController 可以合并后再添加 Set,也可以从合并的结果中删除一个 Set。

代码语言:dart
复制
var usc = UnionSetController();  
usc.add(set1);  
usc.add(set2);  
usc.remove(set1);  

PriorityQueue/HeapPriorityQueue

优先队列,优先级越高,越在前面,也是变相实现了排序。

代码语言:dart
复制
PriorityQueue pq = PriorityQueue<String>((a,b)=>b.length-a.length);  
hpq.add('abc'); 
hpq.add('ab');  
print(hpq.first);

HeapPriorityQueue 是 PriorityQueue 的子类,基于堆内存,改进了时间复杂度。

代码语言:dart
复制
HeapPriorityQueue hpq = HeapPriorityQueue<String>((a,b)=>b.length-a.length);  
hpq.add('abc'); // 时间复杂度是 O(log(n))
hpq.add('a');  
hpq.add('ab');  
print(hpq.first); // abc,时间复杂度 O(1)
print(hpq.toList()); // [abc, ab, a],时间复杂度 O(n*log(n))

QueueList

具有 List 和 Queue 的特性,就是 List 的基础上加上 addFirst/addLast/removeFirst/removeLast 的方法。

代码语言:dart
复制
QueueList<String> ql = QueueList(3); // 初始长度  
ql.add('a');  
ql.addFirst('b');  
print(ql);  
QueueList<int> ql2 = QueueList.from([1,2,3,4]);  
ql2.addLast(5);  
ql2.removeFirst();  
print(ql2);

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Delegating
  • Combined
    • CombinedIterableView
      • CombinedListView
        • CombinedMapView
        • Equality
          • CaseInsensitiveEquality
            • DeepCollectionEquality
              • DefaultEquality
                • EqualityBy
                  • IdentityEquality
                    • IterableEquality/ListEquality/SetEquality/MapEquality
                      • MultiEquality
                      • Unmodifiable
                        • UnmodifiableListView
                          • UnmodifiableSetMixin/UnmodifiableSetView
                            • UnmodifiableMapView
                              • UnmodifiableMapMixin
                              • Map
                                • CanonicalizedMap
                                  • EqualityMap/EqualitySet
                                    • MapKeySet
                                    • List
                                      • BoolList
                                        • IterableZip
                                          • ListSlice
                                            • NonGrowableListMixin/NonGrowableListView
                                            • Set
                                              • UnionSet
                                                • UnionSetController
                                                • PriorityQueue/HeapPriorityQueue
                                                • QueueList
                                                领券
                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档