Dart语言是Flutter开发的必备语言,官方地址如下:
Dart:https://dart.cn/
使用dart工具来运行这些常用的方法,工具:
https://dartpad.cn
在Dart中,Map用来存储对像类型的数据,List与Set用来存储数组类型的数据。
Dart中的Map用来保存key-value键值对的数据集合
Map的创建实例如下:
// 创建一个Map实例,默认实现是LinkedHashMap。
Map()
// 创建一个LinkedHashMap实例,包含other中的所有键值对。
Map.from(Map other)
// 创建一个Map实例,其中Key和Value由iterable的元素计算得到。
Map.fromIterable(Iterable iterable, {K key(element), V value(element)})
// 将指定的keys和values关联,创建一个Map实例。
Map.fromIterables(Iterable<K> keys, Iterable<V> values)
// 使用默认实现LinkedHashMap创建一个严格的Map。
Map.identity()
// 创建一个不可修改、基于哈希值的Map,包含other所有的项
Map.unmodifiable(Map other)
创建有一个有初始值的Map,代码如下:
// 根据一个Map创建一个新的Map, 插入顺序进行排列
var dic1 = new Map.from({'name': '张三'});
print(dic1); // {name: 张三}
// 根据List创建Map, 插入顺序进行排列
List<int> list = [1, 2, 3];
// 使用默认方式, key和value都是数组对应的元素
var dic2 = new Map.fromIterable(list);
print(dic2); // {1: 1, 2: 2, 3: 3}
// 设置key和value的值
var dic3 = new Map.fromIterable(list, key: (item) => item.toString(), value: (item) => item * item);
print(dic3); // {1: 1, 2: 4, 3: 9}
// 创建一个不可修改、基于哈希值的Map
var dic6 = new Map.unmodifiable({'name': 张三});
print(dic6); // {name: 张三}
根据List数据来创建Map,代码如下:
// 两个数组映射一个字典, 插入顺序进行排列
List<String> keys = ['name', 'age'];
var values = [张三, 20];
// 如果有相同的key值, 后面的值会覆盖前面的值
var dic4 = new Map.fromIterables(keys, values);
print(dic4); // {name: 张三, age: 20}
var words = <String>['fee', 'fi', 'fo', 'fum'];
var map = words.asMap(); // {0: fee, 1: fi, 2: fo, 3: fum}
map.keys.toList(); // [0, 1, 2, 3]
map使用entryKey 进行遍历
如果需要对 map 进行遍历并获取 value,建议直接通过 map.entries,而不是获取 map.keys 之后,再遍历获取 value
Map<String,String> map = Map.from({'name': '张三', 'sex': '男',});
//不推荐使用
for (var key in map.keys) {
print('value:${map[key]}');
//推荐使用
for (var entry in map.entries) {
print('value:${entry.value}');
-
Set中的元素是不可重复的,用{}声明Set,并用,分割元素。
-
Set集合可直接对String、int、double类型去重。
var set1 = {1,2,3,4,5,6}; // 声明一个 set 并赋初始元素
var set2 = <Int>{}; // 声明一个空 set
var set3 = new Set(); // 声明一个空 set
var set4 = Set(); // 声明一个空 set,new 关键词可有可无
Set set=new Set();
set.add(1);
set.add(2);
set.add(1);
set.add(1);
set.add(3);
Set set=new Set();
set.add('a');
set.add('b');
set.add('');
set.add('c');
set.add('a');
set.add('b');
print(s); // {a, b,,c}
List数组的常用方法
定义固定长度数组
void main() { var list = List(2); print('$list'); // [null, null]}
定义混合类型数组
void main() {
var list = List<dynamic>();
list.add('我是文本');
list.add(0.66);
print(list); // [我是文本, 0.66]}
判断数组内是否有满足条件的元素- any
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];// 数组中是否有大于3的元素
print(list.any((v) => v > 3)); // true
// 数组中是否有大于7的元素
print(list.any((v) => v > 7)); // false
判断数组所有元素是否都满足设定条件 - every
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
// 数组中所有元素是否都大于0
print(list.every((v) => v > 0)); // true
// 数组中所有元素是否都大于5
print(list.every((v) => v > 5)); // false
将数组用指定字符拼接成字符串 - join
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
// 将数组转换为用英文逗号拼接的字符串
print(list.join(',')); // 1,2,2,3,4,5,6,6
将字符串以指定字符分割成数组-split
void main() {
String str = '1,2,2,3,4,5,6,6';
print(str.split(',')); // [1,2,2,3,4,5,6,6]
数组去重 - toSet
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
print(list.toSet()); // {1, 2, 3, 4, 5, 6}
数组取指定个数的数组- take
void main() {
List latest = [1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4];
List list = latest.take(5).toList();
print('value: $latest list:$list');
打印:value: [1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4] list:[1, 2, 3, 4, 5]
按指定条件返回 - map
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6]; // 将list所有元素加1并返回数组
var v = list.map((e) {
return e + 1;
}).toList();
print(v); //[2, 3, 3, 4, 5, 6, 7, 7]
数组遍历 - for\for in\forEach
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
//for
for (var i = 0; i < list.length; i++) {
print("for:$i");
//for in
for (var item in list) {
print("for in:$item");
//forEach
list.forEach((element) {
print("forEach:$element");
//while+iterator迭代器遍历,类似Java中的iteator
while(list.iterator.moveNext()) {
//获取对应的值
var value = list.iterator.current;
print("for:$value");
累加器 - reduce
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];// 将每次返回值作为value循环执行。最终返回最后一次执行值
var count = list.reduce((value, element) {
print('value: $value - element: $element');
/** 每次的执行结果
value: 1 - element: 2
value: 3 - element: 2
value: 5 - element: 3
value: 8 - element: 4
value: 12 - element: 5
value: 17 - element: 6
value: 23 - element: 6
return value + element;
print('count: $count'); // count: 29
查找一个数组中的最大数
方法1:使用reduce
void main() {
List<int> numbers = [4, 2, 9, 1, 5, 6];
int maxNumber = numbers.reduce((a, b) => a > b ? a : b);
print('The maximum number is: $maxNumber');//The maximum number is: 9
方式2:fold
方法也可以用来找到最大值,它允许你提供一个初始值和一个函数来合并每个元素:
void main() {
List<int> numbers = [4, 2, 9, 1, 5, 6];
int maxNumber = numbers.fold(numbers[0], (prev, element) => element > prev ? element : prev);
print('The maximum number is: $maxNumber');//The maximum number is: 9
方式3:使用for
循环来遍历数组并手动查找最大值:
void main() {
List<int> numbers = [4, 2, 9, 1, 5, 6];
int maxNumber = numbers[0]; // 假设第一个元素是最大值
for (int number in numbers) {
if (number > maxNumber) {
maxNumber = number;
print('The maximum number is: $maxNumber');
方式4:使用max
函数:Dart标准库提供的dart:math
库中有一个max
函数,但它只能用于两个值的比较。你可以使用它在多个值中找出最大值,但这需要额外的代码来实现:
import 'dart:math';
void main() {
List<int> numbers = [4, 2, 9, 1, 5, 6];
int maxNumber = numbers.reduce((a, b) => max(a, b));
print('The maximum number is: $maxNumber');
排序 - sort
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
// a - b 为升序, b - a为降序
list.sort((a, b) { return b - a; });
print(list); //[6, 6, 5, 4, 3, 2, 2, 1]
获取满足条件的元素 - where
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
// 获取所有大于3的元素
print(list.where((v) => v > 3).toList()); //[4, 5, 6, 6]
获取满足条件的第一个元素 - firstWhere
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6]; // 获取最后一个大于3的元素
print(list.firstWhere((v) => v > 3)); // 4
// 如果未查找到所制定条件的元素,进入orElse参数
list.firstWhere((v) => v > 6, orElse: () {
print(888);
获取满足条件的最后一个元素 - lastWhere (与firstWhere同理,第一个与最后一个的区别)
删除满足条件的元素 - removeWhere
/// final numbers = <String>['one', 'two', 'three', 'four'];
/// numbers.removeWhere((item) => item.length == 3);
/// print(numbers); // [three, four]
返回一个包含[start]和[end]之间元素的新列表。
/// final colors = <String>['red', 'green', 'blue', 'orange', 'pink'];
/// print(colors.sublist(1, 3)); // [green, blue]
List<E> sublist(int start, [int? end]);
从指定位置开始,获取满足条件的第一个元素的索引 - indexWhere
获取满足条件的最后一个元素的索引(倒叙查询) - lastIndexWhere(与indexWhere同理,第一个与最后一个的区别)
从指定位置开始,获取指定值的索引 - indexOf
从指定位置开始,倒叙获取指定值的索引 - lastIndexOf(与indexOf同理,第一次与最后一次的区别)
批量添加 - addAll或者 扩展操作符(…)和 空感知扩展操作符(…?)
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
var list2 = [0, 20, 40];
list.addAll(list2);
print(list); //[1, 2, 2, 3, 4, 5, 6, 6, 0, 20, 40]
//或使用扩展操作符,结果是一样的
void main() {
var list2 = [0, 20, 40];
var list = [1, 2, 2, 3, 4, 5, 6, 6, ...?list2];
print(list); //[1, 2, 2, 3, 4, 5, 6, 6, 0, 20, 40]
获取倒序迭代器 - reversed.注意:翻转过后的数组,要用toList方法,才能成为一个新的数组
void main() {
var list = [1, 2, 2, 3, 4, 5, 6, 6];
print(list.reversed); // (6, 6, 5, 4, 3, 2, 2, 1)
print(list.reversed.toList()); // [6, 6, 5, 4, 3, 2, 2, 1]
生成值列表:List.generate
List<E>.generate(
int length,
E generator(int index),
{bool growable: true}
children: List.generate(
(index) => Container(
width: 200,
height: 200,
margin: EdgeInsets.all(16),
color: Colors.grey[300],
child: Center(
child: Text(
'Inner $index',
style: TextStyle(fontSize: 24),
List.from 和 .of 之间以及 Map.from 和 .of 之间的区别
from
和 of
方法的重要区别是后者有类型注解,前者有类型注解不要.由于 Dart 泛型被具体化并且 Dart 2 是强类型的,因此这是确保 List/Map
正确构造的关键
var foo = new List.from(<int>[1, 2, 3]); // List<dynamic>
var bar = new List.of(<int>[1, 2, 3]); // List<int>
有条件的向列表中插入内容
var list = [
if (isAdd) 'c'
];//isAdd 为 true 则 list 中包含'c',否则就不包含
var list = [1,2,3];
var list2 = [
for (var i in list) '$i'
];// list2 中包含 0,1,2,3
常用属性:
1.add 增加
2.addAll 拼接数组
3.indexOf 查找 传入具体值
4.remove 删除 传入具体值
5.removeAt 删除 传入索引值
6.fillRange 修改
7.insert(index,value) 指定位置插入
8.insertAll(index,value) 指定位置插入数组
9.toList 其他类型转换为List类型
10.first 获取数组第一个元素 last最后一个
List数组使用时常见的问题
1.List 作为 Dart 中的基础对象使用广范,由于其本身的特殊性,如使用不当极易导致异常,从而影响业务逻辑。典型示例如下:
List<int> list = [];
// 当 List 为空时访问其 first 会抛异常
list.first
// 同理访问 last 也会抛异常
list.last
// 查找对象时没有提供 orElse 也会抛异常
list.firstWhere((t) => t > 0);
// List 对象其它会抛异常的访问还有
list.single
list.lastWhere((t) => t > 0)
list.singleWhere((t) => t > 0)
所以如果「没有」前置判断条件,所有对 List 的访问均需替换为 collection
里对应的方法。
import 'package:collection/collection.dart';
List<int> list = [];
list.firstOrNull;
list.lastOrNull;
list.firstWhereOrNull((t) => t > 0);
list.singleOrNull;
list.lastWhereOrNull((t) => t > 0);
list.singleWhereOrNull((t) => t > 0);
2.取元素越界:在 Dart 开发时,碰到数组越界或者访问数组中不存在的元素情况时,会导致运行时错误,如:
List<int> numbers = [0, 1, 2];
print(numbers[3]); // RangeError (index): Index out of range: index should be less than 3: 3
方案一:封装一个 extension
来简化数组越界的问题
extension SafeGetList<T> on List<T> {
T? tryGet(int index) =>
index < 0 || index >= this.length ? null : this[index];
final list = <int>[];
final single = list.tryGet(0) ?? 0;
由于 tryGet
返回值类型为可空(T?
) ,外部接收时需要进行空判断或者赋默认值,这相当于强迫开发者去思考值不存在的情况,如此减少了异常发生的可能,同时在业务上也更加严谨。
方案二:继承一个 ListMixin
的自定义类:SafeList
,其代码如下:
class SafeList<T> extends ListMixin<T> {
final List<T?> _rawList;
final T defaultValue;
final T absentValue;
SafeList({
required this.defaultValue,
required this.absentValue,
List<T>? initList,
}) : _rawList = List.from(initList ?? []);
@override
T operator [](int index) => index < _rawList.length ? _rawList[index] ?? defaultValue : absentValue;
@override
void operator []=(int index, T value) {
if (_rawList.length == index) {
_rawList.add(value);
} else {
_rawList[index] = value;
@override
int get length => _rawList.length;
@override
T get first => _rawList.isNotEmpty ? _rawList.first ?? defaultValue : absentValue;
@override
T get last => _rawList.isNotEmpty ? _rawList.last ?? defaultValue : absentValue;
@override
set length(int newValue) {
_rawList.length = newValue;
final list = SafeList(defaultValue: 0, absentValue: 100, initList: [1,2,3]);
print(list[0]); // 正常输出: 1
print(list[3]); // 越界,输出缺省值: 100
list.length = 101;
print(list[100]); // 改变数组长度了,输出默认值: 0
以上两种方案均可以解决越界的问题,第一个方案更简洁,第二个方案略复杂且侵略性也更强但好处是可以统一默认值、缺省值,具体使用哪种取决于你的场景。
参考:http://t.csdn.cn/XsJAi
数组去重:百度安全验证
Flutter中 List列表中移除特定元素
12,创建一个 Map 实例,其中键和值是从 [iterable] 计算的。13,创建一个映射,将给定的 [键] 与给定的 [值] 相关联。14,创建一个映射,将给定的 [键] 与给定的 [值] 相关联。5,查找 [key] 的值,如果不存在,则添加新条目。7,从映射中删除 [key] 及其关联值(如果存在)。键值对的集合,您可以使用其关联的键从中检索值。11,此映射是否包含给定的 [value]。10,此映射是否包含给定的 [key]。6,将所有键值对添加到此映射中。9,循环应用于映射的每个键值对。
add(): 向List添加一个元素。addAll(): 向List添加另一个Iterable的所有元素。remove(): 移除指定的元素。removeAt(): 根据索引移除指定的元素。insert(): 在指定位置插入元素。: 在指定位置插入多个元素。contains(): 判断List是否包含指定的元素。indexOf(): 获取元素的索引。sort(): 对List进行排序。reversed: 获取反转后的List。shuffle(): 随机打乱List元素。map()
列表组件的常用参数: (1) scrollDirection Axis Axis.horizontal表示水平列表,Axis.vertical垂直列表 (2) padding EdgeInsetsGeometry 内边距 (3) resolve bool 组件反向排序 (4) children List 列表元素。(2)图片列表 我们不仅仅可以使用上述的ListTile实现图片列表,使用Image和Text也是可以实现图文列表的。使用ListTile可以配合ListView快速实现垂直列表的效果。
// 定义固定类型的数组
var list = List<int>();
print('$list - length: ${list.length}'); // 输出 [] - 0
2、定义固定长度数组
var list2 = List(2);
print('$list2'); // [null, null]
在学习Flutter之前,让我们先来认识下什么是Flutter跨平台。Flutter是谷歌开源的一款移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。同时, Flutter可以与现有的代码一起工作,在全世界,Flutter正在被越来越多的开发者和组织使用。......
FlutterMap是一个基于Flutter的在线地图插件,提供了丰富的地图数据源和交互方式,开发者可以轻松集成到自己的应用程序中。FlutterMap优秀的UI性能和地图渲染能力,为用户带来极致的滑动、缩放体验。FlutterMap提供了对地图相关的一些丰富操作,使用FlutterMap可以帮助开发者轻松并高效地开发地图交互相关的应用。